khala-cli 0.4.6 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{chunk-2U4E7AM7.mjs → chunk-25AX7UMF.mjs} +294 -101
  2. package/dist/{chunk-AUJEUKVM.mjs → chunk-3OFKVYOX.mjs} +1 -1
  3. package/dist/{chunk-AWBKVTLV.mjs → chunk-4LSCOWWN.mjs} +13 -14
  4. package/dist/chunk-5RGEO5HN.mjs +142 -0
  5. package/dist/{chunk-B2MOLCJM.mjs → chunk-6YEYXZZB.mjs} +8 -9
  6. package/dist/{chunk-2XTYRBYX.mjs → chunk-7V2YQIRI.mjs} +4 -4
  7. package/dist/{chunk-55KBLEX5.mjs → chunk-APIWKRKG.mjs} +1 -1
  8. package/dist/{chunk-PY2ZNVNY.mjs → chunk-C5SMOUTO.mjs} +34 -5
  9. package/dist/{chunk-JG5J3SHW.mjs → chunk-IG2NU5J6.mjs} +4 -4
  10. package/dist/chunk-JEI32DEA.mjs +634 -0
  11. package/dist/{chunk-4X35OUAN.mjs → chunk-K6EJSZYO.mjs} +92 -95
  12. package/dist/{chunk-FH2CZX5T.mjs → chunk-L7L6UNXN.mjs} +83 -36
  13. package/dist/{chunk-P5CP32X2.mjs → chunk-LNG3ZZBK.mjs} +1 -1
  14. package/dist/{chunk-CWHGNVZV.mjs → chunk-OAFYPBCP.mjs} +1 -1
  15. package/dist/{chunk-OECJ45NM.mjs → chunk-ODTSGEID.mjs} +24 -8
  16. package/dist/{chunk-XUJIJ4KB.mjs → chunk-OP2HZ7EM.mjs} +1 -1
  17. package/dist/{chunk-6E3UCO22.mjs → chunk-S3FX7VCY.mjs} +8 -11
  18. package/dist/{chunk-PFDUXY3N.mjs → chunk-SU6362YU.mjs} +1 -1
  19. package/dist/{chunk-Z4EDYB6Y.mjs → chunk-TOBQUAPD.mjs} +59 -43
  20. package/dist/{chunk-SN3STAO2.mjs → chunk-U3MKSPRO.mjs} +40 -3
  21. package/dist/{chunk-SZIEG3RS.mjs → chunk-W5HS2PQO.mjs} +12 -14
  22. package/dist/{chunk-OW3DSTEZ.mjs → chunk-WNOIHCCC.mjs} +5 -5
  23. package/dist/{chunk-RRBIVI77.mjs → chunk-YIHRHD7W.mjs} +1 -1
  24. package/dist/khala.mjs +10 -10
  25. package/dist/web/assets/local-BQl2KrE1.js +9 -0
  26. package/dist/web/assets/local-OwDq47O4.css +1 -0
  27. package/dist/web/index.html +2 -2
  28. package/package.json +1 -1
  29. package/dist/chunk-DPW43YNC.mjs +0 -36
  30. package/dist/chunk-IULQYQJZ.mjs +0 -144
  31. package/dist/chunk-WHONG7UF.mjs +0 -267
  32. package/dist/chunk-ZHMGB3PP.mjs +0 -82
  33. package/dist/web/assets/local-K8EcTVxW.js +0 -9
  34. package/dist/web/assets/local-R2y0Gl4T.css +0 -1
@@ -0,0 +1 @@
1
+ .kh-card{position:relative}.kh-main{container:khm / inline-size}.kh-ib{flex:0 0 auto;width:34px;height:34px;display:grid;place-items:center;border:0;border-radius:10px;background:none;color:var(--muted);cursor:pointer;position:relative;padding:0;font:inherit}.kh-ib:hover{background:var(--surface-2);color:var(--fg)}.kh-ib svg{width:18px;height:18px}.kh-ib.sm{width:28px;height:28px;border-radius:8px}.kh-ib.sm svg{width:15px;height:15px}.kh-ib.ok{color:var(--good-ink)}.kh-ib.ok:hover{background:var(--good-soft)}.kh-ib.no:hover{color:var(--block);background:var(--block-soft)}.kh-ib[aria-expanded=true]{background:var(--surface-3);color:var(--fg)}@media(pointer:coarse){.kh-ib{width:44px;height:44px}.kh-ib.sm{width:36px;height:36px}}@media(hover:hover){.kh-card [data-tip]:hover:after{content:attr(data-tip);position:absolute;top:calc(100% + 6px);right:0;z-index:30;white-space:nowrap;font-size:.7rem;font-weight:600;line-height:1.2;letter-spacing:0;text-transform:none;padding:5px 8px;border-radius:7px;background:var(--fg);color:var(--surface);pointer-events:none}}.kh-pop{position:absolute;z-index:25;width:min(290px,calc(100% - 16px));box-sizing:border-box;padding:.75rem;border-radius:14px;background:var(--surface);border:1px solid var(--line-strong);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;gap:.65rem;animation:khPopIn .14s ease-out}.kh-pop[hidden]{display:none}.kh-pop.menu{width:auto;min-width:170px;padding:.3rem;gap:0}@keyframes khPopIn{0%{opacity:0;transform:translateY(-4px)}}.kh-pop-h{font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--faint)}.kh-f{display:flex;align-items:center;justify-content:space-between;gap:.6rem;font-size:.84rem}.kh-f>span:first-child{color:var(--muted)}.kh-f.col{flex-direction:column;align-items:stretch;gap:.4rem}.kh-lk{position:relative;display:inline-flex;align-items:center;gap:4px}.kh-lk svg{width:11px;height:11px}.kh-seg{display:inline-flex;padding:2px;border-radius:9px;background:var(--surface-3);border:1px solid var(--line);flex:0 0 auto}.kh-seg button{position:relative;border:0;background:none;color:var(--muted);border-radius:7px;font:inherit;font-size:.78rem;font-weight:600;padding:4px 9px;cursor:pointer;display:grid;place-items:center;white-space:nowrap}.kh-seg button:hover{color:var(--fg)}.kh-seg button.on{background:var(--surface);color:var(--fg);box-shadow:0 1px 2px #00000040}.kh-seg.full{display:flex}.kh-seg.full button{flex:1}.kh-seg.lock{opacity:.55}.kh-seg button:disabled{cursor:default}.kh-seg.ic button{width:28px;height:24px;padding:0}.kh-seg.ic svg{width:14px;height:14px}.kh-seg.ic button.on{color:var(--accent-ink)}@media(pointer:coarse){.kh-seg.ic button{width:36px;height:32px}.kh-seg button{padding:7px 11px}}.kh-sw{width:34px;height:20px;border-radius:999px;border:0;background:var(--surface-3);box-shadow:inset 0 0 0 1px var(--line-strong);position:relative;cursor:pointer;flex:0 0 auto;padding:0}.kh-sw:before{content:"";position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:var(--muted);transition:transform .15s,background .15s}.kh-sw[aria-checked=true]{background:var(--accent);box-shadow:none}.kh-sw[aria-checked=true]:before{transform:translate(14px);background:#fff}.kh-link,.kh-oneliner{display:flex;align-items:center;gap:.3rem;padding-left:.65rem;height:38px;border-radius:10px;background:var(--bg-2);border:1px solid var(--line)}.kh-oneliner{border-style:dashed;border-color:var(--line-strong)}.kh-link code,.kh-oneliner code{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:.74rem JetBrains Mono,monospace;color:var(--muted)}.kh-oneliner code{color:var(--fg)}.kh-link .kh-ib,.kh-oneliner .kh-ib{margin-right:4px}.kh-txt{height:36px;min-width:0;width:100%;box-sizing:border-box;border-radius:10px;border:1px solid var(--line-strong);background:var(--bg-2);color:var(--fg);padding:0 .7rem;font:inherit;font-size:.88rem;outline:none}@media(pointer:coarse){.kh-txt{font-size:16px;height:44px}}.kh-txt:focus{border-color:var(--accent-line);box-shadow:0 0 0 3px var(--accent-soft)}.kh-btn{height:34px;padding:0 .9rem;border-radius:10px;border:1px solid var(--line-strong);background:var(--surface-3);color:var(--fg);font:inherit;font-size:.84rem;font-weight:600;cursor:pointer;flex:0 0 auto}@media(pointer:coarse){.kh-btn{height:44px}}.kh-btn.pri{background:var(--accent);border-color:var(--accent);color:#fff}.kh-btn.danger{background:var(--block);border-color:var(--block);color:#fff}.kh-btn:disabled{opacity:.4;cursor:default}.kh-btn-ic{display:flex;align-items:center;justify-content:center;gap:.45rem}.kh-btn-ic svg{width:15px;height:15px}.kh-hint{font-size:.74rem;color:var(--faint);text-align:center;margin-top:-.3rem}.kh-tbtn{align-self:flex-start;border:0;background:none;padding:.2rem 0;font:inherit;font-size:.84rem;font-weight:600;color:var(--block);cursor:pointer}.kh-tbtn:hover{text-decoration:underline}.kh-sep{height:1px;background:var(--line);margin:0 -.75rem}.kh-row2{display:flex;gap:.4rem}.kh-or{display:flex;align-items:center;gap:.5rem;font-size:.7rem;color:var(--faint)}.kh-or:before,.kh-or:after{content:"";flex:1;height:1px;background:var(--line)}.kh-mi{display:flex;align-items:center;gap:.55rem;width:100%;padding:.5rem .6rem;border:0;border-radius:9px;background:none;color:var(--fg);font:inherit;font-size:.84rem;text-align:left;cursor:pointer;min-height:36px;white-space:nowrap}@media(pointer:coarse){.kh-mi{min-height:44px}}.kh-mi:hover{background:var(--surface-2)}.kh-mi svg{width:15px;height:15px;flex:0 0 auto}.kh-mi em{margin-left:auto;padding-left:.8rem;font-style:normal;font-size:.72rem;color:var(--faint)}.kh-swatch-dot{display:inline-block;width:8px;height:8px;margin-right:.35rem;border-radius:50%;vertical-align:0}.kh-mi.on{color:var(--accent-ink)}.kh-mi.danger{color:var(--block)}.kh-mi.danger:hover{background:var(--block-soft)}.kh-toast{position:absolute;left:50%;bottom:104px;z-index:30;display:flex;align-items:center;gap:.35rem;padding:.45rem .85rem;border-radius:999px;background:var(--fg);color:var(--surface);font-size:.8rem;font-weight:600;white-space:nowrap;opacity:0;transform:translate(-50%,8px);pointer-events:none;transition:opacity .18s,transform .18s}.kh-toast.on{opacity:1;transform:translate(-50%)}.kh-toast svg{width:14px;height:14px}.kh-mi[data-setting=mentions]{max-width:min(320px,calc(100vw - 48px));flex-wrap:wrap;white-space:normal}.kh-mi[data-setting=mentions] em{flex-basis:100%;margin-left:1.25rem;padding-left:0}.kh-card .kh-roster [data-tip]:hover:after{content:none}.kh-roster-tooltip{position:absolute;z-index:30;width:max-content;max-width:calc(100% - 16px);box-sizing:border-box;font-size:.7rem;font-weight:600;line-height:1.2;padding:5px 8px;border-radius:7px;background:var(--fg);color:var(--surface);pointer-events:none}.kh-roster-tooltip[hidden]{display:none}.kh-list-head{display:flex;align-items:baseline;justify-content:space-between;padding:1rem 1rem .6rem}.kh-list-head b{font-size:1.05rem;letter-spacing:-.02em}.kh-list-head span{font-size:.76rem;color:var(--muted)}.kh-list-head{align-items:center;gap:.5rem}.kh-list-head b{flex:1}.kh-search{display:flex;align-items:center;gap:.45rem;margin:0 .8rem .6rem;padding:0 .7rem;height:34px;border-radius:10px;background:var(--surface-3);color:var(--faint)}.kh-search svg{width:15px;height:15px;flex:0 0 auto}.kh-search input{flex:1;min-width:0;border:0;background:none;outline:none;color:var(--fg);font:inherit;font-size:.88rem}.kh-convos{flex:1;overflow-y:auto;padding:0 .5rem .6rem;display:flex;flex-direction:column;gap:2px}.kh-cv{display:grid;grid-template-columns:44px minmax(0,1fr);gap:.65rem;align-items:center;padding:.6rem .55rem;border-radius:12px;border:0;background:none;color:var(--fg);font:inherit;text-align:left;cursor:pointer;position:relative}.kh-cv:hover{background:var(--surface-2)}.kh-cv.is-active{background:var(--accent);color:#fff}.kh-cv.is-active .kh-cv-pv,.kh-cv.is-active .kh-cv-t time{color:#fffc}.kh-cv-av{position:relative;width:44px;height:44px}.kh-cv-av .kh-av{position:absolute;width:30px;height:30px;pointer-events:none}.kh-cv-av .kh-av:first-child{left:0;top:0}.kh-cv-av .kh-av:nth-child(2){right:0;bottom:0;border:2px solid var(--surface)}.kh-cv-av .kh-av:only-child,.kh-cv-av .kh-av:first-child:has(+.kh-cv-unread){width:44px;height:44px}.kh-cv-av .kh-own{display:none}.kh-cv-av .kh-av img{width:15px;height:15px}.kh-cv-t{display:flex;flex-direction:column;gap:2px;min-width:0}.kh-cv-t>span:first-child{display:flex;align-items:baseline;gap:.5rem}.kh-cv-t b{flex:1;min-width:0;font-size:.9rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kh-cv-t time{flex:0 0 auto;font-size:.72rem;color:var(--faint)}.kh-cv-pv{font-size:.8rem;color:var(--muted);line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.kh-cv.unread b{font-weight:700}.kh-cv-unread{position:absolute;z-index:1;left:-2px;top:-2px;width:10px;height:10px;border:2px solid var(--surface);border-radius:50%;background:var(--accent);box-sizing:border-box}.kh-cv-av .kh-av:first-child+.kh-cv-unread{left:1px;top:1px}.kh-cv:hover .kh-cv-unread{border-color:var(--surface-2)}.kh-cv.is-active .kh-cv-unread{background:#fff;border-color:var(--accent)}.kh-cv-empty{padding:1.2rem;text-align:center;color:var(--faint);font-size:.84rem}.kh-cv.dead{opacity:.55}@media(max-width:760px){.kh-cv{padding:.7rem .55rem;min-height:60px}.kh-search input{font-size:16px}}.kh-cv-skel{cursor:default}.kh-cv-skel:hover{background:none}.kh-cv-skel .kh-cv-av,.kh-cv-skel .kh-cv-t>span{border-radius:50%;background:linear-gradient(100deg,var(--surface-3) 30%,var(--surface-2) 50%,var(--surface-3) 70%);background-size:200% 100%;animation:khSkel 1.4s ease-in-out infinite}.kh-cv-skel .kh-cv-t{gap:8px}.kh-cv-skel .kh-cv-t>span{display:block;height:10px;border-radius:5px;width:60%}.kh-cv-skel .kh-cv-t>span+span{width:85%}@keyframes khSkel{to{background-position-x:-200%}}.kh-new-err{color:var(--block-ink)}.kh-thread{flex:1 1 auto;overflow-y:auto;padding:1.1rem 1.1rem .6rem;display:flex;flex-direction:column;gap:2px;background:var(--bg-2)}.kh-row{display:flex;align-items:flex-end;gap:.5rem;max-width:78%}.kh-row.me{align-self:flex-end;flex-direction:row-reverse}.kh-row.first{margin-top:.7rem}.kh-col{display:flex;flex-direction:column;gap:2px;min-width:0}.kh-row.me .kh-col{align-items:flex-end}.kh-name{display:flex;align-items:center;gap:.4rem;font-size:.74rem;color:var(--muted);padding:0 .75rem .2rem;background:none;border:0;cursor:pointer;font-family:inherit}.kh-name b{color:hsl(var(--h) 75% 72%);font-weight:600}.khala-app[data-theme=light] .kh-name b{color:hsl(var(--h) 60% 35%)}.kh-name:hover b{text-decoration:underline}.kh-b{padding:.5rem .8rem;border-radius:18px;font-size:.92rem;line-height:1.4;background:var(--surface-3);color:var(--fg);text-wrap:pretty;overflow-wrap:anywhere;position:relative}.kh-row:not(.me) .kh-b{border-top-left-radius:18px}.kh-row:not(.me).mid .kh-b,.kh-row:not(.me).last-of .kh-b{border-top-left-radius:6px}.kh-row:not(.me).first:not(.last-of) .kh-b,.kh-row:not(.me).mid .kh-b{border-bottom-left-radius:6px}.kh-row.me .kh-b{background:var(--hs, var(--accent));color:#fff}.kh-row.me.mid .kh-b,.kh-row.me.last-of .kh-b{border-top-right-radius:6px}.kh-row.me.first:not(.last-of) .kh-b,.kh-row.me.mid .kh-b{border-bottom-right-radius:6px}.kh-b code{font-family:JetBrains Mono,monospace;font-size:.82em;padding:1px 5px;border-radius:5px;background:#00000038}.kh-mention{font-weight:600;color:hsl(var(--mh) 75% 74%);cursor:pointer}.khala-app[data-theme=light] .kh-mention{color:hsl(var(--mh) 60% 34%)}.kh-row.me .kh-mention{color:#fff;text-decoration:underline;text-underline-offset:2px}.kh-mention:hover{text-decoration:underline}.kh-row.human .kh-b{background:var(--hb, hsl(330 42% 30%));color:#fff}.khala-app[data-theme=light] .kh-row.human .kh-b{background:var(--hb-l, hsl(330 62% 86%));color:var(--hk, #3a1026)}.kh-row.human .kh-b code{background:#0003}.kh-row.human .kh-mention{color:#fff;text-decoration:underline;text-underline-offset:2px}.khala-app[data-theme=light] .kh-row.human .kh-mention{color:var(--hk, #3a1026)}.kh-kind{display:inline-grid;place-items:center;flex:0 0 auto;width:13px;height:13px}.kh-kind svg{width:13px;height:13px}.kh-kind-human{color:var(--accent)}.kh-kind-agent{color:var(--accent-complement)}.kh-row.agent{--ob: hsl(var(--oh) 65% 48%);--ob-mix: 30%}.khala-app[data-theme=light] .kh-row.agent{--ob-mix: 28%}.kh-row.agent .kh-b{background:color-mix(in srgb,var(--ob) var(--ob-mix),var(--surface-3))}.kh-row.agent .kh-mention{color:inherit;text-decoration:underline;text-underline-offset:2px}.kh-mention.kh-hm{background:hsl(var(--mh) 60% 50% / .16);padding:0 4px;border-radius:5px}.kh-row.me .kh-mention.kh-hm,.kh-row.human .kh-mention.kh-hm{background:#ffffff2e;text-decoration:none}.kh-retry{align-self:center;color:var(--block)}.kh-row.failed .kh-b{opacity:.55}@media(max-width:760px){.kh-row{max-width:88%}.kh-thread{padding:.8rem .7rem .5rem}.kh-b{font-size:.95rem}}.kh-pre{margin:.35rem 0 0;padding:.55rem .7rem;border-radius:10px;background:#00000038;font:.82em/1.45 JetBrains Mono,monospace;overflow-x:auto;white-space:pre}.khala-app[data-theme=light] .kh-pre{background:#2a251a14}.kh-pre-lang{display:block;font-size:.68rem;color:var(--muted);margin-bottom:.25rem}.kh-rcpt{align-self:flex-end;font-size:.7rem;color:var(--faint);padding:.15rem .3rem 0}.kh-rcpt b{color:var(--muted);font-weight:600}.kh-rcpt.kh-fail{color:var(--block);font-weight:600}.kh-row.pending .kh-b{opacity:.7}.kh-row.pop{animation:khPop .22s ease-out}@keyframes khPop{0%{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}.kh-day{align-self:center;font-size:.72rem;color:var(--faint);margin:.9rem 0 .6rem;font-weight:600}.kh-day b{color:var(--muted);font-weight:600}.kh-ev{align-self:center;display:flex;align-items:center;gap:.45rem;font-size:.76rem;color:var(--muted);margin:.7rem 0 .2rem;padding:.3rem .75rem;border-radius:999px;border:1px solid var(--line);background:var(--surface);cursor:pointer;font-family:inherit}.kh-ev i{width:7px;height:7px;border-radius:50%;background:var(--good)}.kh-ev:hover{border-color:var(--line-strong);color:var(--fg)}.kh-ev--static{cursor:default}.kh-ev--static i{background:var(--muted)}.kh-ev--static:hover{border-color:var(--line);color:var(--muted)}.kh-thread .channel-event-pill{align-self:center;margin:.7rem 0 .2rem}.kh-thread .channel-event-pill__link{display:flex;align-items:center;gap:.45rem;font-size:.76rem;color:var(--muted);padding:.3rem .75rem;border-radius:999px;border:1px solid var(--line);background:var(--surface);font-family:inherit}.kh-thread a.channel-event-pill__link:hover{border-color:var(--line-strong);color:var(--fg)}.kh-thread .channel-event-pill__dot{background:var(--good)}.kh-empty{margin:auto;display:flex;flex-direction:column;align-items:center;gap:.7rem;color:var(--muted);font-size:.9rem}.timeline__list.kh-thread{flex:1 1 auto;list-style:none;margin:0;padding:1.1rem 1.1rem .6rem;gap:2px;max-height:none;min-height:0}@media(max-width:760px){.timeline__list.kh-thread{padding:.8rem .7rem .5rem}}.conversation-thread__body .timeline{height:100%;gap:0;min-height:0}.timeline__state{align-self:center;margin:1rem}.timeline__state[role=alert]>b{color:var(--fg)}.kh-channel-thread{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;overflow:auto}.kh-head{display:flex;align-items:center;gap:.8rem;padding:.85rem 1.1rem;border-bottom:1px solid var(--line);background:var(--surface)}.kh-stack{display:flex}.kh-stack .kh-av{width:30px;height:30px;margin-left:-8px;border:2px solid var(--surface)}.kh-stack .kh-av:first-child{margin-left:0}.kh-head-t{display:flex;flex-direction:column;align-items:flex-start;min-width:0;flex:1 1 auto;border:0;background:none;color:var(--fg);font:inherit;text-align:left;padding:.2rem .45rem;margin:-.2rem -.45rem;border-radius:10px;cursor:pointer}.kh-head-t:hover{background:var(--surface-2)}.kh-head-t>b{display:flex;align-items:center;gap:.3rem;max-width:100%;font-size:.98rem;letter-spacing:-.01em}.kh-head-t>b>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kh-chev{display:inline-grid;width:16px;height:16px;flex:0 0 auto;color:var(--muted);transition:transform .2s}.kh-chev svg{width:16px;height:16px}.roster-open .kh-chev{transform:rotate(180deg)}.kh-head-t>span{font-size:.78rem;color:var(--muted);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kh-head-t .on{color:var(--good-ink)}.kh-hacts{display:flex;gap:2px;margin-left:auto;flex:0 0 auto}.kh-hacts:after{content:"";flex:0 0 34px}@media(pointer:coarse){.kh-hacts:after{flex-basis:44px}}@media(max-width:760px){.kh-head{padding:.65rem .75rem;gap:.55rem}.kh-stack .kh-av:nth-child(n+3){display:none}}.kh-id{font-family:JetBrains Mono,monospace;font-size:.68rem;padding:1px 6px;border-radius:999px;background:hsl(var(--h) 60% 50% / .14);color:hsl(var(--h) 70% 72%);border:1px solid hsl(var(--h) 60% 50% / .3)}.khala-app[data-theme=light] .kh-id{color:hsl(var(--h) 60% 32%)}.kh-rai b .kh-id,.kh-d-hero b .kh-id,.kh-d-agent b .kh-id{margin-left:.3rem;font-weight:400}.kh-roster{position:absolute;left:0;right:0;top:var(--kh-head-h, 60px);z-index:4;display:grid;grid-template-rows:0fr;transition:grid-template-rows .25s ease;background:var(--surface);border-bottom:1px solid transparent}.kh-roster.is-open{box-shadow:0 18px 40px -18px #0000008c}.kh-roster.is-open{grid-template-rows:1fr;border-bottom-color:var(--line)}.kh-roster-in{overflow:hidden;min-height:0}.kh-roster.is-open .kh-roster-in{overflow-y:scroll;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent;max-height:var(--kh-roster-max, 320px);padding:.5rem .7rem .8rem;display:flex;flex-direction:column;gap:.35rem}.kh-rg{display:flex;flex-direction:column}.kh-rh,.kh-rai{display:flex;align-items:center;gap:.6rem;width:100%;padding:.45rem .5rem;border:0;border-radius:12px;background:none;color:var(--fg);font:inherit;text-align:left;cursor:pointer;min-height:44px}.kh-rh:hover,.kh-rai:hover{background:var(--surface-2)}.kh-rh>span:nth-child(2),.kh-rai>span:nth-child(2){flex:1;min-width:0;display:flex;flex-direction:column}.kh-rh b,.kh-rai b{font-size:.88rem;font-weight:600}.kh-rh em,.kh-rai em{font-style:normal;font-size:.76rem;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kh-rh>i{font-style:normal;font-size:.72rem;color:var(--faint);flex:0 0 auto}.kh-ra{margin-left:1.45rem;padding-left:.8rem;border-left:2px solid var(--line);display:flex;flex-direction:column}.kh-rai .kh-av{width:28px;height:28px}.kh-rai .kh-av img{width:14px;height:14px}.kh-rrow{display:flex;align-items:center;gap:.3rem;border-radius:12px}.kh-rrow:hover{background:var(--surface-2)}.kh-rrow>.kh-rh,.kh-rrow>.kh-rai{flex:1;min-width:0;background:none!important}.kh-racts{display:flex;align-items:center;gap:4px;flex:0 0 auto;padding-right:.3rem}.kh-mode-ro{position:relative;width:26px;height:26px;display:grid;place-items:center;color:var(--muted);border-radius:7px;flex:0 0 auto}.kh-mode-ro svg{width:14px;height:14px}.kh-mode-btn{display:none;color:var(--accent-ink)}.kh-roster-in.more{-webkit-mask-image:linear-gradient(#000 calc(100% - 36px),transparent);mask-image:linear-gradient(#000 calc(100% - 36px),transparent)}.kh-roster-in::-webkit-scrollbar{width:6px}.kh-roster-in::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:3px}.kh-rlbl{display:flex;align-items:center;gap:.4rem;padding:.3rem .5rem .15rem;font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;font-weight:700;color:var(--faint)}@container khm (max-width: 600px){.kh-rh>i{display:none}}@container khm (max-width: 520px){.kh-stack,.kh-seg.ic{display:none}.kh-mode-btn{display:grid}}@media(max-width:760px){.kh-ra{margin-left:1.1rem}}.kh-roster-status{padding:.3rem .5rem;font-size:.8rem;color:var(--muted)}.kh-mode-status{margin:0;padding:0 .5rem .3rem calc(1.1rem + 28px);font-size:.76rem}.kh-to{display:block;padding:.5rem .9rem 0;background:var(--surface);border-top:1px solid var(--line)}.kh-to+.kh-comp{border-top:0;padding-top:.45rem}.kh-to-flat{display:flex;gap:.35rem;flex-wrap:wrap;align-items:center}.kh-to-grid{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.4rem .5rem;align-items:start;max-height:min(38vh,180px);overflow-y:auto}.kh-to-h{display:flex}.kh-to-ags{display:flex;flex-wrap:wrap;gap:.35rem}.kh-to-foot{display:flex;align-items:center;justify-content:space-between;margin-top:.45rem;font-size:.72rem;color:var(--faint)}.kh-to.is-open{padding-top:.7rem;animation:khUp .2s ease-out}@keyframes khUp{0%{opacity:.4;transform:translateY(8px)}to{opacity:1;transform:none}}.kh-to-tog{display:inline-flex;align-items:center;gap:.25rem;font:600 .72rem JetBrains Mono,monospace;padding:3px 8px;border-radius:999px;border:1px solid var(--line-strong);background:var(--surface-3);color:var(--fg);cursor:pointer}.kh-to-tog svg{width:12px;height:12px;transition:transform .2s}.kh-to.is-open .kh-to-tog svg{transform:rotate(180deg)}.kh-chip-me{cursor:default;opacity:.85}.kh-chip{font-family:JetBrains Mono,monospace;font-size:.72rem;padding:3px 9px;border-radius:999px;border:1px solid var(--pill-bd);background:var(--pill-bg);color:var(--muted);cursor:pointer}.kh-chip:hover{color:var(--fg);border-color:var(--line-strong)}.kh-chip-a{display:inline-flex;align-items:center;gap:.35rem;padding:2px 3px 2px 7px;color:var(--fg);border-color:hsl(var(--oh) 60% 55% / .45);background:hsl(var(--oh) 60% 50% / .08)}.kh-chip-a img{width:12px;height:12px;flex:0 0 auto}.kh-chip.kh-chip-a{color:hsl(var(--oh) 70% 72%)}.khala-app[data-theme=light] .kh-chip.kh-chip-a{color:hsl(var(--oh) 60% 36%)}.kh-chip-a i{font-style:normal;font:700 8px/16px JetBrains Mono,monospace;min-width:16px;height:16px;padding:0 3px;box-sizing:border-box;text-align:center;border-radius:999px;background:var(--hc, hsl(var(--oh) 65% 29%));color:#fff}.kh-chip-h{display:inline-flex;align-items:center;gap:.35rem;padding:2px 9px 2px 3px}.kh-chip-h i{font-style:normal;font:700 8px/16px JetBrains Mono,monospace;min-width:16px;height:16px;padding:0 3px;box-sizing:border-box;text-align:center;border-radius:999px;background:var(--hc, hsl(var(--oh) 65% 29%));color:#fff}.kh-chip-h{color:hsl(var(--oh) 70% 72%);border-color:hsl(var(--oh) 60% 55% / .45);background:hsl(var(--oh) 60% 50% / .1)}.khala-app[data-theme=light] .kh-chip-h{color:hsl(var(--oh) 60% 36%)}.kh-comp{display:flex;align-items:flex-end;gap:.55rem;padding:.7rem .9rem .85rem;border-top:1px solid var(--line);background:var(--surface)}.kh-input{flex:1 1 auto;min-height:38px;max-height:140px;resize:none;border-radius:19px;border:1px solid var(--line-strong);background:var(--bg-2);color:var(--fg);padding:.5rem .95rem;font:inherit;font-size:.92rem;line-height:1.4;outline:none}.kh-input:focus{border-color:var(--accent-line);box-shadow:0 0 0 3px var(--accent-soft)}.kh-send{flex:0 0 auto;width:38px;height:38px;border-radius:50%;border:0;background:var(--accent);color:#fff;display:grid;place-items:center;cursor:pointer;transition:opacity .15s,transform .15s}.kh-send:disabled{opacity:.35;cursor:default}.kh-send:not(:disabled):active{transform:scale(.92)}.kh-send svg{width:18px;height:18px}@media(max-width:760px){.kh-to{padding:.45rem .6rem 0}.kh-to-flat{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}.kh-to-flat>*{flex:0 0 auto}.kh-chip,.kh-to-tog{min-height:30px}.kh-to-grid{grid-template-columns:minmax(0,1fr);gap:.25rem}.kh-to-ags{padding-left:1.4rem;margin-bottom:.35rem}.kh-input{font-size:16px;min-height:40px}.kh-send{width:40px;height:40px}.kh-comp{padding:.55rem .6rem .65rem}}.kh-comp{position:relative}.kh-mpop{position:absolute;left:.9rem;bottom:calc(100% + 6px);z-index:25;width:min(320px,calc(100% - 1.8rem));max-height:min(40vh,296px);overflow-y:auto;box-sizing:border-box;margin:0;padding:.3rem;list-style:none;border-radius:14px;background:var(--surface);border:1px solid var(--line-strong);box-shadow:var(--shadow-lg);animation:khPopIn .14s ease-out}.kh-mpop-opt{display:flex;align-items:center;gap:.55rem;padding:.45rem .6rem;border-radius:9px;min-height:36px;box-sizing:border-box;cursor:pointer;color:var(--fg);font-size:.84rem}.kh-mpop-opt[aria-selected=true],.kh-mpop-opt:hover{background:var(--surface-2)}.kh-mpop-opt b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}.kh-mpop-opt em{margin-left:auto;padding-left:.8rem;flex:0 0 auto;font-style:normal;font-size:.72rem;color:var(--faint);white-space:nowrap}.kh-mpop-opt img{width:20px;height:20px;flex:0 0 auto}.kh-mpop-opt i.kh-mpop-ag{display:grid;place-items:center;padding:0}.kh-mpop-opt i.kh-mpop-ag img{width:12px;height:12px;filter:brightness(0) invert(1)}.kh-mpop-opt i{flex:0 0 auto;font:700 9px/20px JetBrains Mono,monospace;min-width:20px;height:20px;padding:0 3px;box-sizing:border-box;text-align:center;border-radius:999px;background:var(--hc, hsl(var(--oh) 65% 29%));color:#fff}@media(pointer:coarse){.kh-mpop-opt{min-height:44px}}@media(max-width:760px){.kh-mpop{left:.6rem;right:.6rem;width:auto}}.section-card{background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm)}.kh-card{padding:0!important;overflow:hidden;display:grid;grid-template-columns:300px minmax(0,1fr) 0px;height:calc(100vh - 190px);min-height:540px;transition:grid-template-columns .25s ease}.kh-card.has-detail{grid-template-columns:300px minmax(0,1fr) 320px}.kh-list{display:flex;flex-direction:column;min-height:0;border-right:1px solid var(--line);background:var(--surface)}.kh-back{display:none;width:34px;height:34px;margin-left:-.4rem;border:0;border-radius:50%;background:none;color:var(--accent-ink);cursor:pointer;place-items:center}.kh-back svg{width:20px;height:20px}.kh-back:hover{background:var(--surface-2)}.kh-main{display:flex;flex-direction:column;min-width:0;min-height:0;position:relative}.kh-detail{border-left:1px solid var(--line);background:var(--surface);overflow-y:auto;min-width:0}.kh-state{flex:1;display:grid;place-items:center;background:var(--bg-2);padding:1.5rem}.kh-state[hidden]{display:none}.kh-state-c{display:flex;flex-direction:column;align-items:center;gap:.75rem;padding:1.4rem 1.8rem;border-radius:16px;background:var(--surface);border:1px solid var(--line);text-align:center}.kh-state-c>svg{width:24px;height:24px;color:var(--faint)}.kh-state-c b{font-size:.98rem}.kh-spin{width:22px;height:22px;box-sizing:border-box;border-radius:50%;border:2.5px solid var(--line-strong);border-top-color:var(--accent);animation:khSpin .8s linear infinite}@keyframes khSpin{to{transform:rotate(360deg)}}.kh-loading{flex:1 1 auto;display:grid;place-items:center;min-height:0}.kh-loading--overlay{position:absolute;inset:0;z-index:1;pointer-events:none}.kh-state>.kh-state{padding:0}@media(max-width:1100px){.kh-card,.kh-card.has-detail{grid-template-columns:260px minmax(0,1fr) 0px}.kh-card{position:relative}.kh-detail{position:absolute;top:0;right:0;bottom:0;width:320px;transform:translate(100%);transition:transform .25s ease;z-index:5;box-shadow:var(--shadow-lg)}.kh-card.has-detail .kh-detail{transform:none}}@media(max-width:900px){.kh-card,.kh-card.has-detail{grid-template-columns:minmax(0,1fr)}.kh-card:not(.in-thread) .kh-main{display:none}.kh-card.in-thread .kh-list{display:none}.kh-back{display:grid}.kh-list{border-right:0}}@media(max-width:760px){.kh-card,.kh-card.has-detail{grid-template-columns:minmax(0,1fr);position:relative;height:calc(100vh - 210px)}.kh-detail{position:absolute;inset:0;transform:translate(100%);transition:transform .25s ease;z-index:5;border-left:0}.kh-card.has-detail .kh-detail{transform:none}.kh-card,.kh-card.has-detail{height:calc(100dvh - 190px);min-height:420px;border-radius:var(--radius)}}.khala-app{height:100vh;height:100dvh}.khala-app .kh-card,.khala-app .kh-card.has-detail{height:100%;min-height:0;border:0;border-radius:0;box-shadow:none}@media(max-width:760px){.khala-app .kh-card,.khala-app .kh-card.has-detail{height:100%;min-height:0;border-radius:0}.khala-app .kh-comp{padding-bottom:calc(.65rem + env(safe-area-inset-bottom,0px))}.khala-app .kh-detail{width:auto}}.khala-app .kh-card:not(.has-detail) .kh-detail{visibility:hidden;transition:transform .25s ease,visibility 0s linear .25s}.khala-app .kh-card.has-detail .kh-detail{visibility:visible}.khala-app .kh-card.kh-solo{grid-template-columns:minmax(0,1fr) 0px}.khala-app .kh-card.kh-solo .kh-main{display:flex}.khala-app .kh-solo .kh-brand{border-bottom:1px solid var(--line);padding-bottom:.9rem;background:var(--surface)}@media(max-width:900px){.khala-pending .kh-card{grid-template-rows:auto minmax(0,1fr)}.khala-pending .kh-card .kh-main{display:flex;border-top:1px solid var(--line)}}.kh-brand{display:flex;align-items:center;gap:.55rem;padding:.9rem .8rem .35rem 1rem}.kh-brand .brand-logo{height:24px;width:auto;display:block}.kh-brand .wm{font-family:Bungee,sans-serif;font-size:1.05rem;line-height:1;letter-spacing:.01em;color:var(--fg);text-transform:uppercase;text-decoration:none}.kh-brand-actions{margin-left:auto;min-width:0;display:flex;align-items:center;gap:.4rem}.tool-btn{display:inline-flex;align-items:center;gap:.45rem;border:1px solid var(--pill-bd);background:var(--pill-bg);color:var(--muted);border-radius:999px;padding:.44rem .82rem;font-family:JetBrains Mono,monospace;font-size:.76rem;letter-spacing:.02em;font-weight:500;transition:color .2s ease,border-color .2s ease,background .2s ease}.tool-btn:hover{color:var(--fg);border-color:var(--line-strong)}.tool-btn svg{width:15px;height:15px}.tool-btn.is-on{color:var(--fg);border-color:var(--accent-line);background:var(--accent-soft)}.tool-btn.icon-only{gap:0;padding:0;width:2.05rem;height:2.05rem;justify-content:center;border-radius:50%;aspect-ratio:1;flex:none}.tool-btn:disabled{cursor:wait;opacity:.6}.toggle-icon{display:inline-flex;align-items:center;justify-content:center}.toggle-icon svg{display:block}.toggle-icon .moon,.khala-app[data-theme=light] .toggle-icon .sun{display:none}.khala-app[data-theme=light] .toggle-icon .moon{display:inline}.khala-app .status-badge{display:inline-flex;align-items:center;gap:.42rem;min-height:1.9rem;padding:.3rem .72rem;border-radius:999px;border:1px solid var(--pill-bd);background:var(--pill-bg);color:var(--muted);font-family:JetBrains Mono,monospace;font-size:.72rem;font-weight:600;letter-spacing:.03em}.status-badge-dot{width:.5rem;height:.5rem;border-radius:999px;background:currentColor}.khala-app .status-badge-live{background:var(--good-soft);border-color:var(--good-line);color:var(--good-ink)}.status-badge-live .status-badge-dot{background:var(--good);box-shadow:0 0 8px var(--good);animation:pulse 2s ease-in-out infinite}.status-badge-offline{display:none}@keyframes pulse{0%,to{opacity:1}50%{opacity:.4}}.kh-brand-status{min-width:0;font-size:.72rem;color:var(--muted);text-align:right}.kh-brand-status[role=alert]{color:var(--block-ink)}.kh-av{flex:0 0 auto;width:32px;height:32px;border-radius:50%;display:grid;place-items:center;background:hsl(var(--h) 45% 22%);border:1px solid hsl(var(--h) 60% 50% / .5);cursor:pointer;padding:0}.khala-app[data-theme=light] .kh-av{background:hsl(var(--h) 55% 88%)}.kh-av img{width:17px;height:17px}.kh-av.ghost{visibility:hidden;cursor:default}.kh-av{position:relative}.kh-own{position:absolute;right:-4px;bottom:-4px;min-width:16px;height:16px;padding:0 3px;border-radius:999px;font:700 8px/16px JetBrains Mono,monospace;letter-spacing:-.02em;color:#fff;background:var(--hc, hsl(var(--oh) 65% 29%));border:2px solid var(--bg-2);box-sizing:content-box}.kh-stack .kh-own,.kh-d-hero .kh-own{display:none}.kh-aav{background:var(--hc, hsl(var(--oh) 65% 29%))!important;border-color:transparent}.kh-aav img{filter:brightness(0) invert(1)}.khala-app .kh-av.kh-aav .kh-ini{color:#fff}.kh-hav{background:var(--hc, hsl(var(--oh) 65% 29%))!important;border-color:transparent;color:#fff;font:700 .72rem/1 Space Grotesk,sans-serif;letter-spacing:.02em}.kh-d-hero .kh-hav{font-size:1.3rem}[data-kh-tier="1"].kh-hav{box-shadow:0 0 0 2px var(--bg-2),0 0 0 3.5px var(--hc)}[data-kh-tier="2"].kh-hav{outline:1.5px dashed var(--hc);outline-offset:2px}.kh-more{font:700 .66rem/1 JetBrains Mono,monospace;color:var(--muted);background:var(--surface-3)!important;border-color:var(--line)!important;cursor:default}.kh-gen{background:var(--surface-3)!important;border-color:var(--line)!important;color:var(--faint);font:700 .9rem/1 JetBrains Mono,monospace}.kh-st{position:absolute;left:-2px;top:-2px;width:8px;height:8px;border-radius:50%;border:2px solid var(--surface);background:var(--good)}.kh-st.off{background:var(--faint)}.kh-st.err{background:var(--block)}.kh-ini{font:700 .72rem/1 Space Grotesk,sans-serif;letter-spacing:.02em;color:hsl(var(--h) 75% 72%)}.khala-app[data-theme=light] .kh-ini{color:hsl(var(--h) 60% 35%)}.kh-d-hero .kh-ini{font-size:1.3rem}@media(prefers-reduced-motion:reduce){.khala-app *{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.khala-app :is(button,a,[role=button],input[type=search]):focus-visible{outline:2px solid var(--accent);outline-offset:2px}.khala-app .kh-cv.is-active:focus-visible{outline-color:#fff;outline-offset:-3px}.khala-app .kh-search:focus-within{box-shadow:0 0 0 3px var(--accent-soft)}.khala-app :is(.kh-input,.kh-txt):focus-visible{outline:none}.kh-list>.conversation-list{flex:1;min-height:0;border-right:0;background:none}.kh-main>:not(.kh-toast,.kh-brand){flex:1 1 auto;min-height:0;overflow:auto}.kh-main>.khala-page-frame,.kh-main>.khala-inactive-device{width:100%;padding:clamp(1rem,3vw,2rem)}.kh-main>.channel-page,.kh-main>.channel-page>.khala-page-frame,.kh-main>.channel-page .khala-page-frame__body{display:flex;flex-direction:column;min-height:0;max-width:none;margin:0}.kh-main>.channel-page>.khala-page-frame,.kh-main>.channel-page .khala-page-frame__body{flex:1 1 auto}.kh-main>.channel-page .conversation-layout{flex:1 1 auto;height:auto;min-height:0;border:0;border-radius:0}.kh-main>.kh-channel{display:flex;flex-direction:column;overflow:hidden}.kh-state>.khala-page-frame{width:min(36rem,100%)}.kh-main>.kh-state{place-items:safe center}.kh-fin{position:absolute;inset:0;z-index:40;display:grid;place-items:center;background:var(--bg-2);padding:1.2rem}.kh-fin[hidden]{display:none}.kh-fin-c{width:min(340px,100%);box-sizing:border-box;display:flex;flex-direction:column;align-items:center;gap:.85rem;text-align:center;padding:1.8rem 1.4rem;border-radius:20px;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-lg)}.kh-fin-eb{font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;font-weight:700;color:var(--faint)}.kh-fin-n{font-size:1.45rem;font-weight:700;letter-spacing:-.02em;overflow-wrap:anywhere}.kh-fin .kh-btn{width:100%;height:44px;margin-top:.3rem}h1.kh-fin-n{margin:0}.kh-fin-p{margin:0;font-size:.82rem;color:var(--muted)}.kh-fin-p b{color:var(--fg);font-weight:600}.kh-fin-ok{display:inline-flex;align-items:center;gap:.35rem;font-size:.84rem;font-weight:600;color:var(--good-ink)}.kh-fin-ok svg{width:15px;height:15px}.kh-fin-err{color:var(--block-ink)}.kh-fin a.kh-btn{display:grid;place-items:center;text-decoration:none}.kh-fin--page{position:fixed;inset:0}.khala-app>.kh-brand{position:fixed;top:0;left:0;z-index:41}.kh-fin-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kh-mchip{display:inline-flex;align-items:center;gap:.3rem;padding:2px 8px 2px 6px;border-radius:999px;background:var(--surface-3);border:1px solid var(--line);font:.72rem JetBrains Mono,monospace;color:var(--fg)}.kh-mchip img{width:12px;height:12px}.conversation-layout{display:grid;grid-template-columns:300px minmax(0,1fr);height:min(760px,calc(100dvh - 190px));min-height:540px;border:1px solid var(--khala-line);border-radius:16px;overflow:hidden;background:var(--khala-fill-raised);color:var(--khala-ink)}.conversation-layout--detail{grid-template-columns:300px minmax(0,1fr) 320px}.conversation-list{display:flex;flex-direction:column;min-width:0;min-height:0;border-right:1px solid var(--khala-line);background:var(--khala-fill-raised)}.conversation-list__head{display:flex;align-items:baseline;justify-content:space-between;padding:1rem 1rem .6rem}.conversation-list__head strong{font-size:1.05rem;letter-spacing:-.02em}.conversation-list__head span{font-size:.76rem;color:var(--khala-ink-muted)}.conversation-list__head-actions{display:flex;align-items:center;gap:.45rem}.conversation-list__search{display:flex;align-items:center;gap:.45rem;margin:0 .8rem .6rem;padding:0 .7rem;height:34px;border-radius:10px;background:var(--khala-fill-control);color:var(--khala-ink-muted)}.conversation-list__search svg{width:15px;height:15px;flex:none}.conversation-list__search input{min-width:0;width:100%;border:0;background:none;color:inherit;font:inherit;font-size:.88rem;outline:none}.conversation-list__items{overflow:auto;min-height:0;padding:0 .5rem .6rem}.conversation-list__items>p{text-align:center;font-size:.84rem;color:var(--khala-ink-muted);padding:1.2rem}.conversation-list__item{display:grid;grid-template-columns:44px minmax(0,1fr) auto;align-items:center;gap:.65rem;width:100%;padding:.6rem .55rem;border:0;border-radius:12px;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}.conversation-list__item:hover{background:var(--khala-fill-control)}.conversation-list__item.is-active{background:var(--khala-accent);color:#fff}.conversation-list__item.is-active .conversation-list__preview,.conversation-list__item.is-active time{color:#fffc}.conversation-list__avatar{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;background:var(--khala-fill-control);border:1px solid var(--khala-line);font-weight:700}.conversation-list__copy{display:flex;flex-direction:column;gap:2px;min-width:0}.conversation-list__top{display:flex;align-items:baseline;gap:.5rem}.conversation-list__top strong{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.9rem}.conversation-list__top time{flex:none;font-size:.72rem;color:var(--khala-ink-muted)}.conversation-list__preview{overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:.8rem;line-height:1.35;color:var(--khala-ink-muted)}.conversation-list__unread{background:var(--khala-accent);color:#fff;border-radius:999px;padding:2px 6px;font-size:.7rem}.conversation-thread{display:flex;flex-direction:column;min-height:0;min-width:0}.conversation-thread--empty{align-items:center;justify-content:center;color:var(--khala-ink-muted)}.conversation-thread__head{display:flex;align-items:center;gap:.8rem;padding:.85rem 1.1rem;border-bottom:1px solid var(--khala-line);font-size:.98rem}.conversation-thread__back{display:none;border:0;background:none;color:var(--khala-accent);font-size:1.5rem;cursor:pointer}.conversation-thread__body{min-height:0;overflow:auto;flex:1;background:var(--khala-fill)}.conversation-detail{min-width:0;overflow:auto;border-left:1px solid var(--khala-line);padding:1.1rem}.conversation-detail>button{float:right;border:1px solid var(--khala-line);border-radius:50%;background:none;color:inherit;cursor:pointer}@media(max-width:1100px){.conversation-layout,.conversation-layout--detail{grid-template-columns:260px minmax(0,1fr)}.conversation-layout{position:relative}.conversation-detail{position:absolute;right:0;top:0;bottom:0;width:320px;background:var(--khala-fill-raised);box-shadow:0 8px 30px #0006}}@media(max-width:900px){.conversation-layout,.conversation-layout--detail{grid-template-columns:minmax(0,1fr)}.conversation-layout:not(.conversation-layout--thread) .conversation-thread{display:none}.conversation-layout--thread .conversation-list{display:none}.conversation-thread__back{display:block}.conversation-list{border-right:0}}@media(max-width:760px){.conversation-layout{height:calc(100dvh - 210px);min-height:360px}.conversation-detail{inset:0;width:auto}}.conversation-thread__actions{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;padding:.5rem 1.1rem;color:var(--khala-ink-muted);font-size:.78rem}.conversation-thread__actions button{border:1px solid var(--khala-line);border-radius:999px;background:var(--khala-fill-control);color:var(--khala-ink);padding:.3rem .7rem;cursor:pointer}.conversation-message{display:flex;align-items:flex-end;gap:.55rem;max-width:min(82%,38rem);min-width:0;list-style:none}.conversation-message--mine{align-self:flex-end;flex-direction:row-reverse}.conversation-message__avatar{display:grid;place-items:center;flex:none;width:28px;height:28px;border-radius:50%;background:var(--khala-fill-control);border:1px solid var(--khala-line);color:var(--khala-ink);font-size:.72rem;font-weight:700}.conversation-message--mine .conversation-message__avatar{border-color:var(--khala-accent);color:var(--khala-accent)}.conversation-message--grouped .conversation-message__avatar{visibility:hidden}.conversation-message__bubble{min-width:0;padding:.45rem .55rem;border:1px solid var(--khala-line);border-left:3px solid var(--khala-ink-muted);border-radius:6px;background:var(--khala-fill-raised);color:var(--khala-ink)}.conversation-message--mine .conversation-message__bubble{border-left:1px solid var(--khala-line);border-right:3px solid var(--khala-accent);background:color-mix(in srgb,var(--khala-fill-raised) 90%,var(--khala-accent))}.conversation-message__meta{display:flex;align-items:baseline;flex-wrap:wrap;gap:.35rem;margin-bottom:.2rem;color:var(--khala-ink-muted);font-size:.7rem}.conversation-message__meta strong{color:var(--khala-ink)}.conversation-message__kind{font-weight:600;text-transform:uppercase;letter-spacing:.03em}.conversation-message__meta time{margin-left:auto;font-size:.68rem}.conversation-message--grouped .conversation-message__meta strong{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.conversation-message__content{font-size:.82rem;line-height:1.4;white-space:pre-wrap;overflow-wrap:anywhere}.conversation-message__content p{margin:0}.fixture-messages{display:flex;flex:1;flex-direction:column;gap:.5rem;list-style:none;margin:0;padding:1.1rem;overflow:auto}.conversation-system-event{align-self:center;max-width:min(100%,36rem);list-style:none;text-align:center;color:var(--khala-ink-muted);font-size:.78rem;line-height:1.4;padding:.25rem .65rem}.conversation-system-event__text,.conversation-system-event__actor{display:block}.conversation-system-event__actor{font-size:.68rem;opacity:.8}.conversation-layout .sr-only,.kh-comp .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.conversation-thread__body{display:flex;flex-direction:column}.conversation-thread__head h2{margin:0;font:inherit;font-weight:700}.conversation-layout--no-list{grid-template-columns:minmax(0,1fr)}.conversation-layout--no-list.conversation-layout--detail{grid-template-columns:minmax(0,1fr) 320px}.conversation-thread__actions{justify-content:flex-end;gap:.5rem;padding:.45rem .85rem}.conversation-thread__actions>span{margin-right:auto}.conversation-thread__actions .aiur-shell__icon-button{padding:0;border-radius:50%;width:2.05rem;height:2.05rem}@media(max-width:900px){.conversation-layout--no-list .conversation-thread{display:flex}}@media(max-width:1100px){.conversation-layout--no-list.conversation-layout--detail{grid-template-columns:minmax(0,1fr)}}.conversation-layout{height:100%;min-height:0;border:0;border-radius:0;grid-template-columns:260px minmax(0,1fr)}.conversation-layout--detail{grid-template-columns:260px minmax(0,1fr) 320px}.conversation-list__head{padding:.9rem .85rem .65rem}.conversation-list__search{margin:0 .6rem .5rem;height:36px}.conversation-list__items{padding:0 .35rem .5rem}.conversation-list__item{grid-template-columns:38px minmax(0,1fr) auto;gap:.55rem;padding:.55rem .5rem;border-radius:10px;min-height:62px}.conversation-list__avatar{width:36px;height:36px;background:hsl(var(--avatar-hue) 53% 33%);border-color:hsl(var(--avatar-hue) 55% 42%);color:#fff;font-size:.83rem}.conversation-list__preview{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.76rem}.conversation-list__top strong{font-size:.84rem}.conversation-list__unread{min-width:7px;height:7px;padding:0;overflow:hidden;text-indent:-999px}.conversation-thread__head{min-height:66px;box-sizing:border-box;padding:.65rem 1rem;gap:.75rem;background:var(--khala-fill-raised)}.conversation-thread__identity{min-width:0;flex:1;display:grid;gap:.15rem}.conversation-thread__identity h2{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.94rem}.conversation-thread__header-actions{display:flex;align-items:center;gap:.4rem;flex:none}.conversation-message{align-items:flex-start;max-width:min(86%,42rem);gap:.45rem}.conversation-message__avatar{width:30px;height:30px;background:hsl(var(--avatar-hue) 53% 33%);border-color:hsl(var(--avatar-hue) 55% 42%);color:#fff}.conversation-message--mine .conversation-message__avatar{color:#fff;background:var(--khala-accent);border-color:var(--khala-accent)}.conversation-message__bubble{border:0;border-radius:13px;padding:.5rem .7rem;background:var(--khala-fill-control)}.conversation-message--mine .conversation-message__bubble{border:0;background:color-mix(in srgb,var(--khala-fill-control) 80%,var(--khala-accent))}.conversation-message__meta{margin-bottom:.25rem;font-size:.72rem;gap:.4rem}.conversation-message__meta time{color:var(--khala-ink-muted)}.conversation-message__content{font-size:.88rem;line-height:1.4}@media(max-width:1100px){.conversation-layout,.conversation-layout--detail{grid-template-columns:240px minmax(0,1fr)}}@media(max-width:900px){.conversation-layout,.conversation-layout--detail{grid-template-columns:minmax(0,1fr)}}@media(max-width:760px){.conversation-layout{height:100%;min-height:0}.conversation-message{max-width:calc(100% - .5rem)}.conversation-thread__head{padding:.55rem .7rem}.conversation-thread__header-actions{gap:.25rem}}.conversation-layout.conversation-layout--no-list{grid-template-columns:minmax(0,1fr)}.conversation-layout.conversation-layout--no-list.conversation-layout--detail{grid-template-columns:minmax(0,1fr) 320px}@media(max-width:1100px){.conversation-layout.conversation-layout--no-list.conversation-layout--detail{grid-template-columns:minmax(0,1fr)}}.kh-d-in{padding:1.1rem;display:flex;flex-direction:column;gap:1rem;width:320px;box-sizing:border-box}.kh-d-top{display:flex;align-items:flex-start;justify-content:space-between}.kh-d-x{width:30px;height:30px;border-radius:50%;border:1px solid var(--line);background:var(--surface-2);color:var(--muted);cursor:pointer;font-size:1rem;line-height:1}.kh-d-hero{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.45rem}.kh-d-hero .kh-av{width:64px;height:64px;cursor:default}.kh-d-hero .kh-av img{width:32px;height:32px}.kh-d-hero b{font-size:1.05rem}.kh-d-hero span{font-size:.8rem}.kh-d-hero>span:where(:not(.kh-av)){color:var(--muted)}.kh-d-hero .kh-email{max-width:100%;color:var(--fg);overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}.kh-d-sec{display:flex;flex-direction:column;gap:.4rem;padding:.85rem;border-radius:14px;background:var(--surface-2);border:1px solid var(--hairline)}.kh-d-lbl{font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;color:var(--faint);font-weight:600}.kh-d-sec p{margin:0;font-size:.88rem;line-height:1.45}.kh-d-kv{display:grid;grid-template-columns:auto 1fr;gap:.35rem .8rem;font-size:.82rem}.kh-d-kv dt{color:var(--muted)}.kh-d-kv dd{margin:0;text-align:right;font-family:JetBrains Mono,monospace;font-size:.78rem}.kh-d-act{display:flex;gap:.5rem}.kh-d-act button{flex:1;padding:.55rem;border-radius:12px;border:1px solid var(--line-strong);background:var(--surface-3);color:var(--fg);font:inherit;font-size:.84rem;font-weight:600;cursor:pointer}.kh-d-act button.pri{background:var(--accent);border-color:var(--accent);color:#fff}.kh-d-log{display:flex;flex-direction:column;gap:.45rem;font-size:.82rem;color:var(--muted)}.kh-d-log div{display:flex;gap:.5rem}.kh-d-log time{font-family:JetBrains Mono,monospace;font-size:.72rem;color:var(--faint);flex:0 0 auto;padding-top:1px}.kh-d-owner{white-space:nowrap;max-width:100%;display:inline-flex;align-items:center;gap:.4rem;margin-top:.2rem;padding:3px 10px 3px 3px;border-radius:999px;border:1px solid hsl(var(--oh) 60% 55% / .4);background:hsl(var(--oh) 60% 50% / .1);color:var(--fg);font:inherit;font-size:.78rem;cursor:pointer}.kh-d-owner>span{min-width:0;overflow:hidden;text-overflow:ellipsis}.kh-d-owner b{font-weight:600}.kh-d-owner i{flex:0 0 auto;width:20px;height:20px;border-radius:50%;display:grid;place-items:center;background:var(--hc, hsl(var(--oh) 65% 29%));color:#fff;font:700 8px/1 JetBrains Mono,monospace;font-style:normal}.kh-d-agents{display:flex;flex-direction:column;gap:.5rem}.kh-d-agent{display:flex;align-items:center;gap:.6rem;padding:.4rem;border-radius:12px;border:1px solid transparent;background:none;color:var(--fg);font:inherit;text-align:left;cursor:pointer}.kh-d-agent:hover{background:var(--surface-3)}.kh-d-agent>span{flex:1;min-width:0;display:flex;flex-direction:column;font-size:.84rem}.kh-d-agent em{font-style:normal;color:var(--muted);font-size:.78rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.khala-app .kh-d-owner b{font-size:inherit}.khala-app .kh-d-owner span{font-size:inherit;color:inherit}.khala-app .kh-d-kv{margin:0}.khala-app .kh-d-agent>.kh-av{flex:0 0 auto;display:grid;font-size:inherit}@media(max-width:760px){.kh-d-in{width:auto;padding:1rem .9rem calc(1rem + env(safe-area-inset-bottom,0px))}.kh-d-x{width:36px;height:36px}}.kh-d-rename{display:flex;flex-direction:column;gap:.5rem}.kh-d-rename .kh-row2 .kh-btn{flex:0 0 auto}.kh-d-rename-err{margin:0;color:var(--block-ink);font-size:.78rem;overflow-wrap:anywhere}.kh-uname-page{overflow-y:auto}.kh-uname-card{width:min(400px,100%);box-sizing:border-box;display:flex;flex-direction:column;gap:.85rem;padding:1.6rem 1.4rem;border-radius:20px;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-lg)}.kh-uname-card h1{margin:0;font-size:1.35rem;font-weight:700;letter-spacing:-.02em;outline:none}.kh-uname-card>p{margin:0;font-size:.86rem;color:var(--muted)}@media(max-width:480px){.kh-uname-page{padding:1rem;place-items:start stretch}.kh-uname-card{width:100%;padding:1.2rem 1rem}}.kh-uname{display:flex;flex-direction:column;gap:.45rem}.kh-uname-field{position:relative;display:flex;align-items:center}.kh-uname-at{position:absolute;left:.7rem;color:var(--faint);font-size:.88rem;pointer-events:none}.kh-uname-field .kh-txt{padding-left:1.55rem}.kh-uname-hint,.kh-uname-err{margin:0;font-size:.76rem;color:var(--faint);overflow-wrap:anywhere}.kh-uname-err{color:var(--block-ink)}.kh-txt[aria-invalid=true]{border-color:var(--block-line)}.kh-txt[aria-invalid=true]:focus{border-color:var(--block);box-shadow:0 0 0 3px var(--block-soft)}.kh-uname-actions{display:flex;justify-content:flex-end;gap:.4rem;margin-top:.3rem}.kh-uname-page .kh-uname-actions .kh-btn.pri{flex:1;height:44px}.kh-dlg-scrim{position:absolute;inset:0;z-index:40;display:grid;place-items:center;padding:16px;background:#0006}.kh-dlg{animation:khPopIn .14s ease-out;width:min(400px,100%);box-sizing:border-box;display:flex;flex-direction:column;gap:.75rem;padding:1.2rem 1.1rem;border-radius:14px;background:var(--surface);border:1px solid var(--line-strong);box-shadow:var(--shadow-lg)}.kh-dlg h2{margin:0;font-size:1.05rem;font-weight:700;letter-spacing:-.01em}@media(max-width:480px){.kh-dlg-scrim{place-items:start stretch}.kh-dlg{width:100%}}.kh-prof{position:relative;gap:1.25rem;padding:1.6rem 1.3rem 1.2rem}.kh-prof-h{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.kh-prof-ini{display:flex;align-items:flex-start;gap:1.1rem}.kh-prof-ini>.kh-prof-sec{flex:1;min-width:0;padding-top:.6rem}.kh-prof-av{flex:none;display:grid;place-items:center;width:72px;height:72px;margin:5px 0 5px 5px;border-radius:50%;color:#fff;font-size:1.5rem;font-weight:700;letter-spacing:.02em;box-shadow:0 0 0 4px var(--surface),0 0 0 5px var(--line);transition:background-color .18s ease}.kh-prof-av.is-default>span{opacity:.75}.kh-prof-ini-in{width:3.6rem;padding:0 .5rem;text-align:center;text-transform:uppercase;font-weight:600;letter-spacing:.06em}.kh-prof-ini-in::placeholder{color:var(--faint);opacity:1}.kh-prof-form{display:flex;flex-direction:column;gap:1.1rem}.kh-prof-sec{display:flex;flex-direction:column;gap:.45rem}.kh-prof-lbl{font-size:.72rem;font-weight:600;color:var(--muted)}.kh-prof .kh-uname-actions{margin-top:.2rem}.kh-swatches{display:grid;grid-template-columns:repeat(10,1fr);justify-items:center;gap:.3rem 0}.kh-swatch{display:grid;place-items:center;width:36px;height:36px;padding:0;border:0;border-radius:50%;background:none;cursor:pointer}.kh-swatch>span{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;color:#fff;transition:transform .12s ease}.kh-swatch:hover>span{transform:scale(1.08)}.kh-swatch[aria-checked=true]>span{box-shadow:0 0 0 2px var(--surface),0 0 0 4px var(--fg)}.kh-swatch svg{width:16px;height:16px}.kh-swatch:focus-visible{outline:2px solid var(--accent);outline-offset:3px}@media(max-width:480px),(pointer:coarse){.kh-swatches{grid-template-columns:repeat(5,1fr);gap:.35rem 0}.kh-swatch{width:44px;height:44px}.kh-swatch>span{width:32px;height:32px}}@media(prefers-reduced-motion:reduce){.kh-prof-av,.kh-swatch>span{transition:none}}.channel-event-pill{align-self:center;list-style:none;max-width:100%}.channel-event-pill__link{display:inline-flex;align-items:center;gap:.3rem;padding:.25rem .6rem;border:1px solid var(--khala-line);border-radius:999px;color:var(--khala-ink-muted);font-size:.75rem;text-decoration:none;max-width:100%;box-sizing:border-box}.channel-event-pill__body{min-width:0;overflow-wrap:anywhere}.channel-event-pill__dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.channel-event-pill__dot--success{background:var(--khala-status-positive)}.channel-event-pill__dot--failure{background:var(--khala-status-critical)}.channel-event-pill__dot--attention{background:var(--khala-status-caution)}.channel-event-pill__dot--pending{background:var(--khala-accent)}.channel-event-pill__dot--info{background:var(--khala-ink-muted)}@font-face{font-family:Space Grotesk;src:url(/assets/SpaceGrotesk-Variable-BWuzNAiS.woff2) format("woff2");font-style:normal;font-weight:300 700;font-display:block}@font-face{font-family:JetBrains Mono;src:url(/assets/JetBrainsMono-Variable-CZ7Klmjc.woff2) format("woff2");font-style:normal;font-weight:100 800;font-display:block}@font-face{font-family:Bungee;src:url(/assets/Bungee-Regular-BC4W3tCU.woff2) format("woff2");font-style:normal;font-weight:400;font-display:block}:root,[data-theme=dark]{--aiur-bg: #1a1b1e;--aiur-bg-soft: #161719;--aiur-fg: #edeef0;--aiur-muted: #8c8d93;--aiur-line: rgba(221, 226, 235, .14);--aiur-hairline: rgba(221, 226, 235, .1);--aiur-pill-border: rgba(221, 226, 235, .13);--aiur-pill-bg: rgba(221, 226, 235, .03);--aiur-accent: #2f86ff;--aiur-accent-strong: #0070f0;--aiur-on-accent: #ffffff;--aiur-accent-soft: rgba(47, 134, 255, .15);--aiur-font-body: "Aiur Space Grotesk", system-ui, sans-serif;--aiur-font-mono: "Aiur JetBrains Mono", monospace;--aiur-font-display: "Aiur Bungee", sans-serif;--aiur-topbar-link-size: 13px;--aiur-logo-size: clamp(120px, 18vw, 224px);--aiur-wordmark-size: clamp(40px, 8vw, 96px);--aiur-tagline-size: clamp(16px, 2.2vw, 22px);--aiur-theme-toggle-size: 42px;--aiur-copy-control-size: 28px;--aiur-sun-display: block;--aiur-moon-display: none;--aiur-toggle-rotation: none}[data-theme=light]{--aiur-bg: #e7d6b2;--aiur-bg-soft: #e2cfa6;--aiur-fg: #2a2520;--aiur-muted: #5f5645;--aiur-line: rgba(42, 37, 26, .17);--aiur-hairline: rgba(42, 37, 26, .12);--aiur-pill-border: rgba(42, 37, 26, .16);--aiur-pill-bg: rgba(42, 37, 26, .035);--aiur-accent: #1f57c4;--aiur-accent-strong: #1f57c4;--aiur-on-accent: #ffffff;--aiur-accent-soft: rgba(31, 87, 196, .11);--aiur-sun-display: none;--aiur-moon-display: block;--aiur-toggle-rotation: rotate(360deg)}.khala-app,.khala-content-root{--bg: #16171a;--bg-2: #1a1b1e;--surface: #1e2025;--surface-2: #23262c;--surface-3: #292d34;--fg: #edeef0;--muted: #969aa4;--faint: #676b74;--line: rgba(221, 226, 235, .12);--line-strong: rgba(221, 226, 235, .2);--hairline: rgba(221, 226, 235, .08);--pill-bd: rgba(221, 226, 235, .14);--pill-bg: rgba(221, 226, 235, .04);--accent: #2f86ff;--accent-ink: #8fbcff;--accent-soft: rgba(47, 134, 255, .15);--accent-line: rgba(47, 134, 255, .34);--accent-complement: #c97103;--attn: #e3b341;--attn-ink: #f1cf6f;--attn-soft: rgba(227, 179, 65, .15);--attn-line: rgba(227, 179, 65, .34);--block: #ff7b72;--block-ink: #ffa39c;--block-soft: rgba(255, 123, 114, .14);--block-line: rgba(255, 123, 114, .34);--good: #3fb950;--good-ink: #74d47f;--good-soft: rgba(63, 185, 80, .14);--good-line: rgba(63, 185, 80, .32);--super: #c69bff;--super-ink: #d8bcff;--super-soft: rgba(198, 155, 255, .15);--super-line: rgba(198, 155, 255, .34);--ack: #4fd6c4;--ack-soft: rgba(79, 214, 196, .14);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);--shadow-lg: 0 40px 90px -40px rgba(0, 0, 0, .7);--radius: 16px;--radius-lg: 24px;color-scheme:dark;--khala-font-body: "Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;--khala-font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;--khala-content-measure: 75rem;--khala-panel-radius: 16px;--khala-dialog-radius: 24px;--khala-fill: var(--bg);--khala-fill-raised: var(--surface);--khala-fill-control: var(--surface-3);--khala-ink: var(--fg);--khala-ink-muted: var(--muted);--khala-line: var(--line);--khala-accent: var(--accent);--khala-status-positive: var(--good);--khala-status-caution: var(--attn);--khala-status-critical: var(--block);color:var(--fg);background:var(--bg);font-family:Space Grotesk,system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.5;-webkit-font-smoothing:antialiased;transition:background-color .4s ease,color .4s ease}.khala-app[data-theme=light],.khala-content-root[data-theme=light]{--bg: #e7d6b2;--bg-2: #e2cfa6;--surface: #f4ecd9;--surface-2: #efe5cd;--surface-3: #e9dcbf;--fg: #2a2520;--muted: #756a55;--faint: #9a8e73;--line: rgba(42, 37, 26, .16);--line-strong: rgba(42, 37, 26, .28);--hairline: rgba(42, 37, 26, .1);--pill-bd: rgba(42, 37, 26, .18);--pill-bg: rgba(42, 37, 26, .04);--accent: #1f57c4;--accent-ink: #1a4aa8;--accent-soft: rgba(31, 87, 196, .11);--accent-line: rgba(31, 87, 196, .3);--accent-complement: #8e4d00;--attn: #b8821a;--attn-ink: #8a6210;--attn-soft: rgba(184, 130, 26, .13);--attn-line: rgba(184, 130, 26, .32);--block: #d23b32;--block-ink: #a52a23;--block-soft: rgba(210, 59, 50, .11);--block-line: rgba(210, 59, 50, .3);--good: #1f9d4d;--good-ink: #167038;--good-soft: rgba(31, 157, 77, .13);--good-line: rgba(31, 157, 77, .3);--super: #8a4fd0;--super-ink: #6d3aa8;--super-soft: rgba(138, 79, 208, .12);--super-line: rgba(138, 79, 208, .3);--ack: #0e9e8e;--ack-soft: rgba(14, 158, 142, .13);--shadow-sm: 0 1px 2px rgba(58, 44, 18, .1);--shadow-lg: 0 44px 80px -40px rgba(58, 44, 18, .3);color-scheme:light}:where(.khala-app,.khala-content-root) *,:where(.khala-app,.khala-content-root) *:before,:where(.khala-app,.khala-content-root) *:after{box-sizing:border-box}:where(.khala-app,.khala-content-root) a{color:var(--accent);text-decoration:none;transition:color .14s ease}:where(.khala-app,.khala-content-root) a:hover{color:var(--accent-ink)}:where(.khala-app,.khala-content-root) button{font:inherit;cursor:pointer}:where(.khala-app,.khala-content-root) ::selection{background:var(--accent-soft)}:where(.khala-app,.khala-content-root) .mono{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}:where(.khala-app,.khala-content-root) .num{font-variant-numeric:tabular-nums slashed-zero;font-feature-settings:"tnum" 1,"zero" 1}:is(.khala-app,.khala-content-root) :is(button,a,[role=button],input[type=search]):focus-visible{outline:2px solid var(--accent);outline-offset:2px}.aiur-action,:where(.aiur-actions) button:not([class]){display:inline-flex;align-items:center;justify-content:center;gap:.4rem;min-height:2.25rem;padding:.5rem .85rem;border:1px solid var(--aiur-accent-strong);border-radius:10px;background:var(--aiur-accent-strong);color:var(--aiur-on-accent);cursor:pointer;font-size:.82rem;font-weight:650;text-decoration:none;transition:transform .14s ease,box-shadow .14s ease}.aiur-action:hover,:where(.aiur-actions) button:not([class]):hover{transform:translateY(-1px);box-shadow:0 8px 20px var(--aiur-accent-soft)}.aiur-action:focus-visible,:where(.aiur-actions) button:not([class]):focus-visible{outline:2px solid var(--aiur-accent);outline-offset:3px}.aiur-action:disabled,.aiur-action[aria-disabled=true],:where(.aiur-actions) button:not([class]):disabled,:where(.aiur-actions) button:not([class])[aria-disabled=true]{opacity:.55;cursor:default}.aiur-action:disabled:hover,.aiur-action[aria-disabled=true]:hover,:where(.aiur-actions) button:not([class]):disabled:hover,:where(.aiur-actions) button:not([class])[aria-disabled=true]:hover{transform:none;box-shadow:none}@media(prefers-reduced-motion:reduce){.aiur-action,:where(.aiur-actions) button:not([class]){transition:none}.aiur-action:hover,:where(.aiur-actions) button:not([class]):hover{transform:none}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.khala-content-root{min-height:100dvh}.khala-content-main{min-width:0}.aiur-shell__icon-button{display:inline-flex;align-items:center;justify-content:center;flex:none;width:2.05rem;height:2.05rem;padding:0;border:1px solid var(--khala-line);border-radius:50%;background:var(--khala-fill-control);color:var(--khala-ink-muted);cursor:pointer;transition:color .18s ease,border-color .18s ease,background .18s ease}.aiur-shell__icon-button:hover{color:var(--khala-ink);border-color:var(--khala-accent);background:var(--khala-fill-raised)}.aiur-shell__icon-button:disabled{cursor:wait;opacity:.6}.khala-inactive-device{max-width:36rem;margin:clamp(1rem,8vh,5rem) auto}.khala-device-status{padding:clamp(1rem,3vw,2rem);color:var(--khala-ink-muted)}.khala-device-status [role=alert]{color:var(--khala-ink)}.khala-empty-conversation{display:grid;place-items:center;min-height:min(70dvh,600px);color:var(--khala-ink-muted)}.khala-page-frame{max-width:var(--khala-content-measure);margin:0 auto;min-width:0}.khala-page-frame__header h1{font-size:2rem;font-weight:700;margin:.4rem 0}.panel{background:var(--khala-fill-raised);border:1px solid var(--khala-line);border-radius:var(--khala-panel-radius);padding:1.25rem;margin-top:1rem}.status-badge{display:inline-flex;align-items:center;gap:.4rem;border:1px solid var(--khala-line);border-radius:999px;padding:.2rem .6rem;font-family:var(--khala-font-mono);font-size:.8rem}.status-badge--positive{border-color:var(--khala-status-positive)}.status-badge--caution{border-color:var(--khala-status-caution)}.status-badge--critical{border-color:var(--khala-status-critical)}.create-channel__field{display:flex;flex-direction:column;gap:.35rem;margin-bottom:1rem}.create-channel__field input{min-width:0}.create-channel__status{min-height:1.25rem}.create-channel__share{display:flex;flex-direction:column;gap:.5rem;margin-top:1rem;padding-top:1rem;border-top:1px solid var(--khala-line)}.create-channel__share-url{min-width:0;width:100%;overflow-wrap:anywhere;font-family:var(--khala-font-mono)}.timeline{position:relative;display:flex;flex-direction:column;gap:.75rem;min-width:0}.timeline__status{margin:0 1.1rem;padding:.5rem .75rem;border-radius:var(--khala-panel-radius);background:var(--khala-fill-control)}.timeline__retry-history{align-self:flex-start;margin:0 1.1rem}.timeline__history-loading{position:absolute;top:.5rem;left:50%;transform:translate(-50%);z-index:1;pointer-events:none}.timeline__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.75rem;max-height:60vh;overflow-y:auto;min-width:0;position:relative;overflow-anchor:none}.timeline__empty{color:var(--khala-ink-muted);padding:1rem;text-align:center}.message-content__text{margin:0 0 .5rem;white-space:pre-wrap;overflow-wrap:anywhere}.message-content__text:last-child{margin-bottom:0}.message-content__unavailable{color:var(--khala-ink-muted);font-style:italic}.timeline__viewport{position:relative;display:flex;flex-direction:column;flex:1 1 auto;min-height:0}.timeline__jump{position:absolute;left:50%;bottom:.75rem;transform:translate(-50%);z-index:5}.timeline__jump-latest{display:block;padding:.4rem .9rem;border:1px solid var(--line-strong);border-radius:999px;background:var(--surface);color:var(--fg);box-shadow:0 6px 18px -8px #00000073;font:inherit;font-size:.8rem;font-weight:600;white-space:nowrap;cursor:pointer;animation:timelineJumpIn .16s ease-out}.timeline__jump-latest:hover{background:var(--surface-2)}.timeline__jump-latest:focus-visible{outline:2px solid var(--accent);outline-offset:2px}@keyframes timelineJumpIn{0%{opacity:0;transform:translateY(6px)}}@media(prefers-reduced-motion:reduce){.timeline__jump-latest{animation:none}}.timeline__composer{display:flex;flex-direction:column;gap:.5rem;border-top:1px solid var(--khala-line);padding-top:.75rem}.timeline__composer-label{font-family:var(--khala-font-mono);font-size:.8rem;color:var(--khala-ink-muted)}.timeline__composer-input{min-height:3.5rem;resize:vertical;background:var(--khala-fill-control);color:inherit;border:1px solid var(--khala-line);border-radius:.5rem;padding:.5rem;font-family:inherit}@media(max-width:959px){.timeline__list{max-height:50vh}}.channel-page .khala-page-frame{max-width:none}.channel-page .khala-page-frame__header{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.channel-page .khala-page-frame__body{min-width:0}.channel-page .conversation-layout{height:100%;min-height:0}.kh-channel-thread .timeline{height:100%;gap:0;min-height:0}.channel-share{position:relative;display:flex;align-items:center;flex:none}.channel-share .aiur-shell__icon-button:focus-visible{outline:2px solid var(--khala-accent);outline-offset:2px}.channel-share__feedback{position:absolute;right:0;top:calc(100% + .35rem);z-index:2;width:max-content;max-width:min(15rem,80vw);margin:0;padding:.35rem .55rem;border:1px solid var(--khala-line);border-radius:.45rem;background:var(--khala-fill-raised);color:var(--khala-ink);box-shadow:0 4px 12px #0003;font-size:.75rem;line-height:1.35}.channel-share__fallback{width:min(20rem,80vw);max-width:none;display:grid;gap:.35rem}.kh-cname-scrim{position:absolute;inset:0;z-index:40;display:grid;place-items:center;padding:16px;background:#0006}.kh-cname{width:min(380px,100%);box-sizing:border-box;display:flex;flex-direction:column;gap:.55rem;padding:1.2rem 1.1rem 1.05rem;border-radius:14px;background:var(--surface);border:1px solid var(--line-strong);box-shadow:var(--shadow-lg);color:var(--fg)}.kh-cname h2{margin:0;font-size:.98rem;font-weight:700;letter-spacing:-.01em}.kh-cname-note{margin:0;font-size:.84rem;color:var(--muted);overflow-wrap:anywhere}.kh-cname-form{display:flex;flex-direction:column;gap:.45rem;margin-top:.2rem}.kh-cname-field{position:relative;display:flex;align-items:center}.kh-cname-at{position:absolute;left:.7rem;color:var(--faint);font-size:.88rem;pointer-events:none}.kh-cname-field .kh-txt{flex:1;min-width:0;padding-left:1.55rem}.kh-cname-err{margin:0;font-size:.76rem;color:var(--block-ink);overflow-wrap:anywhere}.kh-cname .kh-txt[aria-invalid=true]{border-color:var(--block-line)}.kh-cname-actions{display:flex;justify-content:flex-end;margin-top:.2rem}@media(max-width:480px){.kh-cname-scrim{place-items:start stretch}.kh-cname{width:100%}.kh-cname-actions .kh-btn{flex:1;height:44px}}.kh-owner-tag{display:inline-block;margin-left:.4rem;padding:.1rem .3rem;border:1px solid var(--line-strong);border-radius:4px;font-size:.55rem;letter-spacing:.05em;color:var(--faint);vertical-align:middle}.kh-remove-agents{color:var(--faint);font-size:.75rem;overflow-wrap:anywhere}html,body,#app{height:100%;margin:0}body{overflow:hidden;background:#16171a;color:#edeef0;font-family:Space Grotesk,system-ui,-apple-system,Segoe UI,sans-serif}button,input,textarea{font:inherit}
@@ -10,8 +10,8 @@
10
10
  <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32-B9Ubw1Dx.png" />
11
11
  <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16-D5waNSZD.png" />
12
12
  <link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon-Du9V6qit.png" />
13
- <script type="module" crossorigin src="/assets/local-K8EcTVxW.js"></script>
14
- <link rel="stylesheet" crossorigin href="/assets/local-R2y0Gl4T.css">
13
+ <script type="module" crossorigin src="/assets/local-BQl2KrE1.js"></script>
14
+ <link rel="stylesheet" crossorigin href="/assets/local-OwDq47O4.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="app"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "khala-cli",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "Khala channels for Claude Code, Codex and Cursor sessions: the khala MCP server, delivery hooks and local channels.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/aiur-team/khala/tree/main/packages/agent#readme",
@@ -1,36 +0,0 @@
1
- import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
-
3
- // ../contracts/src/m1/harness.ts
4
- var LEGACY_HARNESSES = ["claude", "codex", "cursor"];
5
- var HARNESS_REGISTRY = [
6
- { id: "claude", displayName: "Claude Code", modelName: "Claude", logoKey: "claude", steer: true, sync: true, idleWake: "default", registered: true },
7
- { id: "codex", displayName: "Codex", modelName: "Codex", logoKey: "codex", steer: true, sync: true, idleWake: "default", registered: true },
8
- { id: "cursor", displayName: "Cursor", modelName: "Cursor", logoKey: "cursor", steer: true, sync: true, idleWake: "none", registered: true },
9
- { id: "opencode", displayName: "OpenCode", modelName: "OpenCode", logoKey: "opencode", steer: true, sync: true, idleWake: "default", registered: true },
10
- { id: "copilot", displayName: "Copilot CLI", modelName: "Copilot", logoKey: "copilot", steer: true, sync: true, idleWake: "opt-in", registered: true },
11
- { id: "vscode", displayName: "Copilot (VS Code)", modelName: "VSCode", logoKey: "vscode", steer: true, sync: true, idleWake: "opt-in", registered: true },
12
- { id: "gemini", displayName: "Gemini CLI", modelName: "Gemini", logoKey: "gemini", steer: true, sync: true, idleWake: "opt-in", registered: true },
13
- // U29 and U33 establish these capabilities after their spikes.
14
- { id: "antigravity", displayName: "Antigravity CLI", modelName: "Antigravity", logoKey: "antigravity", steer: false, sync: false, idleWake: "none", registered: true },
15
- { id: "qwen", displayName: "Qwen Code", modelName: "Qwen", logoKey: "qwen", steer: true, sync: true, idleWake: "default", registered: true },
16
- { id: "muse", displayName: "Muse Code", modelName: "Muse", logoKey: "muse", steer: false, sync: false, idleWake: "none", registered: true },
17
- { id: "generic", displayName: "MCP agent", modelName: "Agent", logoKey: null, steer: false, sync: false, idleWake: "none", registered: true }
18
- ];
19
- function harnessInfo(id) {
20
- return HARNESS_REGISTRY.find((row) => row.id === id) ?? {
21
- id,
22
- displayName: id.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" "),
23
- modelName: "Agent",
24
- logoKey: null,
25
- steer: false,
26
- sync: false,
27
- idleWake: "none",
28
- registered: false
29
- };
30
- }
31
-
32
- export {
33
- LEGACY_HARNESSES,
34
- HARNESS_REGISTRY,
35
- harnessInfo
36
- };
@@ -1,144 +0,0 @@
1
- import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
- import {
3
- KhalaClientError,
4
- LOCAL_DEFAULT_PORT,
5
- decodeHelperFile
6
- } from "./chunk-2U4E7AM7.mjs";
7
- import {
8
- bundle
9
- } from "./chunk-PFDUXY3N.mjs";
10
- import {
11
- StateError,
12
- ensureStateDir,
13
- readJson,
14
- stateRoot
15
- } from "./chunk-OW3DSTEZ.mjs";
16
-
17
- // src/local/lifecycle.ts
18
- import * as fs from "node:fs/promises";
19
- import { close as closeFd } from "node:fs";
20
- import path from "node:path";
21
- import { fileURLToPath } from "node:url";
22
- import { setTimeout as sleepDefault } from "node:timers/promises";
23
- import { spawn as nodeSpawn } from "node:child_process";
24
- function helperPaths(env = process.env) {
25
- const root = path.join(stateRoot(env), "local");
26
- const candidate = /^\d{1,5}$/u.test(env.KHALA_LOCAL_PORT ?? "") ? Number(env.KHALA_LOCAL_PORT) : 0;
27
- const port = candidate >= 1 && candidate <= 65535 ? candidate : LOCAL_DEFAULT_PORT;
28
- return { root, helperFile: path.join(root, "helper.json"), logFile: path.join(root, "helper.log"), port, origin: `http://127.0.0.1:${port}` };
29
- }
30
- async function readHelperFile(env = process.env) {
31
- const decoded = decodeHelperFile(await readJson(helperPaths(env).helperFile));
32
- if (!decoded.ok) return null;
33
- const file = decoded.value;
34
- if (!Number.isSafeInteger(file.pid) || file.pid <= 0 || !Number.isSafeInteger(file.port) || file.port <= 0 || file.port > 65535 || file.origin !== `http://127.0.0.1:${file.port}` || !/^[A-Za-z0-9_-]{43}$/u.test(file.adminToken)) return null;
35
- return file;
36
- }
37
- function helperBinPath() {
38
- return fileURLToPath(bundle ? new URL("./khala.mjs", import.meta.url) : new URL("../../bin/khala.mjs", import.meta.url));
39
- }
40
- var HELPER_ENV_ALLOWLIST = [
41
- "PATH",
42
- "HOME",
43
- "USER",
44
- "LOGNAME",
45
- "LANG",
46
- "LC_ALL",
47
- "TMPDIR",
48
- "XDG_STATE_HOME",
49
- "NODE_OPTIONS",
50
- "KHALA_EGRESS_LOG",
51
- "KHALA_LOCAL_PORT",
52
- "KHALA_LOCAL_IDLE_MS",
53
- "KHALA_LOCAL_WEB_DIR"
54
- ];
55
- function helperChildEnv(env) {
56
- const childEnv = {};
57
- for (const key of HELPER_ENV_ALLOWLIST) if (env[key] !== void 0) childEnv[key] = env[key];
58
- return childEnv;
59
- }
60
- var attempts = /* @__PURE__ */ new Map();
61
- async function healthy(fetchImpl, file) {
62
- try {
63
- const response = await fetchImpl(`${file.origin}/healthz`, { signal: AbortSignal.timeout(500) });
64
- if (response.status !== 200) {
65
- await response.body?.cancel();
66
- return false;
67
- }
68
- const body = await response.json();
69
- return typeof body === "object" && body !== null && "ok" in body && body.ok === true && "pid" in body && body.pid === file.pid;
70
- } catch {
71
- return false;
72
- }
73
- }
74
- function connection(file) {
75
- return { origin: file.origin, adminToken: file.adminToken };
76
- }
77
- async function attempt(env, deps) {
78
- const fetchImpl = deps.fetch ?? globalThis.fetch;
79
- const spawn = deps.spawn ?? ((command, argv, options) => nodeSpawn(command, [...argv], options));
80
- const sleep = deps.sleep ?? sleepDefault;
81
- const now = deps.now ?? Date.now;
82
- const existing = await readHelperFile(env);
83
- if (existing && await healthy(fetchImpl, existing)) return connection(existing);
84
- const paths = helperPaths(env);
85
- try {
86
- await ensureStateDir(path.join(paths.root, "channels"));
87
- let handle;
88
- let fd;
89
- let spawnFailed = false;
90
- try {
91
- if (deps.openLog) fd = await deps.openLog(paths.logFile);
92
- else {
93
- handle = await fs.open(paths.logFile, "a", 384);
94
- await handle.chmod(384);
95
- fd = handle.fd;
96
- }
97
- const child = spawn(process.execPath, [helperBinPath(), "local", "serve"], {
98
- detached: true,
99
- stdio: ["ignore", fd, fd],
100
- env: helperChildEnv(env),
101
- cwd: paths.root,
102
- shell: false
103
- });
104
- child.on("error", () => {
105
- spawnFailed = true;
106
- });
107
- child.unref();
108
- } finally {
109
- if (handle) await handle.close();
110
- else if (fd !== void 0) {
111
- const descriptor = fd;
112
- await new Promise((resolve) => {
113
- closeFd(descriptor, () => resolve());
114
- });
115
- }
116
- }
117
- const deadline = now() + 5e3;
118
- while (!spawnFailed && now() < deadline) {
119
- const file = await readHelperFile(env);
120
- if (file && await healthy(fetchImpl, file) && !spawnFailed && now() <= deadline) return connection(file);
121
- if (spawnFailed || now() >= deadline) break;
122
- await sleep(100);
123
- }
124
- } catch (error) {
125
- if (error instanceof StateError) throw error;
126
- }
127
- throw new KhalaClientError("internal_error", "helper_unavailable");
128
- }
129
- function ensureHelper(env = process.env, deps = {}) {
130
- const key = helperPaths(env).helperFile;
131
- const pending = attempts.get(key);
132
- if (pending) return pending;
133
- const promise = attempt(env, deps).finally(() => {
134
- attempts.delete(key);
135
- });
136
- attempts.set(key, promise);
137
- return promise;
138
- }
139
-
140
- export {
141
- helperPaths,
142
- readHelperFile,
143
- ensureHelper
144
- };
@@ -1,267 +0,0 @@
1
- import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
- import {
3
- CURSOR_DEFAULT_SESSION,
4
- CURSOR_WORKSPACE_ENV,
5
- cursorSessionId,
6
- readActivity,
7
- readListeningMode
8
- } from "./chunk-ZHMGB3PP.mjs";
9
- import {
10
- listChannels,
11
- readCursor,
12
- unreadCount
13
- } from "./chunk-XUJIJ4KB.mjs";
14
- import {
15
- HARNESS_REGISTRY
16
- } from "./chunk-DPW43YNC.mjs";
17
- import {
18
- SESSION_ID_PATTERN,
19
- readJson
20
- } from "./chunk-OW3DSTEZ.mjs";
21
-
22
- // src/harness/claude.ts
23
- var claude = {
24
- id: "claude",
25
- sessionSources: [(_meta, env) => env.CLAUDE_CODE_SESSION_ID],
26
- codec: void 0,
27
- rejoinable: () => true,
28
- watcherStatus: true
29
- };
30
-
31
- // src/wake/codex.ts
32
- import path from "node:path";
33
-
34
- // src/wake/idle-wake.ts
35
- var CODEX_IDLE_WAKE_NOTICE = "Khala: channel messages are waiting. Continue.";
36
- function codexIdleWakeArgv(sessionId) {
37
- return ["queue", "--thread", sessionId, "--message", CODEX_IDLE_WAKE_NOTICE];
38
- }
39
-
40
- // src/wake/idle-wake-process.ts
41
- import { spawn as nodeSpawn } from "node:child_process";
42
- var CODEX_QUEUE_ENV_ALLOWLIST = [
43
- "PATH",
44
- "HOME",
45
- "USER",
46
- "LOGNAME",
47
- "SHELL",
48
- "LANG",
49
- "LC_ALL",
50
- "TMPDIR",
51
- "CODEX_HOME",
52
- "XDG_CONFIG_HOME",
53
- "XDG_DATA_HOME",
54
- "XDG_STATE_HOME",
55
- "XDG_RUNTIME_DIR"
56
- ];
57
- function scrubbedQueueEnv(source) {
58
- const env = {};
59
- for (const name of CODEX_QUEUE_ENV_ALLOWLIST) {
60
- const value = source[name];
61
- if (value !== void 0) env[name] = value;
62
- }
63
- return env;
64
- }
65
- function createCodexQueueProcessPort(deps) {
66
- const spawn = deps.spawn ?? ((command, argv, options) => nodeSpawn(command, [...argv], options));
67
- const timeoutMs = deps.timeoutMs ?? 1e4;
68
- return {
69
- run(argv, signal) {
70
- return new Promise((resolve) => {
71
- if (signal.aborted) return resolve({ status: "not_started" });
72
- let child;
73
- try {
74
- child = spawn(deps.command, argv, { shell: false, stdio: "ignore", env: scrubbedQueueEnv(deps.env) });
75
- } catch {
76
- return resolve({ status: "not_started" });
77
- }
78
- let timedOut = false;
79
- let stopped = false;
80
- let force = null;
81
- const stop = () => {
82
- if (stopped) return;
83
- stopped = true;
84
- child.kill("SIGTERM");
85
- force = setTimeout(() => {
86
- child.kill("SIGKILL");
87
- }, 500);
88
- };
89
- const timer = setTimeout(() => {
90
- timedOut = true;
91
- stop();
92
- }, timeoutMs);
93
- signal.addEventListener("abort", stop, { once: true });
94
- const settle = (outcome) => {
95
- clearTimeout(timer);
96
- if (force !== null) clearTimeout(force);
97
- signal.removeEventListener("abort", stop);
98
- resolve(outcome);
99
- };
100
- child.on("error", () => settle({ status: "not_started" }));
101
- child.on("close", (code) => settle(timedOut ? { status: "lost", cause: "timeout" } : code === 0 ? { status: "queued" } : { status: "exited", code: code ?? -1 }));
102
- });
103
- }
104
- };
105
- }
106
-
107
- // src/wake/codex.ts
108
- function createCodexWaker(deps) {
109
- if (!SESSION_ID_PATTERN.test(deps.threadId)) throw new TypeError("invalid_thread_id");
110
- const port = deps.port ?? createCodexQueueProcessPort({ command: "codex", env: process.env });
111
- const now = deps.now ?? Date.now;
112
- const stderr = deps.stderr ?? ((line) => {
113
- process.stderr.write(line);
114
- });
115
- const controller = new AbortController();
116
- let pending;
117
- const wakesAtCount = /* @__PURE__ */ new Map();
118
- const identities = /* @__PURE__ */ new Map();
119
- let stopped = false;
120
- let again = false;
121
- let inFlight;
122
- const warn = (warning, status) => {
123
- try {
124
- stderr(JSON.stringify({ ok: false, warning, ...status ? { status } : {} }) + "\n");
125
- } catch {
126
- }
127
- };
128
- const evaluate = async () => {
129
- try {
130
- const channels = await listChannels(deps.files);
131
- const eligible = [];
132
- const currentIdentities = /* @__PURE__ */ new Map();
133
- for (const channel of channels) {
134
- const session = await readJson(channel.files.session);
135
- const metadata = channel.legacy ? null : await readJson(path.join(channel.files.dir, "channel.json"));
136
- currentIdentities.set(channel.key, JSON.stringify([session?.roomId ?? channel.roomId, session?.userId, metadata?.joinedAt]));
137
- if (await readListeningMode(channel.files) === "async") continue;
138
- eligible.push({
139
- channel,
140
- counts: await unreadCount(channel.files.dir),
141
- cursor: await readCursor(channel.files)
142
- });
143
- }
144
- const keys = new Set(currentIdentities.keys());
145
- const changed = /* @__PURE__ */ new Set();
146
- for (const [key, identity] of currentIdentities) {
147
- if (identities.get(key) !== identity) changed.add(key);
148
- }
149
- for (const key of identities.keys()) if (!keys.has(key)) changed.add(key);
150
- if (changed.size) {
151
- for (const [key, wakes2] of [...wakesAtCount]) {
152
- const pairs2 = JSON.parse(key);
153
- if (!pairs2.some(([id]) => changed.has(id))) continue;
154
- wakesAtCount.delete(key);
155
- const remainingPairs = pairs2.filter(([id]) => !changed.has(id));
156
- if (!remainingPairs.length) continue;
157
- const remaining = JSON.stringify(remainingPairs);
158
- wakesAtCount.set(remaining, Math.max(wakes2, wakesAtCount.get(remaining) ?? 0));
159
- }
160
- }
161
- for (const key of changed) identities.delete(key);
162
- for (const [key, identity] of currentIdentities) identities.set(key, identity);
163
- const pairs = eligible.map(({ channel, cursor: cursor2 }) => [channel.key, cursor2.deliveredCount]).sort(([a], [b]) => a.localeCompare(b));
164
- const budgetKey = JSON.stringify(pairs);
165
- if (changed.size) {
166
- const inheritedKey = JSON.stringify(pairs.filter(([key]) => !changed.has(key)));
167
- const newUnread = eligible.some((item) => changed.has(item.channel.key) && item.counts.messages > 0);
168
- wakesAtCount.set(budgetKey, newUnread ? 0 : wakesAtCount.get(inheritedKey) ?? 0);
169
- if (newUnread || !eligible.some((item) => !changed.has(item.channel.key) && item.counts.messages > 0)) pending = void 0;
170
- }
171
- if (!eligible.some((item) => item.counts.messages > 0)) {
172
- pending = void 0;
173
- return;
174
- }
175
- const activity = await readActivity(deps.files);
176
- if (pending && Date.parse(activity.updatedAt) > pending.at) pending = void 0;
177
- const at = now();
178
- if (pending && at - pending.at < (deps.retryAfterMs ?? 6e4)) return;
179
- if (stopped || activity.state !== "idle") return;
180
- const wakes = wakesAtCount.get(budgetKey) ?? 0;
181
- if (wakes >= 2) return;
182
- for (const { channel } of eligible) {
183
- if (await readListeningMode(channel.files) === "async") {
184
- pending = void 0;
185
- return;
186
- }
187
- }
188
- if (stopped) return;
189
- pending = { at };
190
- wakesAtCount.set(budgetKey, wakes + 1);
191
- const outcome = await port.run(codexIdleWakeArgv(deps.threadId), controller.signal);
192
- if (outcome.status !== "queued") warn("codex_queue_failed", outcome.status);
193
- } catch {
194
- warn("codex_waker_error");
195
- }
196
- };
197
- const notify = () => {
198
- if (stopped) return;
199
- if (inFlight) {
200
- again = true;
201
- return;
202
- }
203
- inFlight = (async () => {
204
- do {
205
- again = false;
206
- await evaluate();
207
- } while (again && !stopped);
208
- })().finally(() => {
209
- inFlight = void 0;
210
- if (again && !stopped) notify();
211
- });
212
- };
213
- const timer = setInterval(notify, deps.pollMs ?? 1e3);
214
- timer.unref();
215
- return {
216
- notify,
217
- async stop() {
218
- stopped = true;
219
- again = false;
220
- clearInterval(timer);
221
- controller.abort();
222
- await inFlight;
223
- }
224
- };
225
- }
226
-
227
- // src/harness/codex.ts
228
- var install = async (flags, deps) => (await import("./chunk-6E3UCO22.mjs")).runCodexInstall(flags, deps);
229
- var codex = {
230
- id: "codex",
231
- // A string metadata id wins even when empty or invalid; validation happens after selection.
232
- sessionSources: [(meta, env) => typeof meta?.threadId === "string" ? meta.threadId : env.CODEX_THREAD_ID],
233
- codec: void 0,
234
- install,
235
- uninstall: (flags, deps) => install([...flags, "--uninstall"], deps),
236
- waker: createCodexWaker,
237
- rejoinable: () => true
238
- };
239
-
240
- // src/harness/cursor.ts
241
- var install2 = async (flags, deps) => (await import("./chunk-6E3UCO22.mjs")).runCursorInstall(flags, deps);
242
- var cursor = {
243
- id: "cursor",
244
- sessionSources: [(_meta, env) => cursorSessionId(env[CURSOR_WORKSPACE_ENV])],
245
- codec: void 0,
246
- install: install2,
247
- uninstall: (flags, deps) => install2([...flags, "--uninstall"], deps),
248
- rejoinable: (source) => source !== CURSOR_DEFAULT_SESSION
249
- };
250
-
251
- // src/harness/index.ts
252
- function createAdapterRegistry(adapters) {
253
- const byId = /* @__PURE__ */ new Map();
254
- for (const adapter of adapters) {
255
- if (byId.has(adapter.id)) throw new Error(`duplicate_adapter: ${adapter.id}`);
256
- if (!HARNESS_REGISTRY.some((row) => row.id === adapter.id)) throw new Error(`unregistered_adapter: ${adapter.id}`);
257
- byId.set(adapter.id, adapter);
258
- }
259
- return Object.freeze({ resolve: (id) => byId.get(id) });
260
- }
261
- var ADAPTERS = Object.freeze([claude, codex, cursor]);
262
- var registry = createAdapterRegistry(ADAPTERS);
263
- var adapterFor = registry.resolve;
264
-
265
- export {
266
- adapterFor
267
- };