@clawos-dev/clawd 0.2.185 → 0.2.186-beta.371.fccc918

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.cjs CHANGED
@@ -45254,14 +45254,6 @@ var DEFAULT_PERSONAS = [
45254
45254
  network: true
45255
45255
  }
45256
45256
  },
45257
- {
45258
- personaId: "persona-developer",
45259
- label: "\u5F00\u53D1\u8005",
45260
- model: "opus",
45261
- iconKey: "code",
45262
- public: false,
45263
- sandboxProfile: DEFAULT_BYPASS_PROFILE
45264
- },
45265
45257
  {
45266
45258
  personaId: "persona-builder",
45267
45259
  label: "\u4EBA\u683C\u8BBE\u8BA1\u5E08",
@@ -549,4 +549,4 @@ WARNING: This link could potentially be dangerous`)){let n=window.open();if(n){t
549
549
  * Fabrice Bellard's javascript vt100 for jslinux:
550
550
  * http://bellard.org/jslinux/
551
551
  * Copyright (c) 2011 Fabrice Bellard
552
- */var ZZ=2,QZ=1,JZ=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){var d;if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(e.css.cell.width===0||e.css.cell.height===0)return;let t=this._terminal.options.scrollback===0?0:((d=this._terminal.options.overviewRuler)==null?void 0:d.width)||14,n=window.getComputedStyle(this._terminal.element.parentElement),r=parseInt(n.getPropertyValue("height")),i=Math.max(0,parseInt(n.getPropertyValue("width"))),s=window.getComputedStyle(this._terminal.element),o={top:parseInt(s.getPropertyValue("padding-top")),bottom:parseInt(s.getPropertyValue("padding-bottom")),right:parseInt(s.getPropertyValue("padding-right")),left:parseInt(s.getPropertyValue("padding-left"))},a=o.top+o.bottom,c=o.right+o.left,l=r-a,u=i-c-t;return{cols:Math.max(ZZ,Math.floor(u/e.css.cell.width)),rows:Math.max(QZ,Math.floor(l/e.css.cell.height))}}};let lm;function cm(){return{count:0,byteSum:0,firstT:null,lastT:null}}const um=32,_S=320;function eQ({sessionId:e,client:t}){const n=g.useRef(null),r=g.useRef(null),i=g.useRef(null),s=g.useRef([]),o=g.useRef(cm()),a=g.useRef(!1),[c,l]=g.useState("collapsed"),[u,d]=g.useState(null);g.useEffect(()=>{const v=n.current;if(!v)return;let b=!1;const _=(P,N)=>getComputedStyle(document.documentElement).getPropertyValue(P).trim()||N,x=_("--bg-0","#1B1B1B"),y=_("--text-100","#ECECEC"),S=new YZ({fontFamily:"ui-monospace, SF Mono, Menlo, monospace",fontSize:12,lineHeight:1.2,theme:{background:x,foreground:y},minimumContrastRatio:4.5,cursorBlink:!0,convertEol:!1,scrollback:5e3,allowProposedApi:!0,cols:120,rows:40}),k=new JZ;S.loadAddon(k),De("xterm-mount",{sessionId:e,hostChildCount:v.childNodes.length}),lm!==e&&(De("xterm-trace",`===== SWITCH ${lm??"(initial)"} → ${e} =====`),lm=e),De("xterm-trace","effect-setup-start",{sessionId:e,t:performance.now()}),o.current=cm(),S.open(v);const w=S.onData(P=>{const N=btoa(unescape(encodeURIComponent(P)));t.request("session:pty:input",{sessionId:e,data:N}).catch(()=>{})});return(async()=>{var M;let P=0,N=null,L=null;try{De("xterm-trace","snapshot-rpc-start",{sessionId:e,t:performance.now()});const O=await t.request("session:pty:snapshot",{sessionId:e});if(De("xterm-trace","snapshot-rpc-resolved",{sessionId:e,cancelled:b,byteLen:((M=O==null?void 0:O.data)==null?void 0:M.length)??0,atSeq:O==null?void 0:O.atSeq,t:performance.now()}),b)return;if(O!=null&&O.ok&&typeof O.data=="string"&&O.data.length>0){const $=atob(O.data),z=new Uint8Array($.length);for(let F=0;F<$.length;F++)z[F]=$.charCodeAt(F);N=z}O!=null&&O.ok&&typeof O.atSeq=="number"&&(P=O.atSeq),O!=null&&O.ok&&O.popupKind!=null&&(L=O.popupKind)}catch{}if(b)return;r.current=S,i.current=k;let R=!1,A;const j=S.onRender(()=>{if(!R){R=!0;try{k.fit(),N&&S.write(N),De("xterm-trace","snapshot-flush",{sessionId:e,atSeq:P,pendingFrameCount:s.current.length,frameStatsBeforeFlush:{...o.current},t:performance.now()}),o.current=cm();const O=s.current;s.current=[];let $=0;for(const z of O){if(z.seq!==void 0&&z.seq<=P){$++;continue}S.write(z.bytes)}$>0&&De("xterm-trace","snapshot-flush-dropped",{sessionId:e,dropped:$,atSeq:P}),a.current=!0,L!=null&&(d(L),l("expanded"),requestAnimationFrame(()=>S.focus())),t.request("session:pty:resize",{sessionId:e,cols:S.cols,rows:S.rows}).catch(()=>{})}catch{}S.scrollToBottom(),A?A():setTimeout(()=>A==null?void 0:A(),0)}});A=()=>j.dispose()})(),()=>{De("xterm-trace","cleanup-start",{sessionId:e,pendingFrameCount:s.current.length,termReady:a.current,frameStatsThisMount:{...o.current},t:performance.now()}),b=!0,w.dispose(),S.dispose(),r.current=null,i.current=null,a.current=!1,s.current=[],De("xterm-trace","cleanup-cleared-pending",{sessionId:e,t:performance.now()})}},[e,t]),g.useEffect(()=>{const v=t.on("session:pty",_=>{const x=_;if(x.sessionId!==e||typeof x.data!="string")return;const y=o.current;y.count++,y.byteSum+=x.data.length;const S=performance.now();y.firstT===null&&(y.firstT=S),y.lastT=S;try{const k=atob(x.data),w=new Uint8Array(k.length);for(let P=0;P<k.length;P++)w[P]=k.charCodeAt(P);a.current&&r.current?r.current.write(w):s.current.push({seq:x.seq,bytes:w})}catch{}}),b=t.on("session:control",_=>{const x=_;if(x.sessionId===e)switch(x.kind){case"popup_open":(x.popupKind==="permission"||x.popupKind==="question")&&(d(x.popupKind),l("expanded"),requestAnimationFrame(()=>{var y;return(y=r.current)==null?void 0:y.focus()}));break;case"popup_close":d(null),l("collapsed");break}});return()=>{v(),b(),De("xterm-trace","cleanup-off-listener",{sessionId:e,t:performance.now()})}},[e,t]),g.useEffect(()=>{const v=n.current;if(!v)return;let b=0,_=0;const x=()=>{const S=i.current,k=r.current;if(!(!S||!k)){try{S.fit()}catch{return}try{k.refresh(0,k.rows-1)}catch{}k.cols===b&&k.rows===_||(b=k.cols,_=k.rows,t.request("session:pty:resize",{sessionId:e,cols:k.cols,rows:k.rows}).catch(()=>{}))}},y=new ResizeObserver(()=>x());return y.observe(v),()=>y.disconnect()},[e,t]);const f=()=>{l(v=>{const b=v==="collapsed"?"expanded":"collapsed";return b==="expanded"&&requestAnimationFrame(()=>{var _;return(_=r.current)==null?void 0:_.focus()}),b})},p=c==="expanded"?_S:um,m=_S-um;return h.jsxs("div",{className:"border-t border-border bg-bg-0 overflow-hidden",style:{height:p},"data-testid":"xterm-panel","data-state":c,"data-mode":"tui","data-popup-kind":u??"",children:[h.jsxs("button",{type:"button",onClick:f,className:"flex items-center justify-between w-full px-3 py-1 text-xs text-text-200 bg-bg-200 hover:bg-bg-300 cursor-pointer border-b border-border",style:{height:um,flexShrink:0},"data-testid":"xterm-panel-toggle",children:[h.jsxs("span",{className:"font-mono",children:[u==="permission"&&"⚠️ CC 需要权限确认 — 在下方终端按数字键 / Enter 选择",u==="question"&&"❓ CC 在问问题 — 在下方终端用 ↑/↓ + Enter 选择",u===null&&(c==="collapsed"?"▴ 展开原生 TUI 终端":"▾ 收起 TUI 终端")]}),h.jsx("span",{className:"text-text-200 text-[10px] opacity-60",children:c==="expanded"?"点击收起":"点击展开"})]}),h.jsx("div",{ref:n,className:"p-1",style:{height:m},"data-testid":"xterm-panel-host"})]})}function vM(e,t){const n=fo(),r=e?`session/${e}`:"",i=Si(r)??hc,s=g.useCallback(d=>{!e||!r||n.setData(r,f=>iE(f??hc,d,e))},[n,r,e]),o=g.useCallback(()=>{e&&s({type:"session:change",sessionId:e})},[s,e]),a=g.useCallback(d=>{e&&s({type:"permission:clear",sessionId:e,requestId:d})},[s,e]),c=g.useCallback(d=>{e&&s({type:"permission:request",sessionId:e,requestId:d.requestId,tool:d.tool,input:d.input,...d.toolUseId?{toolUseId:d.toolUseId}:{}})},[s,e]),l=g.useCallback(d=>{e&&s({type:"session:question:clear",sessionId:e,toolUseId:d})},[s,e]),u=g.useCallback((d,f)=>{e&&s({type:"session:question:submitted",sessionId:e,toolUseId:d,answers:f})},[s,e]);return{...i,reset:o,clearPermission:a,restorePermission:c,clearQuestion:l,markQuestionSubmitted:u}}function Sx(e){const t=Si(e?`capabilities/${e}`:"");return e?{capabilities:t??null,loading:!t}:{capabilities:null,loading:!1}}const tQ=50;function nQ({api:e,sessionId:t,toolSessionId:n,pageSize:r=tQ}){const[i,s]=g.useState({messages:[],total:0,loading:!1,hasMore:!1,error:null}),o=g.useRef(0),a=g.useRef(n),c=g.useRef(null),l=g.useRef(0);g.useEffect(()=>{const d=a.current;if(a.current=n,!(c.current!==t)&&!(typeof d=="string"&&d!==n))return;if(s({messages:[],total:0,loading:!1,hasMore:!1,error:null}),o.current=0,!t){c.current=null;return}c.current=t;const m=++l.current;s(v=>({...v,loading:!0,error:null})),(async()=>{try{const v=await e.historyRead({sessionId:t,limit:r});if(m!==l.current)return;o.current=v.offset,s({messages:v.messages??[],total:v.total??0,loading:!1,hasMore:v.offset>0,error:null})}catch(v){if(m!==l.current)return;s({messages:[],total:0,loading:!1,hasMore:!1,error:v.message??"history load failed"})}})()},[e,t,n,r]);const u=g.useCallback(async()=>{if(!t)return;const d=o.current;if(d<=0)return;const f=Math.max(0,d-r),p=d-f;s(m=>({...m,loading:!0,error:null}));try{const m=await e.historyRead({sessionId:t,limit:p,offset:f});o.current=m.offset,s(v=>({...v,messages:[...m.messages??[],...v.messages],loading:!1,hasMore:m.offset>0}))}catch(m){s(v=>({...v,loading:!1,error:m.message??"load more failed"}))}},[e,t,r]);return{...i,loadMore:u}}function xS(e){const t=Pf(e);return t.commandName?t.commandArgs?`${t.commandName} ${t.commandArgs}`:t.commandName:e}function yS(e){return e.kind==="user-text"||e.kind==="user-meta"&&e.metaKind==="slash-command"}function rQ(e,t){const n=t.find(yS);if(!n)return e;const r=xS(n.text);for(let i=e.length-1;i>=0;i--){const s=e[i];if(yS(s)&&xS(s.text)===r)return e.slice(0,i)}return e}function iQ(e){const t=e.lastEventKind==="turn_end"||e.lastEventKind==="error";return e.procAlive&&!t}function sQ(e){return e==="running"||e==="observing"}const oQ=1e6;function aQ(e){if(!e)return;const t=e.contextUsage,n=e.contextWindowSize;if(!t||!n||n<=0)return;const r=t.inputTokens+(t.cacheReadTokens??0)+(t.cacheCreateTokens??0);if(!(r<=0))return Math.round(r/n*100)}function lQ(e){const t=ho(),n=g.useMemo(()=>new f0(t),[t]),r=Si("sessions"),i=g.useMemo(()=>r==null?void 0:r.find(T=>T.sessionId===e),[r,e]),s=i==null?void 0:i.toolSessionId,o=i==null?void 0:i.tool,a=vM(e),{events:c,pendingPermissions:l,status:u,clearPermission:d,restorePermission:f}=a,p=nQ({api:n,sessionId:e,toolSessionId:s}),m=g.useMemo(()=>p.messages.filter(T=>!T.isSidechain),[p.messages]),v=g.useMemo(()=>iR(m,0,o),[m,o]),b=l[0]??null,_=g.useMemo(()=>_G(c,(b==null?void 0:b.requestId)??null),[c,b==null?void 0:b.requestId]),x=g.useMemo(()=>rQ(v,_),[v,_]),y=g.useMemo(()=>_.map((T,D)=>({...T,seq:oQ+D})),[_]),S=g.useMemo(()=>[...x,...y],[x,y]),k=sQ(u),w=c.length>0?c[c.length-1].kind:null,P=iQ({procAlive:k,lastEventKind:w}),N=(i==null?void 0:i.resolvedModel)??(i==null?void 0:i.model),L=g.useMemo(()=>({sessionLabel:(i==null?void 0:i.label)??e,sessionId:e,...N?{model:N}:{},...(()=>{const T=i==null?void 0:i.gitBranch;return T?{gitBranch:T}:{}})(),...(()=>{const T=aQ(i);return T!==void 0?{contextPct:T}:{}})(),...i!=null&&i.cwd?{cwd:i.cwd}:{},...(()=>{const T=i==null?void 0:i.permissionMode;return T?{permissionMode:T}:{}})(),procAlive:k,streamInProgress:P,pinnedAt:(i==null?void 0:i.pinnedAt)??null}),[i,e,N,k,P]),R=g.useMemo(()=>t.isOpen?u==="error"?{kind:"error",message:"session error"}:{kind:"ready"}:{kind:"closed"},[t.isOpen,u]),A=g.useCallback(async T=>{await n.sessionSend(e,T)},[n,e]),j=g.useCallback(async T=>{if(!(i!=null&&i.cwd)||!s)throw new Error("fork requires sessionFile with cwd + toolSessionId");await n.sessionFork({cwd:i.cwd,toolSessionId:s,messageUuid:T})},[n,i==null?void 0:i.cwd,s]),M=g.useCallback(async T=>{await n.sessionRewind({sessionId:e,userMessageId:T,dryRun:!1})},[n,e]),O=g.useCallback(async T=>{await n.sessionUpdate(e,{model:T})},[n,e]),$=g.useCallback(async()=>{await n.sessionNew(e)},[n,e]),z=g.useCallback(async(T,D)=>{const C=l.find(U=>U.requestId===T);C&&d(T);try{await n.permissionRespond({sessionId:e,permissionRequestId:T,allow:D==="allow"})}catch(U){throw!((U==null?void 0:U.message)??"").startsWith("PERMISSION_REQUEST_STALE")&&C&&f(C),U}},[n,e,l,d,f]),F=g.useCallback(async()=>{await p.loadMore()},[p]);return g.useMemo(()=>({lines:S,connState:R,meta:L,historyDone:!p.hasMore,historyLoading:p.loading,pendingPermissions:l,sendText:A,fork:j,rewind:M,switchModel:O,clearSession:$,respondPermission:z,loadMoreHistory:F}),[S,R,L,p.hasMore,p.loading,l,A,j,M,O,$,z,F])}function cQ({api:e,open:t,onOpenChange:n,scope:r,sessionId:i,onShareFile:s,onOpenInTab:o}){const[a,c]=g.useState([]),[l,u]=g.useState(null);g.useEffect(()=>{if(!t)return;let f=!1;return(async()=>{try{const p=await e.attachmentGroupList(i);if(f)return;c(p.entries)}catch(p){f||u(p.message)}})(),()=>{f=!0}},[e,i,t]);async function d(f){try{await e.attachmentGroupRemove(i,f.relPath),c(p=>f.from==="owner"?p.filter(m=>m.relPath!==f.relPath):p.map(m=>m.relPath===f.relPath?{...m,stale:!0}:m))}catch(p){u(p.message)}}return t?h.jsx(MT,{delayDuration:120,children:h.jsxs("div",{"data-testid":"files-drawer",className:"fixed inset-y-0 right-0 z-50 flex w-[420px] flex-col border-l border-border bg-elevated shadow-2xl",children:[h.jsxs("div",{className:"flex items-center justify-between border-b border-border px-4 py-3",children:[h.jsxs("div",{className:"flex items-center gap-2 text-[13px] font-semibold text-text-100",children:[h.jsx(eO,{className:"h-4 w-4"}),"Edited Files"]}),h.jsx("button",{type:"button",onClick:()=>n(!1),className:"flex h-7 w-7 items-center justify-center rounded text-text-400 hover:bg-bg-200 hover:text-text-100","aria-label":"Close drawer",children:h.jsx(Hn,{className:"h-4 w-4"})})]}),h.jsxs("div",{className:"flex-1 overflow-y-auto",children:[h.jsx(uQ,{title:`Session files (${a.length})`,subtitle:"agent Write/Edit 自动入清单",children:a.length===0?h.jsx(hQ,{text:"还没有文件。agent Write/Edit 会自动加入清单。"}):a.map(f=>h.jsx(dQ,{entry:f,onShareLink:()=>s(f.relPath),...o?{onOpenInTab:()=>o(f.relPath)}:{},onRemove:()=>d(f)},f.id))}),l?h.jsx("div",{className:"border-t border-border bg-destructive/5 px-4 py-2 text-[11px] text-destructive",children:l}):null]})]})}):null}function uQ({title:e,subtitle:t,children:n}){return h.jsxs("div",{className:"border-b border-border last:border-b-0",children:[h.jsx("div",{className:"sticky top-0 z-10 flex items-start justify-between bg-elevated px-4 py-2",children:h.jsxs("div",{className:"flex-1",children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wide text-text-300",children:e}),t?h.jsx("div",{className:"mt-0.5 text-[11px] text-text-400",children:t}):null]})}),h.jsx("div",{className:"flex flex-col",children:n})]})}function dQ({entry:e,onShareLink:t,onOpenInTab:n,onRemove:r}){var c;const i=(c=e.mime)!=null&&c.startsWith("image/")?aO:po,s=e.relPath.lastIndexOf("/"),o=s>=0?e.relPath.slice(0,s+1):"",a=s>=0?e.relPath.slice(s+1):e.relPath;return h.jsxs("div",{"data-testid":"files-drawer-group-row",className:re("group flex items-center gap-2 px-4 py-2 hover:bg-bg-200",e.stale&&"opacity-50"),children:[h.jsx(i,{className:"h-4 w-4 shrink-0 text-text-400"}),h.jsxs("div",{className:"min-w-0 flex-1",children:[h.jsxs("div",{className:"flex items-center gap-1.5",children:[h.jsxs(IT,{children:[h.jsx(AT,{asChild:!0,children:h.jsxs("span",{className:"flex min-w-0 items-baseline text-[13px] text-text-100",children:[o?h.jsx("span",{className:"truncate text-text-400",children:o}):null,h.jsx("span",{className:"shrink-0",children:a})]})}),h.jsx(z0,{side:"top",align:"start",className:"max-w-[380px] break-all",children:e.relPath})]}),e.stale&&h.jsx("span",{className:"rounded bg-text-100/10 px-1 py-0 text-[10px] uppercase text-text-400",children:"stale"})]}),h.jsxs("div",{className:"flex items-center gap-1.5 truncate text-[11px] text-text-400",children:[h.jsx("span",{children:e.from}),h.jsx("span",{children:"·"}),h.jsx("span",{children:fQ(e.addedAt)})]})]}),!e.stale&&h.jsxs("div",{className:"flex items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100",children:[n?h.jsx(dm,{icon:h.jsx(fc,{className:"h-3.5 w-3.5"}),title:"Open in tab",onClick:n}):null,h.jsx(dm,{icon:h.jsx(m0,{className:"h-3.5 w-3.5"}),title:"Share link",onClick:t}),e.from==="owner"&&h.jsx(dm,{icon:h.jsx(g0,{className:"h-3.5 w-3.5"}),title:"Remove",onClick:r})]})]})}function dm({icon:e,title:t,onClick:n}){return h.jsx("button",{type:"button",onClick:n,title:t,"aria-label":t,className:"flex h-7 w-7 items-center justify-center rounded text-text-400 hover:bg-text-100/10 hover:text-text-100",children:e})}function hQ({text:e}){return h.jsx("div",{className:"px-4 py-3 text-[12px] italic text-text-400",children:e})}function fQ(e){const t=Date.now()-e;return t<6e4?`${Math.max(1,Math.floor(t/1e3))}s ago`:t<36e5?`${Math.floor(t/6e4)}m ago`:t<864e5?`${Math.floor(t/36e5)}h ago`:`${Math.floor(t/864e5)}d ago`}function pQ({persona:e,open:t,onClose:n,onTogglePublic:r,guestShareUrl:i,onChangeIcon:s,onDelete:o,embedded:a,onLoadPersonality:c,onSavePersonality:l,onDirtyChange:u,initialPersonality:d,onShareCapability:f,readOnly:p=!1,onChangeTool:m}){const[v,b]=g.useState(!1),[_,x]=g.useState(!1),y=()=>{i&&navigator.clipboard.writeText(i).then(()=>{x(!0),setTimeout(()=>x(!1),2e3)})},S=w=>{b(w),u==null||u(w)},k=()=>{v&&!window.confirm("修改未保存,确定关闭?")||n()};return t?h.jsxs(h.Fragment,{children:[!a&&h.jsx("div",{className:"absolute inset-0 z-30 bg-black/30",onClick:k,"aria-hidden":"true"}),h.jsxs("aside",{className:a?"flex h-full w-full flex-col bg-bg-0":"absolute right-0 top-0 z-40 flex h-full w-[420px] flex-col bg-bg-0 border-l border-border shadow-xl","data-testid":"persona-settings-drawer",children:[h.jsxs("header",{className:"flex items-center justify-between border-b border-border px-4 py-3 shrink-0",children:[h.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[h.jsx(DO,{className:"h-4 w-4 text-text-300"}),h.jsx("span",{className:"text-[13px] font-medium text-text-100 truncate",children:"Persona 设置"})]}),h.jsx("button",{type:"button",onClick:k,"aria-label":"关闭",className:"rounded-sm p-1.5 text-text-400 hover:bg-bg-200 hover:text-text-100",children:h.jsx(Hn,{className:"h-4 w-4"})})]}),h.jsxs("div",{className:"flex-1 overflow-y-auto p-6 flex flex-col gap-4",children:[h.jsxs("header",{className:"flex items-start justify-between gap-3",children:[h.jsxs("div",{className:"flex flex-col gap-0.5 min-w-0",children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("h2",{className:"text-lg font-semibold text-text-100 truncate",children:e.label}),e.public?h.jsxs("span",{className:"inline-flex items-center gap-1 rounded-sm bg-bg-200 px-1.5 py-0.5 text-[10px] text-text-200",children:[h.jsx(sO,{className:"h-3 w-3"})," 公开"]}):h.jsxs("span",{className:"inline-flex items-center gap-1 rounded-sm bg-error-dim px-1.5 py-0.5 text-[10px] text-error",children:[h.jsx(rO,{className:"h-3 w-3"})," 已关闭"]})]}),h.jsx("span",{className:"font-mono text-[11px] text-text-400 truncate","data-testid":"persona-id-subtitle",children:e.personaId})]}),h.jsxs("div",{className:"flex items-center gap-1",children:[f?h.jsxs("button",{type:"button",onClick:f,"aria-label":"分享给他人",title:"分享给他人",className:"inline-flex items-center gap-1 rounded-sm px-2 py-1.5 text-xs text-text-200 hover:bg-bg-200 hover:text-text-100",children:[h.jsx(m0,{className:"h-3.5 w-3.5"}),"分享"]}):null,o?h.jsx("button",{type:"button",onClick:o,"aria-label":"删除 persona",className:"rounded-sm p-1.5 text-text-400 hover:bg-bg-200 hover:text-error",children:h.jsx(g0,{className:"h-4 w-4"})}):null]})]}),h.jsx("hr",{className:"border-border"}),r?h.jsxs(h.Fragment,{children:[h.jsxs("section",{className:"flex items-center justify-between gap-3",children:[h.jsxs("div",{className:"flex flex-col gap-0.5",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"公开访问"}),h.jsx("span",{className:"text-[11px] text-text-400",children:"开启后这个 persona 才会出现在「邀请联系人」的可选列表里。关闭即拒所有新分享(已颁出的 token 不受影响)。"})]}),h.jsx(mQ,{checked:e.public??!1,onChange:w=>r(w)})]}),e.public?h.jsxs("section",{className:"flex flex-col gap-1.5","data-testid":"guest-share-link",children:[h.jsxs("div",{className:"flex items-center gap-1.5",children:[h.jsx(pE,{className:"h-3.5 w-3.5 text-text-400","aria-hidden":!0}),h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"访客分享链接"})]}),i?h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("input",{readOnly:!0,value:i,onFocus:w=>w.currentTarget.select(),className:"min-w-0 flex-1 truncate rounded border border-border bg-bg-100 px-2 py-1 text-[12px] text-text-200","data-testid":"guest-share-link-input"}),h.jsx("button",{type:"button",onClick:y,className:"flex shrink-0 items-center gap-1 rounded border border-border px-2 py-1 text-[12px] text-text-200 hover:bg-bg-200","data-testid":"guest-share-link-copy",children:_?h.jsxs(h.Fragment,{children:[h.jsx(Lc,{className:"h-3 w-3"})," 已复制"]}):h.jsxs(h.Fragment,{children:[h.jsx(lf,{className:"h-3 w-3"})," 复制"]})})]}),h.jsx("span",{className:"text-[11px] text-text-400",children:"任何 TTC 员工打开此链接(飞书登录)即可在该 persona 下交互。"})]}):h.jsx("span",{className:"text-[11px] text-text-400","data-testid":"guest-share-link-no-tunnel",children:"需先开启 tunnel(公网访问)才能生成可分享给外部的链接。"})]}):null,h.jsx("hr",{className:"border-border"})]}):null,s?h.jsxs("section",{className:"flex flex-col gap-1.5",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"默认图标"}),h.jsx("span",{className:"text-[11px] text-text-400",children:"新建该 persona 的 session 会默认继承此图标。"}),h.jsx(jT,{value:e.iconKey??null,onChange:s})]}):null,s?h.jsx("hr",{className:"border-border"}):null,m&&!p?h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:"flex flex-col gap-1.5",children:[h.jsx("span",{className:"text-[12px] font-medium text-text-200",children:"Agent"}),h.jsx("div",{className:"flex gap-2",children:["claude","codex"].map(w=>h.jsx("button",{type:"button","data-testid":`persona-edit-tool-${w}`,onClick:()=>m(w),className:re("flex-1 rounded-md border px-3 py-2 text-[12px]",(e.tool??"claude")===w?"border-accent bg-accent/10 text-accent":"border-bg-300 text-text-300"),children:w==="claude"?"Claude Code":"Codex"},w))}),h.jsx("span",{className:"text-[11px] text-text-400",children:"切换只影响之后新建的会话,已有会话保持原 tool。"})]}),h.jsx("hr",{className:"border-border"})]}):null,c?h.jsxs(h.Fragment,{children:[h.jsx(xQ,{onLoad:c,...l?{onSave:l}:{},onDirtyChange:S,initialPersonality:d,readOnly:p}),h.jsx("hr",{className:"border-border"})]}):null,h.jsx(gQ,{settings:e.sandboxSettings??null}),h.jsx("hr",{className:"border-border"}),h.jsx(vQ,{skills:e.skills??[]}),h.jsx("hr",{className:"border-border"}),h.jsx(_Q,{plugins:e.plugins??[]})]})]})]}):null}function mQ({checked:e,onChange:t}){return h.jsx("button",{type:"button",role:"switch","aria-checked":e,onClick:()=>t(!e),"data-testid":"persona-public-toggle",className:re("relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors",e?"bg-success":"bg-bg-300"),children:h.jsx("span",{className:re("inline-block h-5 w-5 rounded-full bg-bg-0 shadow transition-transform",e?"translate-x-[22px]":"translate-x-0.5")})})}function gQ({settings:e}){var t,n,r,i,s,o,a,c,l,u,d,f,p;return h.jsxs("section",{className:"flex flex-col gap-2","data-testid":"persona-sandbox-setting-section",children:[h.jsxs("header",{className:"flex flex-col gap-0.5",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"Sandbox Setting"}),h.jsx("span",{className:"text-[11px] text-text-400",children:"约束此 persona 的沙箱权限(只读,需通过文件修改)。"})]}),e==null?h.jsx("span",{className:"text-[12px] text-text-300","data-testid":"persona-sandbox-setting-empty",children:"暂无 sandbox 配置"}):h.jsxs("div",{className:"flex flex-col gap-1.5 rounded-md border border-border bg-bg-100 px-3 py-2",children:[h.jsx(Vu,{label:"权限默认模式",value:((t=e.permissions)==null?void 0:t.defaultMode)??"—"}),h.jsx(Vu,{label:"沙箱启用",value:hm((n=e.sandbox)==null?void 0:n.enabled)}),h.jsx(Vu,{label:"沙箱内自动放行 Bash",value:hm((r=e.sandbox)==null?void 0:r.autoAllowBashIfSandboxed)}),h.jsx(Vu,{label:"允许非沙箱命令",value:hm((i=e.sandbox)==null?void 0:i.allowUnsandboxedCommands)}),h.jsxs("div",{className:"mt-1 flex flex-col gap-1.5 border-t border-border pt-1.5",children:[h.jsx(hl,{label:"沙箱外命令",paths:(s=e.sandbox)==null?void 0:s.excludedCommands}),h.jsx(hl,{label:"允许读取",paths:(a=(o=e.sandbox)==null?void 0:o.filesystem)==null?void 0:a.allowRead}),h.jsx(hl,{label:"拒绝读取",paths:(l=(c=e.sandbox)==null?void 0:c.filesystem)==null?void 0:l.denyRead}),h.jsx(hl,{label:"允许写入",paths:(d=(u=e.sandbox)==null?void 0:u.filesystem)==null?void 0:d.allowWrite}),h.jsx(hl,{label:"拒绝写入",paths:(p=(f=e.sandbox)==null?void 0:f.filesystem)==null?void 0:p.denyWrite})]})]})]})}function hm(e){return e===!0?"是":e===!1?"否":"—"}function Vu({label:e,value:t}){return h.jsxs("div",{className:"flex items-center justify-between gap-3 text-[12px]",children:[h.jsx("span",{className:"text-text-300",children:e}),h.jsx("span",{className:"font-mono text-text-100",children:t})]})}function hl({label:e,paths:t}){const n=!t||t.length===0;return h.jsxs("div",{className:"flex flex-col gap-1",children:[h.jsx("span",{className:"text-[11px] text-text-300",children:e}),n?h.jsx("span",{className:"text-[11px] text-text-400",children:"—"}):h.jsx("div",{className:"flex flex-wrap gap-1",children:t.map((r,i)=>h.jsx("span",{className:"rounded-sm border border-border bg-bg-0 px-1.5 py-0.5 font-mono text-[11px] text-text-200",children:r},`${e}-${i}-${r}`))})]})}function vQ({skills:e}){return h.jsxs("section",{className:"flex flex-col gap-2","data-testid":"persona-skills-section",children:[h.jsxs("header",{className:"flex flex-col gap-0.5",children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"Persona Skills"}),h.jsx("span",{className:"rounded-sm border border-border px-1.5 py-0.5 text-[10px] text-text-300",children:e.length})]}),h.jsxs("span",{className:"text-[11px] text-text-400",children:["此 persona 私有 skills(来自"," ",h.jsx("code",{className:"font-mono",children:"<persona-dir>/.claude/skills/"}),")。"]})]}),e.length===0?h.jsx("span",{className:"text-[12px] text-text-300","data-testid":"persona-skills-empty",children:"暂无 skills"}):h.jsx("ul",{className:"flex flex-col divide-y divide-border rounded-md border border-border bg-bg-100",children:e.map(t=>h.jsxs("li",{className:"flex flex-col gap-0.5 px-3 py-2","data-testid":"persona-skill-row",children:[h.jsx("span",{className:"font-mono text-[13px] text-text-100",children:t.name}),t.description?h.jsx("span",{className:"text-[12px] text-text-300",children:t.description}):h.jsx("span",{className:"text-[11px] text-text-400 italic",children:"无描述"})]},t.name))})]})}function _Q({plugins:e}){return h.jsxs("section",{className:"flex flex-col gap-2","data-testid":"persona-plugins-section",children:[h.jsxs("header",{className:"flex flex-col gap-0.5",children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"Enabled Plugins"}),h.jsx("span",{className:"rounded-sm border border-border px-1.5 py-0.5 text-[10px] text-text-300",children:e.length})]}),h.jsxs("span",{className:"text-[11px] text-text-400",children:["此 persona 已启用的插件(来自"," ",h.jsx("code",{className:"font-mono",children:"<persona-dir>/.claude/settings.json"})," ","的 ",h.jsx("code",{className:"font-mono",children:"enabledPlugins"}),")。"]})]}),e.length===0?h.jsx("span",{className:"text-[12px] text-text-300","data-testid":"persona-plugins-empty",children:"暂无启用插件"}):h.jsx("ul",{className:"flex flex-col divide-y divide-border rounded-md border border-border bg-bg-100",children:e.map(t=>h.jsx("li",{className:"flex flex-col gap-0.5 px-3 py-2","data-testid":"persona-plugin-row",children:h.jsx("span",{className:"font-mono text-[13px] text-text-100",children:t.id})},t.id))})]})}function xQ({onLoad:e,onSave:t,onDirtyChange:n,initialPersonality:r,readOnly:i=!1}){const s=r!==void 0,[o,a]=g.useState(s),[c,l]=g.useState(s?r:""),[u,d]=g.useState(s?r:""),[f,p]=g.useState(null),[m,v]=g.useState(!1),[b,_]=g.useState(null),x=rt.useRef(e),y=rt.useRef(t),S=rt.useRef(n);rt.useEffect(()=>{x.current=e,y.current=t,S.current=n});const k=rt.useCallback(()=>{a(!1),p(null),x.current().then(L=>{l(L),d(L),a(!0)}).catch(L=>{p(L instanceof Error?L.message:String(L))})},[]);rt.useEffect(()=>{s||k()},[s,k]);const w=!i&&o&&u!==c;rt.useEffect(()=>{i||S.current(w)},[w,i]);const P=()=>{y.current&&(v(!0),_(null),y.current(u).then(()=>{l(u),v(!1)}).catch(L=>{_(L instanceof Error?L.message:String(L)),v(!1)}))},N=()=>{d(c),_(null)};return h.jsxs("section",{className:"flex flex-col gap-2","data-testid":"persona-personality-section",children:[h.jsx("span",{className:"text-[12px] font-medium text-text-200",children:"人格 (Personality)"}),f?h.jsxs("div",{"data-testid":"persona-personality-load-error",className:"rounded-md border border-error bg-error-dim px-3 py-2 text-[12px] text-error flex items-center justify-between gap-2",children:[h.jsxs("span",{children:["加载失败:",f]}),h.jsx("button",{type:"button",onClick:k,className:"rounded-sm border border-error px-2 py-0.5 text-[11px] hover:bg-error/10",children:"重试"})]}):null,b?h.jsxs("div",{"data-testid":"persona-personality-save-error",className:"rounded-md border border-error bg-error-dim px-3 py-2 text-[12px] text-error",children:["保存失败:",b]}):null,h.jsx("textarea",{"data-testid":"persona-personality-textarea",value:u,onChange:L=>d(L.target.value),readOnly:i,disabled:!i&&(!o||m),placeholder:o?"":"加载中…",rows:8,className:"min-h-[8rem] max-h-[18rem] resize-y rounded-md border border-border bg-bg-100 px-2 py-1.5 font-mono text-[11px] text-text-100 disabled:opacity-60"}),!i&&h.jsxs("p",{className:"text-[10px] text-text-400",children:["写入到 ",h.jsx("code",{className:"font-mono",children:"<persona-dir>/CLAUDE.md"}),"。 修改只对新启动的 sub-session 生效。"]}),o&&w?h.jsxs("div",{className:"flex justify-end gap-2",children:[h.jsx("button",{type:"button",onClick:N,disabled:m,className:"rounded-sm border border-border px-2 py-1 text-[12px] text-text-200 hover:bg-bg-200 disabled:opacity-60",children:"放弃"}),h.jsx("button",{type:"button",onClick:P,disabled:m,"data-testid":"persona-personality-save-btn",className:"rounded-sm bg-accent-dim px-2 py-1 text-[12px] text-text-100 hover:opacity-90 disabled:opacity-60",children:m?"保存中…":"保存"})]}):null]})}function yQ({personaId:e,open:t,onClose:n,api:r,embedded:i,onDirtyChange:s,onShareCapability:o,viewerRole:a="owner"}){const{persona:c}=lE(e),l=aL(e),u=lL(),d=cL(),{httpBaseUrl:f}=of(),p=g.useMemo(()=>!(c!=null&&c.public)||!f||/^https?:\/\/(127\.0\.0\.1|localhost|0\.0\.0\.0|\[?::1\]?)([:/]|$)/i.test(f)?null:`${f}/s/${e}`,[c==null?void 0:c.public,f,e]),m=g.useCallback(k=>{u(e,{public:k}).catch(w=>{De("persona","togglePublic failed",w)})},[u,e]),v=g.useCallback(k=>{u(e,{iconKey:k}).catch(w=>{De("persona","changeIcon failed",w)})},[u,e]),b=g.useCallback(k=>{u(e,{tool:k}).catch(w=>{De("persona","changeTool failed",w)})},[u,e]),_=g.useCallback(()=>{c&&confirm(`删除 persona "${c.label}"?`)&&(d(e).catch(k=>{De("persona","delete failed",k)}),n())},[c,d,e,n]),x=g.useCallback(async()=>l.loaded?l.personality:(await l.refresh()).personality,[l]),y=g.useCallback(async k=>{await u(e,{personality:k}),await l.refresh()},[u,e,l]);if(!c)return null;const S=a==="guest";return h.jsx(pQ,{embedded:i,persona:{...c,skills:l.skills,plugins:l.plugins,sandboxSettings:l.sandboxSettings},open:t,onClose:n,onLoadPersonality:x,onDirtyChange:s,readOnly:S,...S?{}:{onTogglePublic:m,guestShareUrl:p,onChangeIcon:v,onChangeTool:b,onDelete:_,onSavePersonality:y,...o?{onShareCapability:o}:{}}})}function bQ({api:e,open:t,onOpenChange:n,personaId:r,personaName:i,viewerRole:s}){return t?h.jsxs("div",{"data-testid":"persona-drawer",className:"fixed inset-y-0 right-0 z-50 flex w-[420px] flex-col border-l border-border bg-elevated shadow-2xl",children:[h.jsxs("div",{className:"flex items-center justify-between border-b border-border px-4 py-3",children:[h.jsxs("div",{className:"flex min-w-0 items-center gap-2 text-[13px] font-semibold text-text-100",children:[h.jsx(v0,{className:"h-4 w-4 shrink-0"}),h.jsxs("span",{className:"truncate",title:i,children:["Persona · ",i]})]}),h.jsx("button",{type:"button",onClick:()=>n(!1),className:"flex h-7 w-7 items-center justify-center rounded text-text-400 hover:bg-bg-200 hover:text-text-100","aria-label":"Close drawer",children:h.jsx(Hn,{className:"h-4 w-4"})})]}),h.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto",children:h.jsx(yQ,{personaId:r,open:!0,onClose:()=>n(!1),api:e,embedded:!0,...s?{viewerRole:s}:{}},r)})]}):null}function wQ(e){try{const t=new URL(e);return t.protocol==="ws:"?t.protocol="http:":t.protocol==="wss:"&&(t.protocol="https:"),`${t.protocol}//${t.host}`}catch{return e}}function SQ(e,t){try{const n=new URL(e),r=new URL(t);return n.protocol=r.protocol,n.host=r.host,n.toString()}catch{return e}}async function _M(e,t,n,r,i){const s=await e.attachmentSignUrl({sessionId:n,relPath:r,...i!==void 0?{ttlSeconds:i}:{}});return SQ(s.url,wQ(t.url))}async function kQ(e,t,n,r,i=60){const s=window.open("about:blank","_blank");try{const o=await _M(e,t,n,r,i);s?s.location.href=o:window.open(o,"_blank")}catch(o){throw s&&s.close(),o}}async function CQ(e){var t;try{if((t=navigator.clipboard)!=null&&t.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{const n=document.createElement("textarea");n.value=e,n.style.position="fixed",n.style.left="-9999px",n.style.top="0",n.setAttribute("readonly",""),document.body.appendChild(n),n.select();const r=document.execCommand("copy");return document.body.removeChild(n),r}catch{return!1}}const EQ={...kc,h1:({node:e,...t})=>h.jsx("h1",{...t,className:"mt-4 mb-3 text-[18px] font-semibold leading-tight text-text-100"}),h2:({node:e,...t})=>h.jsx("h2",{...t,className:"mt-4 mb-2 text-[16px] font-semibold leading-tight text-text-100"}),h3:({node:e,...t})=>h.jsx("h3",{...t,className:"mt-3 mb-2 text-[14px] font-semibold leading-tight text-text-100"}),h4:({node:e,...t})=>h.jsx("h4",{...t,className:"mt-3 mb-1 text-[13px] font-semibold text-text-100"}),h5:({node:e,...t})=>h.jsx("h5",{...t,className:"mt-2 mb-1 text-[12px] font-semibold text-text-100"}),h6:({node:e,...t})=>h.jsx("h6",{...t,className:"mt-2 mb-1 text-[12px] font-semibold text-text-300"}),p:({node:e,...t})=>h.jsx("p",{...t,className:"my-2 leading-relaxed"}),ul:({node:e,...t})=>h.jsx("ul",{...t,className:"my-2 list-disc space-y-1 pl-5"}),ol:({node:e,...t})=>h.jsx("ol",{...t,className:"my-2 list-decimal space-y-1 pl-5"}),li:({node:e,...t})=>h.jsx("li",{...t,className:"leading-relaxed"}),blockquote:({node:e,...t})=>h.jsx("blockquote",{...t,className:"my-2 border-l-2 border-border pl-3 italic text-text-300"}),code:({node:e,className:t,children:n,...r})=>t?h.jsx("code",{...r,className:`${t} font-mono text-[12px]`,children:n}):h.jsx("code",{...r,className:"rounded bg-bg-50 px-1 py-0.5 font-mono text-[12px] text-text-100",children:n}),pre:({node:e,...t})=>h.jsx("pre",{...t,className:"my-2 overflow-auto rounded border border-border bg-bg-0 p-3 text-[12px] font-mono text-text-100"}),hr:({node:e,...t})=>h.jsx("hr",{...t,className:"my-3 border-border"}),table:({node:e,...t})=>h.jsx("table",{...t,className:"my-2 w-full border-collapse text-[12px]"}),thead:({node:e,...t})=>h.jsx("thead",{...t,className:"bg-bg-50"}),th:({node:e,...t})=>h.jsx("th",{...t,className:"border border-border px-2 py-1 text-left font-semibold"}),td:({node:e,...t})=>h.jsx("td",{...t,className:"border border-border px-2 py-1"}),strong:({node:e,...t})=>h.jsx("strong",{...t,className:"font-semibold text-text-100"}),em:({node:e,...t})=>h.jsx("em",{...t,className:"italic"})};function NQ(e){const t=e.split("/");return t[t.length-1]||e}function TQ({open:e,onOpenChange:t,relPath:n,loadMarkdown:r,onShare:i}){const[s,o]=g.useState(null),[a,c]=g.useState(null),[l,u]=g.useState(!1);return g.useEffect(()=>{if(!e||!n)return;let d=!1;return u(!0),c(null),o(null),(async()=>{try{const f=await r(n);if(d)return;o(f)}catch(f){if(d)return;c(f.message||String(f))}finally{d||u(!1)}})(),()=>{d=!0}},[e,n,r]),e?h.jsxs("div",{"data-testid":"md-preview-drawer",className:"fixed inset-y-0 right-0 z-50 flex w-1/2 max-w-[900px] flex-col border-l border-border bg-elevated shadow-2xl",children:[h.jsxs("div",{className:"flex items-center justify-between border-b border-border px-3 py-2",children:[h.jsx("div",{"data-testid":"md-preview-title",className:"truncate text-[13px] font-medium text-text-100",title:n??"",children:n?NQ(n):""}),h.jsxs("div",{className:"flex items-center gap-1",children:[i?h.jsx("button",{type:"button","data-testid":"md-preview-share","aria-label":"Share rendered preview link",onClick:i,className:"inline-flex h-6 w-6 items-center justify-center rounded text-text-400 hover:bg-bg-50 hover:text-text-200",children:h.jsx(pE,{className:"h-4 w-4"})}):null,h.jsx("button",{type:"button","aria-label":"Close preview",onClick:()=>t(!1),className:"inline-flex h-6 w-6 items-center justify-center rounded text-text-400 hover:bg-bg-50 hover:text-text-200",children:h.jsx(Hn,{className:"h-4 w-4"})})]})]}),h.jsx("div",{className:"flex-1 overflow-auto px-4 py-3 text-[13px] text-text-100",children:l?h.jsx("div",{"data-testid":"md-preview-loading",className:"text-text-400",children:"Loading…"}):a?h.jsx("div",{"data-testid":"md-preview-error",className:"text-destructive whitespace-pre-wrap",children:a}):s!==null?h.jsx("div",{"data-testid":"md-preview-content",className:"max-w-none",children:h.jsx(bc,{remarkPlugins:[Sc],components:EQ,children:s})}):null})]}):null}function PQ({left:e,right:t,stage:n,onExpand:r,onCollapse:i}){const s=n==="stopped",[o,a]=g.useState(!1);async function c(){if(!o){a(!0);try{await r()}catch{}finally{a(!1)}}}async function l(){if(!o){a(!0);try{await i()}catch{}finally{a(!1)}}}return h.jsxs("div",{className:"flex h-full w-full min-h-0","data-testid":"two-pane-layout",children:[h.jsxs("div",{className:"relative flex min-w-0 flex-1 flex-col","data-testid":"two-pane-left",children:[s&&h.jsx("button",{type:"button",disabled:o,className:"absolute right-14 top-2 z-10 rounded border border-border bg-elevated px-2 py-1 text-[12px] text-text-100 hover:bg-bg-200 disabled:opacity-50 disabled:cursor-not-allowed",onClick:c,children:o?"启动中…":"展开预览"}),e]}),!s&&h.jsxs("div",{className:"flex w-1/2 min-w-[320px] flex-col border-l border-bg-200","data-testid":"two-pane-right",children:[h.jsx("div",{className:"flex items-center justify-end gap-2 border-b border-bg-200 bg-bg-50 px-2 py-1",children:h.jsx("button",{type:"button",disabled:o,className:"rounded px-2 py-1 text-[12px] text-text-300 hover:bg-bg-100 disabled:opacity-50",onClick:l,children:"收起预览"})}),h.jsx("div",{className:"min-h-0 flex-1",children:t})]})]})}const xM=yR,RQ=bR,yM=g.forwardRef(({className:e,...t},n)=>h.jsx(cx,{ref:n,className:re("fixed inset-0 z-50 bg-black/50 backdrop-blur-sm",e),...t}));yM.displayName=cx.displayName;const kx=g.forwardRef(({className:e,children:t,...n},r)=>h.jsxs(RQ,{children:[h.jsx(yM,{}),h.jsxs(ux,{ref:r,className:re("fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2","gap-4 rounded-lg border border-border bg-elevated p-6 shadow-lg",e),...n,children:[t,h.jsxs(wR,{className:"absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-accent",children:[h.jsx(Hn,{className:"h-4 w-4"}),h.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));kx.displayName=ux.displayName;const Cx=({className:e,...t})=>h.jsx("div",{className:re("flex flex-col space-y-1.5 text-left",e),...t});Cx.displayName="DialogHeader";const Ex=({className:e,...t})=>h.jsx("div",{className:re("flex flex-row justify-end gap-2",e),...t});Ex.displayName="DialogFooter";const Nx=g.forwardRef(({className:e,...t},n)=>h.jsx(dx,{ref:n,className:re("text-lg font-semibold leading-none text-text-100",e),...t}));Nx.displayName=dx.displayName;const bM=g.forwardRef(({className:e,...t},n)=>h.jsx(hx,{ref:n,className:re("text-sm text-text-300",e),...t}));bM.displayName=hx.displayName;const MQ=6173,IQ=6182;function AQ({open:e,onOpenChange:t,projectName:n,currentPort:r,allUsedPorts:i,onUpdate:s}){const o=[];for(let v=MQ;v<=IQ;v++)(v===r||!i.includes(v))&&o.push(v);const[a,c]=g.useState(r),[l,u]=g.useState(!1),[d,f]=g.useState(null),p=a!==r&&!l;async function m(){if(p){u(!0),f(null);try{await s(a),t(!1)}catch(v){f((v==null?void 0:v.message)??String(v))}finally{u(!1)}}}return h.jsx(xM,{open:e,onOpenChange:t,children:h.jsxs(kx,{className:"max-w-md",children:[h.jsxs(Cx,{children:[h.jsxs(Nx,{children:["改端口 · ",n]}),h.jsxs(bM,{children:["手改通常发生在系统其他进程占了默认分配的端口、dev server 起不来时。 提交后 daemon 会停 dev server → 写 ",h.jsx("code",{className:"mx-1 rounded bg-bg-100 px-1 py-0.5 text-[11px]",children:".clawd-project.json"})," → 用新端口重新起。"]})]}),h.jsxs("div",{className:"flex flex-col gap-2",children:[h.jsx("label",{className:"text-xs text-text-400",children:"新端口(仅显示段内可用 + 当前端口)"}),h.jsx("select",{className:"h-9 rounded-md border border-border bg-elevated px-3 py-1 text-sm text-text-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent",value:a,onChange:v=>c(Number(v.target.value)),disabled:l,children:o.map(v=>h.jsxs("option",{value:v,children:[v,v===r?"(当前)":""]},v))}),o.length===1&&h.jsx("div",{className:"text-[11px] text-text-400",children:"端口段已全被其它 project 占用,没有可换的;先删一个 idle project 释放端口。"}),d&&h.jsx("div",{className:"rounded border border-destructive/30 bg-destructive/5 px-3 py-2 text-[12px] text-destructive",children:d})]}),h.jsxs(Ex,{children:[h.jsx(Jr,{variant:"ghost",onClick:()=>t(!1),disabled:l,children:"取消"}),h.jsx(Jr,{onClick:m,disabled:!p,children:l?"应用中…":"应用新端口"})]})]})})}const bS=[{stage:"build",label:"构建"},{stage:"deploy",label:"部署到阿里云"},{stage:"verify",label:"验证可访问性"}];function jQ({currentStage:e,onCancel:t}){const n=bS.findIndex(r=>r.stage===e);return h.jsxs("div",{"data-testid":"publish-progress",className:"flex items-center gap-3 border-b border-bg-200 bg-bg-50 px-3 py-1.5 text-[12px]",children:[bS.map((r,i)=>{const s=i<n,o=i===n,a=s?"text-text-300":o?"text-text-200":"text-text-500/50";return h.jsxs("span",{className:`flex items-center gap-1 ${a}`,children:[s?h.jsx(af,{className:"size-3.5"}):o?h.jsx(tr,{className:"size-3.5 animate-spin"}):h.jsx(dE,{className:"size-3.5"}),h.jsxs("span",{children:[r.label,o?"中…":""]})]},r.stage)}),h.jsx("button",{type:"button",onClick:t,className:"ml-auto rounded px-2 py-0.5 text-[11px] text-text-400 hover:bg-bg-100 hover:text-text-200",children:"取消"})]})}const DQ={build:"构建",deploy:"部署",verify:"验证"};function LQ({stage:e,onRetry:t,onDismiss:n}){return h.jsxs("div",{"data-testid":"publish-interrupted-banner",className:"flex items-center gap-2 border-b border-yellow-400/40 bg-yellow-400/10 px-3 py-1.5 text-[12px]",children:[h.jsx(pc,{className:"size-3.5 text-yellow-500"}),h.jsxs("span",{className:"text-text-200",children:["上次发布在 ",h.jsxs("strong",{className:"font-medium",children:["[",DQ[e],"]"]})," ","阶段被中断(daemon 重启)"]}),h.jsx("button",{type:"button",onClick:t,className:"ml-auto rounded bg-accent-main-100 px-2 py-0.5 text-[11px] text-oncolor-100 hover:opacity-90",children:"重新发布"}),h.jsx("button",{type:"button",onClick:n,className:"rounded px-2 py-0.5 text-[11px] text-text-400 hover:bg-bg-100 hover:text-text-200",children:"取消"})]})}const OQ={build:"构建",deploy:"部署",verify:"验证",unknown:"未知"};function BQ({stage:e,onFocusChat:t,onClose:n}){return h.jsxs("div",{"data-testid":"publish-failed-banner",className:"flex items-center gap-2 border-b border-destructive/40 bg-destructive/10 px-3 py-1.5 text-[12px]",children:[h.jsx(Ss,{className:"size-3.5 text-destructive"}),h.jsxs("button",{type:"button",onClick:t,className:"flex-1 text-left text-text-200 hover:underline",children:["发布失败:",h.jsxs("strong",{className:"font-medium",children:["[",OQ[e],"]"]})," ","已通知 assistant 接管 →"]}),h.jsx("button",{type:"button",onClick:n,"aria-label":"关闭失败提示",className:"rounded p-0.5 text-text-400 hover:bg-bg-100 hover:text-text-200",children:h.jsx(Hn,{className:"size-3.5"})})]})}const wS={"install-pending":{label:"等装依赖…",step:"1/3"},installing:{label:"安装依赖中…(可能要几十秒到几分钟)",step:"2/3"},"starting-dev-server":{label:"启动 dev server…(等监听端口才挂 iframe)",step:"3/3"}};function $Q({project:e,previewHost:t,previewScheme:n,onUpdatePort:r,allUsedPorts:i,publishSlot:s,publishInFlightStage:o,onDismissPublishJob:a,onRetryPublish:c,publishFailureBanner:l,onPublishFailureBannerClose:u,onPublishFailureBannerFocusChat:d}){var _,x;const[f,p]=g.useState(!1);if(!e)return h.jsx("div",{className:"flex h-full w-full items-center justify-center p-6 text-center text-[13px] text-text-400",children:"未绑定 project"});const m=e.stage??(e.isRunning?"running":"stopped"),v=t?`${n}://${t}/preview/${e.port}/`:null,b=e.prodUrl??null;return h.jsxs("div",{className:"flex h-full w-full flex-col","data-testid":"preview-pane",children:[h.jsxs("header",{className:"flex items-center justify-between gap-2 border-b border-bg-200 bg-bg-50 px-3 py-1.5",children:[h.jsxs("div",{className:"flex items-center gap-2 text-[12px]",children:[h.jsx("span",{className:"font-medium text-text-200",children:e.name}),h.jsx("span",{className:"rounded bg-bg-100 px-1.5 py-0.5 text-[11px] text-text-400",children:e.port}),h.jsx("span",{className:"text-[10px] uppercase tracking-wider text-text-500",children:m==="running"?"dev":m})]}),h.jsxs("div",{className:"flex items-center gap-2",children:[b?h.jsxs("a",{href:b,target:"_blank",rel:"noopener noreferrer",title:`打开线上:${b}`,className:"inline-flex items-center gap-1 rounded border border-bg-200 px-2 py-0.5 text-[11px] text-text-300 hover:bg-bg-100",children:[h.jsx(fc,{className:"size-3"}),"打开线上"]}):null,s,h.jsxs(xT,{children:[h.jsx(yT,{asChild:!0,children:h.jsx("button",{type:"button","aria-label":"Project settings",className:"rounded p-1 text-text-400 hover:bg-bg-100",children:h.jsx(AO,{className:"size-3.5"})})}),h.jsxs(B0,{align:"end",children:[h.jsx(Fs,{onSelect:()=>p(!0),children:"Update Port…"}),h.jsxs(Fs,{disabled:!0,title:"rename not supported yet",onSelect:y=>y.preventDefault(),children:["Name: ",e.name]})]})]})]})]}),l?h.jsx(BQ,{stage:l.stage,onClose:()=>u==null?void 0:u(),onFocusChat:()=>d==null?void 0:d()}):null,((_=e.publishJob)==null?void 0:_.status)==="in-flight"?h.jsx(jQ,{currentStage:o??e.publishJob.stage,onCancel:()=>void(a==null?void 0:a())}):null,((x=e.publishJob)==null?void 0:x.status)==="interrupted"?h.jsx(LQ,{stage:e.publishJob.stage,onRetry:()=>void(c==null?void 0:c()),onDismiss:()=>void(a==null?void 0:a())}):null,h.jsx("div",{className:"min-h-0 flex-1",children:m==="failed"?h.jsx(zQ,{reason:e.stageReason}):m==="stopped"?null:m==="running"?v?h.jsx("iframe",{"data-testid":"preview-iframe",className:"size-full border-0 bg-white",src:v,title:"preview"}):h.jsx(SS,{label:"等 tunnel 起来…",step:"-"}):h.jsx(SS,{label:wS[m].label,step:wS[m].step})}),h.jsx(AQ,{open:f,onOpenChange:p,projectName:e.name,currentPort:e.port,allUsedPorts:i,onUpdate:async y=>{await r(y)}})]})}function SS({label:e,step:t}){return h.jsxs("div",{"data-testid":"preview-spinner",className:"flex h-full w-full flex-col items-center justify-center gap-3 p-6 text-center",children:[h.jsx(tr,{className:"size-6 animate-spin text-accent-main-100"}),h.jsx("div",{className:"text-[13px] text-text-200",children:e}),h.jsx("div",{className:"text-[11px] uppercase tracking-wider text-text-500",children:t}),h.jsx("div",{className:"mt-2 max-w-[300px] text-[11px] text-text-500",children:"左侧 chat 可看 assistant 详细进度"})]})}function zQ({reason:e}){return h.jsxs("div",{"data-testid":"preview-failed",className:"flex h-full w-full flex-col items-center justify-center gap-3 p-6 text-center",children:[h.jsx(Ss,{className:"size-6 text-destructive"}),h.jsx("div",{className:"text-[13px] text-text-200",children:"project 启动失败"}),h.jsx("div",{className:"max-w-[400px] text-[12px] text-text-400",children:e??"未知原因 —— 看 ~/.clawd/clawd.log 排查"}),h.jsx("div",{className:"mt-1 max-w-[300px] text-[11px] text-text-500",children:"左侧 chat 可看 assistant 详细进度 / 跟它说怎么修"})]})}function FQ({error:e,onClose:t}){const[n,r]=g.useState(!1),i=async()=>{var a;if(!e)return;const s=e.message;let o=!1;try{(a=navigator.clipboard)!=null&&a.writeText&&(await navigator.clipboard.writeText(s),o=!0)}catch{o=!1}if(!o){const c=document.createElement("textarea");c.value=s,c.style.position="fixed",c.style.opacity="0",document.body.appendChild(c),c.select();try{document.execCommand("copy"),o=!0}catch{o=!1}finally{document.body.removeChild(c)}}o&&(r(!0),setTimeout(()=>r(!1),1500))};return h.jsx(xM,{open:!!e,onOpenChange:s=>{s||(r(!1),t())},children:h.jsxs(kx,{className:"max-w-lg",children:[h.jsx(Cx,{children:h.jsx(Nx,{children:(e==null?void 0:e.title)??"错误"})}),h.jsx("pre",{"data-testid":"rpc-error-message",className:"max-h-72 overflow-auto whitespace-pre-wrap break-words rounded border border-bg-200 bg-bg-50 px-3 py-2 text-[12px] text-text-200",children:(e==null?void 0:e.message)??""}),h.jsxs(Ex,{children:[h.jsx(Jr,{variant:"ghost",onClick:i,className:"gap-1.5",children:n?h.jsxs(h.Fragment,{children:[h.jsx(Lc,{className:"size-3.5"}),"已复制"]}):h.jsxs(h.Fragment,{children:[h.jsx(lf,{className:"size-3.5"}),"复制"]})}),h.jsx(Jr,{onClick:t,children:"关闭"})]})]})})}function HQ(e,t){for(const n of[e,t])if(n)try{const r=new URL(n),i=r.protocol==="https:"||r.protocol==="wss:"?"https":"http";return{host:r.host,scheme:i}}catch{}return{host:null,scheme:"https"}}function UQ({extras:e}){const t=lQ(e.session.sessionId),n=h.jsx(qQ,{state:t,extras:e});return e.session.appBuilderProject?h.jsx(WQ,{state:t,chat:n,extras:e}):n}function WQ({state:e,chat:t,extras:n}){var N;const r=Si("daemon-info"),i=ho(),s=n.api,o=n.session,a=o.appBuilderProject,[c,l]=g.useState(null),u=g.useCallback(()=>{s.appBuilderGetProject(o.sessionId).then(L=>l(L.project)).catch(()=>l(null))},[s,o.sessionId]);g.useEffect(()=>{u()},[u]);const[d,f]=g.useState([]),p=g.useCallback(()=>{s.appBuilderListProjects().then(L=>f(L.projects)).catch(()=>f([]))},[s]);g.useEffect(()=>{p()},[p]),g.useEffect(()=>i.on("appBuilder:project-updated",R=>{const A=R;A!=null&&A.project&&(A.project.name===a&&l(A.project),f(j=>{const M=j.findIndex($=>$.name===A.project.name);if(M<0)return[...j,A.project];const O=j.slice();return O[M]=A.project,O}))}),[i,a]);const{host:m,scheme:v}=HQ(i.url,r==null?void 0:r.tunnelUrl),[b,_]=g.useState(void 0),[x,y]=g.useState(null);g.useEffect(()=>{const L=i.on("appBuilder:publish-progress",A=>{const j=A;!j||j.name!==a||j.status==="started"&&_(j.stage)}),R=i.on("appBuilder:publish-failed",A=>{const j=A;!j||j.name!==a||(_(void 0),y({stage:j.stage}))});return()=>{L(),R()}},[i,a]),g.useEffect(()=>{_(void 0),y(null)},[a]);const[S,k]=g.useState(null),w=h.jsx("button",{type:"button",className:"rounded bg-accent-main-100 px-2.5 py-1 text-[12px] text-oncolor-100 hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",disabled:((N=c==null?void 0:c.publishJob)==null?void 0:N.status)==="in-flight",onClick:async()=>{try{await s.appBuilderPublish(a)}catch(L){k({title:"发布请求失败",message:(L==null?void 0:L.message)??String(L)})}},children:"发布上线"}),P=(c==null?void 0:c.stage)??(c!=null&&c.isRunning?"running":"stopped");return h.jsxs(h.Fragment,{children:[h.jsx(PQ,{left:t,stage:P,onExpand:async()=>{await s.appBuilderStartDevServer(o.sessionId)},onCollapse:async()=>{await s.appBuilderStopDevServer(o.sessionId)},right:h.jsx($Q,{project:c,previewHost:m,previewScheme:v,allUsedPorts:d.map(L=>L.port),onUpdatePort:async L=>{await s.appBuilderUpdateProjectPort(a,L),p()},publishSlot:w,publishInFlightStage:b,onDismissPublishJob:async()=>{try{await s.appBuilderDismissPublishJob(a)}catch(L){k({title:"取消发布失败",message:(L==null?void 0:L.message)??String(L)})}},onRetryPublish:async()=>{try{await s.appBuilderPublish(a)}catch(L){k({title:"重新发布失败",message:(L==null?void 0:L.message)??String(L)})}},publishFailureBanner:x,onPublishFailureBannerClose:()=>y(null),onPublishFailureBannerFocusChat:()=>{}})}),h.jsx(FQ,{error:S,onClose:()=>k(null)})]})}function VQ({headerMeta:e,connState:t,models:n,liveGitBranch:r,liveWorktreeRoot:i,onOpenConfig:s,onForceStop:o,cronActiveCount:a,onCronClick:c,lines:l,pendingPermissions:u,procAlive:d,rewindableUserMessageIds:f,onPermissionRespond:p,onPermissionInterrupt:m,onRewind:v,onFork:b,onQuickAsk:_,topSlot:x,realtimeQuestionAnswers:y,onSubmitQuestion:S,onCancelQuestion:k,liveQuestionToolUseIds:w,api:P,cwd:N,tool:L,sessionKey:R,onSend:A,awaitingUser:j,onAbort:M,onNewSession:O,onClearSession:$,chatRootRef:z,chatBodyRef:F,topSentinelRef:T,drawers:D,xtermSlot:C,fileSharingScope:U,onShareFile:V,onOpenInTab:I,onPreviewMarkdown:ae,onOpenFiles:te,onTogglePin:Z,personaName:ye,onOpenPersona:Fe}){return h.jsx(bK,{children:h.jsxs("div",{ref:z,"data-cc-chat-root":"",className:"flex flex-col h-full bg-bg-0",children:[h.jsx(pG,{meta:e,...L?{tool:L}:{},connState:t,...n?{models:n}:{},...r!==void 0?{liveGitBranch:r}:{},...i!==void 0?{liveWorktreeRoot:i}:{},...s?{onOpenConfig:s}:{},...o?{onForceStop:o}:{},cronActiveCount:a,...c?{onCronClick:c}:{},...te?{onOpenFiles:te}:{},...Z?{onTogglePin:Z}:{},...ye?{personaName:ye}:{},...Fe?{onOpenPersona:Fe}:{}}),h.jsxs("div",{ref:F,"data-testid":"chat-body",className:"flex-1 overflow-y-auto min-h-0",style:{overflowAnchor:"none"},children:[T?h.jsx("div",{ref:T,"data-testid":"top-sentinel","aria-hidden":"true",style:{height:1}}):null,h.jsx(JP,{lines:l,...p?{onPermissionRespond:p}:{},...m&&d?{onPermissionInterrupt:m}:{},topSlot:x,...v?{onRewind:v}:{},rewindableUserMessageIds:f,...b?{onFork:b}:{},..._?{onQuickAsk:_}:{},realtimeQuestionAnswers:y,onSubmitQuestion:S,...k?{onCancelQuestion:k}:{},liveQuestionToolUseIds:w,...U?{fileSharingScope:U}:{},...V?{onShareFile:V}:{},...I?{onOpenInTab:I}:{},...ae?{onPreviewMarkdown:ae}:{}})]}),C,h.jsx(hG,{meta:e,...P?{api:P}:{},cwd:N,...L?{tool:L}:{},sessionKey:R,onSend:A,awaitingUser:j,...M?{onAbort:M}:{},...O?{onNewSession:O}:{},...$?{onClearSession:$}:{}}),D]})})}function qQ({state:e,extras:t}){const{session:n,api:r,models:i,liveGitBranch:s,liveWorktreeRoot:o,onNewSession:a,onTurnEnd:c,onOpenConfig:l,onFork:u,onQuickAsk:d,viewerRole:f}=t,{capabilities:p}=Sx(n.tool||"claude"),m=(p==null?void 0:p.features)??{rewind:!0,subagents:!0,tui:!0,fileSharing:!0,fork:!0},[v,b]=g.useState(null),[_,x]=g.useState(!1),[y,S]=g.useState(!1),k=of(),w=!!r&&k.actionsLevel==="owner"&&m.fileSharing,P=lE(n.ownerPersonaId??null).persona,N=(P==null?void 0:P.label)??null,L=!!N&&!!n.ownerPersonaId,R=g.useCallback(()=>{S(!1),x(!0)},[]),A=g.useCallback(()=>{x(!1),S(!0)},[]),j=g.useCallback((q,oe)=>{b({kind:q,text:oe}),setTimeout(()=>{b(pe=>(pe==null?void 0:pe.text)===oe?null:pe)},2e3)},[]),M=ho(),O=BD(),$=vM(n.sessionId,n.toolSessionId),{events:z,pendingQuestions:F,clearQuestion:T,markQuestionSubmitted:D,status:C}=$,U=e.historyLoading,V=C==="running"||C==="observing";g.useEffect(()=>{De("chat-panel","sessionStatus",{sessionId:n.sessionId,sessionStatus:C,procAlive:V})},[C,V,n.sessionId]);const I=e.lines,ae=e.pendingPermissions,te=ae[0]??null,Z=g.useMemo(()=>I8(z),[z]),[ye,Fe]=g.useState(!1),[ue,Me]=g.useState(null),[Be,We]=g.useState(()=>new Set);P8(r,n.sessionId,n.toolSessionId);const ve=g.useRef(n.sessionId);g.useEffect(()=>{ve.current=n.sessionId;let q=!1;return Me(null),(async()=>{try{const oe=await r.sessionRewindableMessageIds(n.sessionId);if(q)return;Me(new Set(oe.userMessageIds))}catch{q||Me(null)}})(),()=>{q=!0}},[r,n.sessionId]);const Ge=g.useCallback(()=>{const q=n.sessionId;r.sessionRewindableMessageIds(q).then(oe=>{ve.current===q&&Me(new Set(oe.userMessageIds))}).catch(()=>{})},[r,n.sessionId]),fn=g.useMemo(()=>{if(ue!==null){const Ie=new Set(ue);for(const An of Be)Ie.delete(An);return Ie}const q=new Set(["Edit","Write","MultiEdit","NotebookEdit"]),oe=new Set;let pe=null;for(const Ie of I)Ie.kind==="user-text"?pe=Ie.uuid??null:pe&&Ie.kind==="tool-call"&&q.has(Ie.tool)&&!Be.has(pe)&&oe.add(pe);return oe},[I,Be,ue]),[Pt,mt]=g.useState({}),Xt=g.useRef({}),wt=g.useRef(c);wt.current=c,g.useEffect(()=>{var An;const q=n.sessionId;if(z.length===0){Xt.current[q]=-1;return}const oe=Xt.current[q]??-1;let pe=0,Ie=oe;for(const It of z){if(It.kind!=="turn_end"&&It.kind!=="error")continue;const Es=It.seq??-1;Es<=oe||(pe++,Es>Ie&&(Ie=Es))}pe!==0&&(Xt.current[q]=Ie,mt(It=>{const Es=It[q]??0,qa=Math.max(0,Es-pe);if(Es===qa)return It;if(qa===0){const{[q]:SJ,...kM}=It;return kM}return{...It,[q]:qa}}),(An=wt.current)==null||An.call(wt),Ge())},[z,n.sessionId,Ge]),R8(n.sessionId,n.toolSessionId,()=>{be(null),We(new Set),mt(q=>{if(!q[n.sessionId])return q;const{[n.sessionId]:oe,...pe}=q;return pe})}),Pt[n.sessionId];const lt=z.length>0?z[z.length-1]:null,Ye=lt!==null&&(lt.kind==="turn_end"||lt.kind==="error"),ct=FG({sessionStatus:C,daemonStreaming:V&&!Ye}),Yt=g.useRef(null);g.useEffect(()=>{const q=Yt.current;q!==ct&&(Yt.current=ct,De("session-phase",ct,{sid:n.sessionId,phase:ct,prev:q,desc:zG[ct]}))},[ct,n.sessionId]);const on=g.useCallback(()=>{const q=n.sessionId;mt(oe=>{if(!oe[q])return oe;const{[q]:pe,...Ie}=oe;return Ie})},[n.sessionId]),H=g.useCallback(async q=>{const oe=n.sessionId;mt(pe=>({...pe,[oe]:(pe[oe]??0)+1}));try{await e.sendText(q)}catch(pe){throw mt(Ie=>{const An=Ie[oe]??0;if(An<=0)return Ie;const It=An-1;if(It===0){const{[oe]:Es,...qa}=Ie;return qa}return{...Ie,[oe]:It}}),pe}},[e,n.sessionId]),X=g.useCallback(()=>{on(),r.sessionInterrupt(n.sessionId).catch(()=>{})},[r,n.sessionId,on]),[_e,be]=g.useState(null),Q=g.useCallback(q=>{be(q)},[]),[Ze,Rt]=g.useState(!1),bn=g.useCallback(()=>{on(),r.sessionStop(n.sessionId).catch(()=>{}),Rt(!1)},[r,n.sessionId,on]),de=g.useCallback(q=>{r.pinSession(n.sessionId,q).catch(oe=>{De("chat-panel","pinSession failed",{err:oe==null?void 0:oe.message})})},[r,n.sessionId]),Te=g.useRef(0),Qe=g.useRef(null);g.useEffect(()=>{const q=oe=>{if(oe.key!=="Escape")return;if(!V){Te.current=0;return}if(oe.isComposing)return;const Ie=oe.target;if(Ie&&Ie.closest("[data-cc-chat-root]")!==Qe.current)return;const An=Date.now();An-Te.current<2e3?(Te.current=0,Rt(!0)):(Te.current=An,X())};return window.addEventListener("keydown",q),()=>window.removeEventListener("keydown",q)},[X,V]);const an=g.useRef(null),In=g.useRef(null),za=g.useRef(!0),Oi=g.useRef(null),Fa=g.useRef(0),bo=g.useRef(0);g.useEffect(()=>{za.current=!0,Oi.current=null,Fa.current=0,bo.current=0},[n.sessionId]),g.useEffect(()=>{Fe(!1)},[n.sessionId]);const Yc=g.useRef(e);Yc.current=e;const Zc=g.useCallback(()=>{var pe;const q=an.current;if(!q||Oi.current!==null)return;const oe=Yc.current;oe.historyDone||oe.historyLoading||(Oi.current={distFromBottom:q.scrollHeight-q.scrollTop},(pe=oe.loadMoreHistory)==null||pe.call(oe))},[]);g.useEffect(()=>{const q=an.current,oe=In.current;if(!q||!oe)return;const pe=new IntersectionObserver(Ie=>{for(const An of Ie)An.isIntersecting&&Zc()},{root:q,threshold:0});return pe.observe(oe),()=>pe.disconnect()},[Zc]),g.useEffect(()=>{const q=an.current;if(!q)return;const oe=150,pe=Ie=>{Date.now()<bo.current&&(Ie.preventDefault(),bo.current=Date.now()+oe)};return q.addEventListener("wheel",pe,{passive:!1}),()=>q.removeEventListener("wheel",pe)},[]),g.useEffect(()=>{const q=an.current;if(!q)return;const oe=32,pe=()=>{const Ie=q.scrollHeight-q.scrollTop-q.clientHeight;za.current=Ie<=oe};return q.addEventListener("scroll",pe,{passive:!0}),()=>q.removeEventListener("scroll",pe)},[]),g.useLayoutEffect(()=>{const q=an.current;if(!q)return;const oe=Fa.current,pe=I.length;Fa.current=pe;const Ie=Oi.current;if(Ie!==null&&pe>oe){Oi.current=null,q.scrollTop=q.scrollHeight-Ie.distFromBottom,bo.current=Date.now()+200;return}Ie!==null&&(Oi.current={distFromBottom:q.scrollHeight-q.scrollTop}),za.current&&(q.scrollTop=q.scrollHeight)},[I,te==null?void 0:te.requestId]);const Qc=g.useMemo(()=>{const q={};for(const[oe,pe]of Object.entries(F))pe.submittedAnswers&&(q[oe]=pe.submittedAnswers);return q},[F]),wo=g.useMemo(()=>new Set(Object.keys(F)),[F]),So=g.useCallback(async(q,oe)=>{try{await r.answerQuestion({sessionId:n.sessionId,toolUseId:q,answers:oe}),D(q,oe)}catch{}},[r,n.sessionId,D]),Ha=g.useCallback(async q=>{try{await r.cancelQuestion({sessionId:n.sessionId,toolUseId:q}),T(q)}catch{}},[r,n.sessionId,T]),Ua=g.useCallback(async(q,oe)=>{var pe;if(te)try{await((pe=e.respondPermission)==null?void 0:pe.call(e,te.requestId,q?"allow":"deny"))}catch{}},[e,te]),Bi=g.useCallback(async()=>{const q=n.sessionId;try{await r.sessionStop(q)}catch{}e.clearSession?await e.clearSession():await r.sessionNew(q)},[e,r,n.sessionId]),$i=g.useMemo(()=>U&&I.length===0?h.jsx("div",{className:"flex justify-center py-4","data-testid":"history-loading",children:h.jsx(tr,{className:"w-4 h-4 text-text-400 animate-spin"})}):e.historyDone?null:h.jsx("div",{className:"flex justify-center py-2",children:h.jsx("button",{type:"button",onClick:()=>{var q;return void((q=e.loadMoreHistory)==null?void 0:q.call(e))},disabled:U,"data-testid":"history-load-more",className:"text-[12px] text-text-400 hover:text-text-200 cursor-pointer px-3 py-1 rounded-md border border-bg-300 hover:bg-bg-100 transition-colors disabled:opacity-60",children:U?"加载中…":"Load earlier messages"})}),[U,I.length,e.historyDone,e.loadMoreHistory]),Jc=e.meta,Df=h.jsxs(h.Fragment,{children:[n.toolSessionId&&m.subagents?h.jsx(yG,{api:r,cwd:n.cwd,toolSessionId:n.toolSessionId}):null,_e&&m.rewind?h.jsx(wG,{open:!0,onOpenChange:q=>{q||be(null)},api:r,sessionId:n.sessionId,userMessageId:_e,lines:I,procAlive:V,onNoChanges:q=>{We(oe=>{if(oe.has(q))return oe;const pe=new Set(oe);return pe.add(q),pe})}}):null,Ze?h.jsx(KQ,{onConfirm:bn,onCancel:()=>Rt(!1)}):null,h.jsx($G,{open:ye,onClose:()=>Fe(!1),jobs:Z})]}),Dt={kind:"session",sessionId:n.sessionId},Wa=g.useCallback(async q=>{if(r)try{await kQ(r,M,n.sessionId,q)}catch(oe){const pe=oe.message;De("chat-panel","open-in-tab failed",{err:pe}),j("err",`Open in tab 失败:${pe}`)}},[r,M,n.sessionId,j]),[Lf,St]=g.useState(!1),[Mt,ir]=g.useState(null),sr=g.useCallback(q=>{ir(q),St(!0)},[]),ko=g.useCallback(async q=>{if(!r)throw new Error("daemon api not ready");const oe=await _M(r,M,n.sessionId,q,60),pe=await fetch(oe);if(!pe.ok)throw new Error(`fetch ${pe.status} ${pe.statusText}`);return await pe.text()},[r,M,n.sessionId]),Va=g.useCallback(async(q,oe)=>{if(r)try{const{url:pe}=await r.attachmentSignUrl({sessionId:n.sessionId,relPath:q,ttlSeconds:86400,...oe?{view:oe}:{}}),Ie=await CQ(pe);j(Ie?"ok":"err",Ie?"分享链接已复制到剪贴板(24h 有效)":"复制失败:请手动复制")}catch(pe){const Ie=pe.message;De("chat-panel","share-file failed",{err:Ie}),j("err",`生成分享链接失败:${Ie}`)}},[r,n.sessionId,j]);return h.jsxs(h.Fragment,{children:[h.jsx(VQ,{headerMeta:Jc,connState:e.connState,...i?{models:i}:{},...s!==void 0?{liveGitBranch:s}:{},...o!==void 0?{liveWorktreeRoot:o}:{},...l?{onOpenConfig:l}:{},onForceStop:()=>Rt(!0),cronActiveCount:Z.length,onCronClick:()=>Fe(!0),lines:I,pendingPermissions:ae,procAlive:V,rewindableUserMessageIds:fn,onPermissionRespond:Ua,onPermissionInterrupt:X,onRewind:m.rewind?Q:void 0,...u&&m.fork?{onFork:u}:{},...d&&m.fork?{onQuickAsk:d}:{},topSlot:$i,realtimeQuestionAnswers:Qc,onSubmitQuestion:So,onCancelQuestion:Ha,liveQuestionToolUseIds:wo,api:r,cwd:n.cwd,...n.tool?{tool:n.tool}:{},sessionKey:n.sessionId,onSend:H,awaitingUser:ae.length>0||Object.values(F).some(q=>!q.submittedAnswers),onAbort:X,...a?{onNewSession:a}:{},onClearSession:Bi,chatRootRef:Qe,chatBodyRef:an,topSentinelRef:In,drawers:Df,xtermSlot:O==="tui"&&V&&m.tui?h.jsx(eQ,{sessionId:n.sessionId,client:M},n.sessionId):null,fileSharingScope:Dt,...r?{onShareFile:Va}:{},...r?{onOpenInTab:Wa}:{},...r?{onPreviewMarkdown:sr}:{},...w?{onOpenFiles:R}:{},onTogglePin:de,...L?{personaName:N}:{},...L?{onOpenPersona:A}:{}}),w&&r?h.jsx(cQ,{api:r,open:_,onOpenChange:x,scope:Dt,sessionId:n.sessionId,onShareFile:Va,onOpenInTab:Wa}):null,r?h.jsx(TQ,{open:Lf,onOpenChange:St,relPath:Mt,loadMarkdown:ko,onShare:Mt?()=>void Va(Mt,"md-rendered"):void 0}):null,L&&r&&n.ownerPersonaId?h.jsx(bQ,{api:r,open:y,onOpenChange:S,personaId:n.ownerPersonaId,personaName:N??"",...f?{viewerRole:f}:{}}):null,v?h.jsx("div",{"data-testid":"share-toast",role:"status","aria-live":"polite",className:v.kind==="ok"?"fixed left-1/2 top-4 z-50 -translate-x-1/2 rounded-md border border-emerald-500/40 bg-emerald-500/10 px-3 py-2 text-[12px] text-emerald-700 shadow-md dark:text-emerald-300":"fixed left-1/2 top-4 z-50 -translate-x-1/2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-[12px] text-destructive shadow-md",children:v.text}):null]})}function KQ({onConfirm:e,onCancel:t}){return h.jsx("div",{role:"dialog","aria-modal":"true","data-testid":"force-stop-confirm",className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40",onClick:t,children:h.jsxs("div",{className:"max-w-sm w-[92%] rounded-lg border border-red-400/40 bg-bg-0 p-4 shadow-xl",onClick:n=>n.stopPropagation(),children:[h.jsxs("div",{className:"flex items-start gap-2 mb-3",children:[h.jsx(pc,{className:"w-5 h-5 text-red-500 shrink-0 mt-0.5"}),h.jsx("div",{className:"text-[14px] text-text-100",children:"强制停止会话进程?会丢失 initialize / 预热缓存,下一次发送需要重新 spawn。"})]}),h.jsxs("div",{className:"flex justify-end gap-2",children:[h.jsx("button",{type:"button",onClick:t,className:"h-8 px-3 rounded-md text-[12px] text-text-300 hover:bg-text-100/5 cursor-pointer",children:"取消"}),h.jsx("button",{type:"button","data-testid":"force-stop-confirm-ok",onClick:e,className:"h-8 px-3 rounded-md bg-red-500 text-white text-[12px] font-medium hover:bg-red-600 cursor-pointer",children:"强制停止"})]})]})})}function GQ({current:e,models:t,onSelect:n}){return h.jsxs("div",{children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-2",children:"Model"}),h.jsx("div",{className:"flex flex-wrap gap-1.5","data-testid":"config-model-selector",children:t.map(r=>{const i=(e||"")===r.id;return h.jsx("button",{type:"button",onClick:()=>n(r.id),"data-testid":`config-model-${r.id||"default"}`,className:re("px-3 py-1.5 rounded-lg text-[12px] font-medium transition-colors cursor-pointer",i?"bg-accent text-white shadow-sm":"bg-bg-100 text-text-300 hover:bg-bg-200 hover:text-text-100"),children:r.label},r.id||"default")})})]})}function XQ({current:e,modes:t,onSelect:n}){var i;const r=(i=t.find(s=>s.id===(e||"")))==null?void 0:i.description;return h.jsxs("div",{children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-2",children:"Permission Mode"}),h.jsx("div",{className:"flex flex-wrap gap-1.5","data-testid":"config-mode-selector",children:t.map(s=>{const o=(e||"")===s.id;return h.jsx("button",{type:"button",onClick:()=>n(s.id),"data-testid":`config-mode-${s.id||"default"}`,className:re("px-3 py-1.5 rounded-lg text-[12px] font-medium transition-colors cursor-pointer",o?"bg-accent text-white shadow-sm":"bg-bg-100 text-text-300 hover:bg-bg-200 hover:text-text-100"),children:s.label},s.id||"default")})}),r?h.jsx("p",{className:"text-[11px] text-text-400 mt-1.5",children:r}):null]})}function YQ({open:e,onOpenChange:t,session:n,onPatch:r,embedded:i=!1,viewerRole:s="owner"}){var p;const{capabilities:o}=Sx(e?n.tool||"claude":null),a=(o==null?void 0:o.models)??[],c=(o==null?void 0:o.permissionModes)??[],l=((p=o==null?void 0:o.configSchema.find(m=>m.name==="permissionMode"))==null?void 0:p.default)??"",u=n.permissionMode&&c.some(m=>m.id===n.permissionMode)?n.permissionMode:l,d=g.useMemo(()=>(o==null?void 0:o.configSchema.filter(m=>m.scope==="tool-specific"))??[],[o]);if(!e)return null;const f=h.jsxs("div",{className:"flex-1 min-h-0 flex flex-col px-4 py-4 gap-6 overflow-y-auto",children:[h.jsxs("div",{className:"shrink-0",children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-1",children:"Working Directory"}),h.jsx("div",{className:"text-[12px] font-mono text-text-300 bg-bg-100 rounded-lg px-3 py-2 truncate","data-testid":"config-cwd",title:n.cwd,children:n.cwd})]}),h.jsx("div",{className:"shrink-0",children:h.jsx(GQ,{current:n.model??"",models:a,onSelect:m=>void r({model:m})})}),h.jsx("div",{className:"shrink-0",children:h.jsx(XQ,{current:u,modes:c,onSelect:m=>void r({permissionMode:m})})}),d.length>0?h.jsx("div",{className:"shrink-0",children:h.jsx(ZQ,{fields:d,session:n,onPatch:r})}):null]});return i?h.jsxs("div",{"data-testid":"config-drawer",className:"h-full w-full flex flex-col",children:[h.jsx("div",{className:"flex items-center px-4 py-3 border-b border-bg-300/30 shrink-0",children:h.jsx("span",{className:"text-[14px] font-semibold text-text-100",children:"Session Settings"})}),f]}):h.jsxs("div",{"data-testid":"config-drawer",className:"h-full flex flex-col border-l border-bg-300/40 bg-bg-0 shrink-0",style:{width:360,minWidth:360},children:[h.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-bg-300/30 shrink-0",children:[h.jsx("span",{className:"text-[14px] font-semibold text-text-100",children:"Session Settings"}),h.jsx("button",{type:"button",onClick:()=>t(!1),"data-testid":"config-drawer-close",className:"flex items-center justify-center w-7 h-7 rounded-md text-text-400 hover:text-text-100 hover:bg-text-100/5 transition-colors cursor-pointer","aria-label":"Close",children:h.jsx(Hn,{className:"w-4 h-4"})})]}),f]})}function ZQ({fields:e,session:t,onPatch:n}){return h.jsxs("div",{"data-testid":"config-advanced",children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-2",children:"Advanced"}),h.jsx("div",{className:"space-y-3",children:e.map(r=>h.jsx(QQ,{field:r,session:t,onPatch:n},r.name))})]})}function QQ({field:e,session:t,onPatch:n}){if(e.type!=="select"||!e.options)return null;const r=t[e.name]??"",i=e.options.some(s=>s.value===r)?r:e.default??"";return h.jsxs("div",{"data-testid":`config-advanced-${e.name}`,children:[h.jsx("div",{className:"text-[11px] text-text-400 mb-1.5",children:e.label}),h.jsx("div",{className:"flex flex-wrap gap-1.5",children:e.options.map(s=>{const o=i===s.value;return h.jsx("button",{type:"button","data-testid":`config-advanced-${e.name}-${s.value||"default"}`,onClick:()=>void n({[e.name]:s.value}),className:re("px-3 py-1.5 rounded-lg text-[12px] font-medium transition-colors cursor-pointer",o?"bg-accent text-white shadow-sm":"bg-bg-100 text-text-300 hover:bg-bg-200 hover:text-text-100"),children:s.label},s.value||"default")})})]})}function JQ(e,t,n=0){const[r,i]=g.useState(null),[s,o]=g.useState(!1),a=g.useCallback(async()=>{if(!t){i(null);return}o(!0);try{const c=await e.getGitBranch(t);i(c.branch??null)}catch{i(null)}finally{o(!1)}},[e,t]);return g.useEffect(()=>{a()},[a,n]),{branch:r,loading:s,refresh:()=>void a()}}function eJ(e,t,n=0){const[r,i]=g.useState(null),[s,o]=g.useState(!1),a=g.useCallback(async()=>{if(!t){i(null);return}o(!0);try{const c=await e.getGitRoot(t);i(c.gitRoot??null)}catch{i(null)}finally{o(!1)}},[e,t]);return g.useEffect(()=>{a()},[a,n]),{worktreeRoot:r,loading:s,refresh:()=>void a()}}function tJ({api:e,session:t,focused:n,totalPanes:r,onFocus:i,onClose:s,onNewSession:o,onOpenConfig:a,onConfigPatch:c,onFork:l,onQuickAsk:u,className:d,viewerRole:f="owner"}){const{capabilities:p}=Sx(t.tool),[m,v]=g.useState(0),[b,_]=g.useState(!1),{branch:x}=JQ(e,t.cwd,m),{worktreeRoot:y}=eJ(e,t.cwd,m),S=r>1,k=w=>{w==="desktop"?_(!0):a()};return h.jsxs("div",{className:`group/pane relative flex-1 ${d??"flex"} flex-row min-w-0 min-h-0 overflow-hidden ${S?`rounded-md border transition-colors ${n?"border-accent ring-1 ring-accent":"border-border"}`:""}`,onMouseDown:i,"data-testid":`session-pane-${t.sessionId}`,children:[h.jsx("div",{className:"flex-1 flex flex-col min-w-0 min-h-0",children:h.jsx(nJ,{api:e,session:t,models:p==null?void 0:p.models,liveGitBranch:x,liveWorktreeRoot:y,onNewSession:o,onTurnEnd:()=>v(w=>w+1),onOpenConfig:k,onFork:l,onQuickAsk:u,viewerRole:f})}),b?h.jsx("div",{className:"hidden md:flex h-full",children:h.jsx(YQ,{open:b,onOpenChange:_,session:t,onPatch:c,viewerRole:f})}):null,S&&h.jsx("button",{type:"button",onClick:w=>{w.stopPropagation(),s()},className:"absolute top-1.5 right-1.5 z-10 p-1 rounded-md bg-bg-100/80 backdrop-blur-sm border border-border opacity-0 group-hover/pane:opacity-100 transition-opacity text-text-400 hover:text-text-100 hover:bg-bg-200","aria-label":"close pane","data-testid":`session-pane-close-${t.sessionId}`,children:h.jsx(Hn,{className:"w-3.5 h-3.5"})})]})}function nJ({api:e,session:t,models:n,liveGitBranch:r,liveWorktreeRoot:i,onNewSession:s,onTurnEnd:o,onOpenConfig:a,onFork:c,onQuickAsk:l,viewerRole:u}){return h.jsx(UQ,{extras:{session:t,api:e,...n?{models:n}:{},...r!==void 0?{liveGitBranch:r}:{},...i!==void 0?{liveWorktreeRoot:i}:{},onNewSession:s,onTurnEnd:o,onOpenConfig:a,...c?{onFork:d=>{c(d)}}:{},...l?{onQuickAsk:d=>{l(d)}}:{},...u?{viewerRole:u}:{}}})}function rJ({personas:e,sessions:t,api:n,selfPrincipalId:r,selectedPersonaId:i,selectedSessionId:s,selectedSession:o,onSelectPersona:a,onSelectSession:c,onCreateSession:l,onDeleteSession:u,onEditSession:d,onCloseSession:f,onConfigPatch:p}){return h.jsxs("div",{className:"flex h-screen min-h-0 bg-bg-50","data-testid":"guest-share-page",children:[h.jsx("aside",{className:"w-[280px] shrink-0 overflow-y-auto border-r border-border bg-bg-50",children:h.jsx(E8,{personas:e,sessions:t,activePersonaId:i,activeSessionId:s,onSelectPersona:a,onSelectSession:c,onCreateSession:l,onDeleteSession:u,onEditSession:d,showCopyResume:!1,treatSessionsAsRoots:!0,...r?{ownerPrincipalId:r}:{},isPersonaExpanded:()=>!0})}),h.jsx("main",{className:"flex-1 min-w-0 min-h-0 flex",children:o?h.jsx(tJ,{api:n,session:o,focused:!0,totalPanes:1,onFocus:()=>{},onClose:f,onNewSession:()=>{},onOpenConfig:()=>{},onConfigPatch:p,viewerRole:"guest"}):h.jsx("div",{className:"flex flex-1 items-center justify-center p-6 text-xs text-text-400","data-testid":"guest-share-empty",children:"选择左侧 persona 开始对话"})})]})}function iJ(){const e=ho(),t=g.useMemo(()=>new f0(e),[e]),n=sL(e),{sessions:r,refresh:i}=oL(n),{personas:s}=aE(),o=g.useMemo(()=>{const y=window.location.pathname.match(/^\/s\/([^/]+)/);return y?decodeURIComponent(y[1]):null},[]),a=g.useMemo(()=>r.filter(y=>!y.ephemeral),[r]),c=g.useMemo(()=>o?s.filter(y=>y.personaId===o):s,[s,o]),[l,u]=g.useState(null),[d,f]=g.useState(null),[p,m]=g.useState(null);g.useEffect(()=>{let y=!1;return e.request("whoami",{}).then(S=>{y||u(S.capability.id)}).catch(()=>{}),()=>{y=!0}},[e]),g.useEffect(()=>{o&&f(o)},[o]);const v=g.useCallback(async(y,S)=>{const k=await t.sessionCreate({ownerPersonaId:y,...S.trim()?{label:S.trim()}:{}});await i(),f(y),m(k.sessionId)},[t,i]),b=g.useCallback(async y=>{await t.sessionDelete(y),await i(),m(S=>S===y?null:S)},[t,i]),_=g.useCallback(async(y,S)=>{await t.sessionUpdate(y,{label:S.label,iconKey:S.iconKey===null?"":S.iconKey}),await i()},[t,i]),x=g.useMemo(()=>a.find(y=>y.sessionId===p)??null,[a,p]);return h.jsx(rJ,{personas:c,sessions:a,api:t,selfPrincipalId:l,selectedPersonaId:d,selectedSessionId:p,selectedSession:x,onSelectPersona:f,onSelectSession:m,onCreateSession:(y,S)=>void v(y,S),onDeleteSession:y=>void b(y),onEditSession:(y,S)=>void _(y,S),onCloseSession:()=>m(null),onConfigPatch:async()=>{}})}const kS="https://app.ttcadvisory.com";function sJ({onAuthed:e}){const[t,n]=g.useState(!1),[r,i]=g.useState(null),s=g.useRef(null);g.useEffect(()=>()=>{s.current&&window.removeEventListener("message",s.current)},[]);const o=g.useCallback(()=>{s.current&&(window.removeEventListener("message",s.current),s.current=null),n(!0),i(null);const a=window.location.origin,c=`${kS}/auth/authorize?callback_url=${encodeURIComponent(a)}&auto=1`,l=async d=>{if(d.origin!==kS)return;const f=d.data;if((f==null?void 0:f.type)==="AUTH_CANCEL"){u(),n(!1);return}if(!((f==null?void 0:f.type)!=="AUTH_SUCCESS"||!f.token)){u();try{const p=await fetch(`${window.location.origin}/share/exchange`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ttcToken:f.token})});if(!p.ok){const v=await p.json().catch(()=>({}));throw new Error(v.code??`exchange failed (${p.status})`)}const m=await p.json();if(!m.visitorToken)throw new Error("no visitorToken in response");e(m.visitorToken)}catch(p){i(p instanceof Error?p.message:String(p)),n(!1)}}},u=()=>{window.removeEventListener("message",l),s.current=null};s.current=d=>void l(d),window.addEventListener("message",s.current),window.open(c,"ttc-login","width=480,height=640")},[e]);return h.jsx("div",{className:"flex min-h-screen items-center justify-center bg-bg-50 p-6 font-sans text-text-100","data-testid":"guest-login",children:h.jsxs("div",{className:"flex w-full max-w-xs flex-col gap-3 rounded-lg border border-border bg-bg-100 px-5 py-6",children:[h.jsx("h1",{className:"text-base font-semibold",children:"登录后进入分享"}),h.jsx("p",{className:"text-[11px] leading-snug text-text-400",children:"使用飞书账号登录,即可在浏览器里与分享给你的 persona 交互,无需安装。"}),r?h.jsxs("p",{className:"text-[11px] leading-snug text-error","data-testid":"guest-login-error",children:["登录失败:",r]}):null,h.jsx("button",{type:"button",disabled:t,onClick:()=>o(),"data-testid":"guest-login-button",className:"w-full rounded border border-border bg-bg-50 px-2 py-1.5 text-xs text-text-200 transition-colors hover:bg-text-100/5 hover:text-text-100 disabled:opacity-50",children:t?"请在弹窗中完成授权…":"飞书登录"})]})})}const s_="clawd-visitor:token";function oJ(e,t){const r=`${e.protocol==="https:"?"wss:":"ws:"}//${e.host}`;return t!=null&&t.devPath?`${r}${t.devPath}`:r}function aJ(){return{async getUrl(e){const t=localStorage.getItem(s_);if(!t)throw new Error("NO_VISITOR_TOKEN");const n=oJ(window.location,{});return await J2(e).upsert({id:"guest",name:"访客",mode:"remote",url:n,token:t}),{url:n}}}}function lJ(e){const t=n=>{document.documentElement.classList.toggle("dark",n==="dark")};return t(e.theme.mode),e.onThemeChange(n=>t(n.mode))}function cJ(){const e=ho(),t=g.useMemo(()=>iL(e),[e]);return h.jsx($D,{cache:t.cache,children:h.jsx(HD,{children:h.jsx(iJ,{})})})}function uJ({host:e}){const[t]=g.useState(()=>localStorage.getItem(s_)),[n,r]=g.useState(!1),[i,s]=g.useState(null);return g.useEffect(()=>lJ(e),[e]),g.useEffect(()=>{if(!t)return;let o=!1;return aJ().getUrl(e).then(()=>{o||r(!0)}).catch(a=>{o||s(a instanceof Error?a.message:String(a))}),()=>{o=!0}},[e,t]),t?h.jsx(Oy,{host:e,children:h.jsx(g1,{children:i?h.jsxs("div",{className:"flex min-h-screen items-center justify-center bg-bg-50 p-6 text-center text-xs text-error","data-testid":"guest-share-connect-error",children:["连接失败:",i]}):n?h.jsx(OD,{host:e,children:h.jsx(cJ,{})}):h.jsx("div",{className:"flex min-h-screen items-center justify-center bg-bg-50 p-6 text-xs text-text-400",children:"正在连接…"})})}):h.jsx(Oy,{host:e,children:h.jsx(g1,{children:h.jsx(sJ,{onAuthed:o=>{localStorage.setItem(s_,o),window.location.reload()}})})})}function dJ({filePath:e,oldString:t,newString:n,content:r}){const i=g.useMemo(()=>r!=null?r.split(/\r?\n/).map(s=>({type:"add",text:s})):hJ(t??"",n??""),[t,n,r]);return h.jsxs("div",{"data-testid":"inline-diff",className:"min-w-0 max-w-full rounded-lg border border-bg-300/60 bg-bg-50 overflow-hidden text-[12px] font-mono",children:[h.jsx("div",{className:"flex min-w-0 items-center gap-2 px-3 py-1.5 border-b border-bg-300/40 bg-bg-100/30",children:h.jsx("span",{className:"min-w-0 text-text-400 truncate",title:e,children:e})}),h.jsx("div",{className:"max-h-[320px] max-w-full overflow-auto",children:i.map((s,o)=>h.jsxs("div",{"data-testid":`diff-line-${s.type}`,className:re("flex min-w-max gap-2 px-3 py-0.5 whitespace-pre",s.type==="add"?"bg-success/10 text-success":s.type==="remove"?"bg-error/10 text-error":"text-text-300"),children:[h.jsx("span",{className:"w-3 shrink-0 select-none opacity-60",children:s.type==="add"?"+":s.type==="remove"?"-":" "}),h.jsx("span",{className:"flex-1",children:s.text||" "})]},o))})]})}function hJ(e,t){const n=e.split(/\r?\n/),r=t.split(/\r?\n/),i=n.length,s=r.length,o=Array.from({length:i+1},()=>new Array(s+1).fill(0));for(let u=i-1;u>=0;u--)for(let d=s-1;d>=0;d--)o[u][d]=n[u]===r[d]?o[u+1][d+1]+1:Math.max(o[u+1][d],o[u][d+1]);const a=[];let c=0,l=0;for(;c<i&&l<s;)n[c]===r[l]?(a.push({type:"equal",text:n[c]}),c++,l++):o[c+1][l]>=o[c][l+1]?(a.push({type:"remove",text:n[c]}),c++):(a.push({type:"add",text:r[l]}),l++);for(;c<i;)a.push({type:"remove",text:n[c++]});for(;l<s;)a.push({type:"add",text:r[l++]});return a}function fJ({items:e}){return e.length===0?null:h.jsxs("div",{"data-testid":"todo-checklist",className:"rounded-lg border border-bg-300/60 bg-bg-50 px-3 py-2 text-[13px]",children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-1.5",children:"Todos"}),h.jsx("ul",{className:"flex flex-col gap-1",children:e.map((t,n)=>{const r=t.status==="in_progress"&&t.activeForm||t.content;return h.jsxs("li",{"data-testid":`todo-item-${t.status}`,className:"flex items-start gap-2",children:[h.jsx(pJ,{status:t.status}),h.jsx("span",{className:re("flex-1 leading-snug",t.status==="completed"?"text-text-400 line-through":t.status==="in_progress"?"text-text-100 font-medium":"text-text-200"),children:r})]},n)})})]})}function pJ({status:e}){return e==="completed"?h.jsx(af,{className:"w-3.5 h-3.5 text-success mt-0.5 shrink-0"}):e==="in_progress"?h.jsx(tr,{className:"w-3.5 h-3.5 text-warning mt-0.5 shrink-0 animate-spin"}):h.jsx(dE,{className:"w-3.5 h-3.5 text-text-400 mt-0.5 shrink-0"})}function mJ(e){const t=e??{};return Array.isArray(t.todos)?t.todos.map(n=>{if(!n||typeof n!="object")return null;const r=n,i=typeof r.content=="string"?r.content:"",s=r.status==="pending"||r.status==="in_progress"||r.status==="completed"?r.status:"pending",o=typeof r.activeForm=="string"?r.activeForm:void 0;return{content:i,status:s,activeForm:o}}).filter(n=>n!==null):[]}function gJ({description:e,prompt:t,subagentType:n}){return h.jsxs("div",{"data-testid":"task-checklist",className:"rounded-lg border border-bg-300/60 bg-bg-50 px-3 py-2 text-[13px]",children:[h.jsxs("div",{className:"flex items-center gap-2 text-text-200 font-medium",children:[h.jsx(p0,{className:"w-3.5 h-3.5 text-accent shrink-0"}),h.jsx("span",{className:"truncate",children:e||"subagent task"}),n?h.jsx("span",{className:"shrink-0 px-1.5 py-0.5 rounded-md text-[10px] font-mono bg-accent/10 text-accent",children:n}):null]}),t?h.jsx("div",{className:"mt-1 text-[12px] text-text-400 leading-snug line-clamp-3",children:t}):null]})}function vJ(e){const t=e??{};return{description:typeof t.description=="string"?t.description:"",prompt:typeof t.prompt=="string"?t.prompt:void 0,subagentType:typeof t.subagent_type=="string"?t.subagent_type:void 0}}const _J={render:({input:e})=>rt.createElement(fJ,{items:mJ(e)})},xJ={render:({input:e})=>{const{description:t,prompt:n,subagentType:r}=vJ(e);return rt.createElement(gJ,{description:t,prompt:n,subagentType:r})}},wM={render:({input:e,output:t,error:n,pending:r,fileScope:i,onShareFile:s,onOpenInTab:o,onPreviewMarkdown:a})=>{const c=bJ(e),l=c?rt.createElement(dJ,{filePath:c.filePath,oldString:c.oldString,newString:c.newString,content:c.content}):void 0;return rt.createElement(KP,{tool:yJ(e),input:e,output:t,error:n,pending:r,expandedBody:l,...i?{fileScope:i}:{},...s?{onShareFile:s}:{},...o?{onOpenInTab:o}:{},...a?{onPreviewMarkdown:a}:{}})}};function yJ(e){const t=e??{};return"content"in t&&t.content!==void 0?"Write":("old_string"in t&&t.old_string!==void 0,"Edit")}function bJ(e){const t=e??{},n=typeof t.file_path=="string"?t.file_path:null;if(!n)return null;const r=typeof t.old_string=="string"?t.old_string:void 0,i=typeof t.new_string=="string"?t.new_string:void 0,s=typeof t.content=="string"?t.content:void 0;return r==null&&i==null&&s==null?null:{filePath:n,oldString:r,newString:i,content:s}}Vc.register("claude","TodoWrite",_J);Vc.register("claude","Task",xJ);Vc.register("claude","Edit",wM);Vc.register("claude","Write",wM);const SM=document.getElementById("root");if(!SM)throw new Error("guest-main: #root not found");const wJ=QA({});fm.createRoot(SM).render(h.jsx(rt.StrictMode,{children:h.jsx(uJ,{host:wJ})}));
552
+ */var ZZ=2,QZ=1,JZ=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){var d;if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(e.css.cell.width===0||e.css.cell.height===0)return;let t=this._terminal.options.scrollback===0?0:((d=this._terminal.options.overviewRuler)==null?void 0:d.width)||14,n=window.getComputedStyle(this._terminal.element.parentElement),r=parseInt(n.getPropertyValue("height")),i=Math.max(0,parseInt(n.getPropertyValue("width"))),s=window.getComputedStyle(this._terminal.element),o={top:parseInt(s.getPropertyValue("padding-top")),bottom:parseInt(s.getPropertyValue("padding-bottom")),right:parseInt(s.getPropertyValue("padding-right")),left:parseInt(s.getPropertyValue("padding-left"))},a=o.top+o.bottom,c=o.right+o.left,l=r-a,u=i-c-t;return{cols:Math.max(ZZ,Math.floor(u/e.css.cell.width)),rows:Math.max(QZ,Math.floor(l/e.css.cell.height))}}};let lm;function cm(){return{count:0,byteSum:0,firstT:null,lastT:null}}const um=32,_S=320;function eQ({sessionId:e,client:t}){const n=g.useRef(null),r=g.useRef(null),i=g.useRef(null),s=g.useRef([]),o=g.useRef(cm()),a=g.useRef(!1),[c,l]=g.useState("collapsed"),[u,d]=g.useState(null);g.useEffect(()=>{const v=n.current;if(!v)return;let b=!1;const _=(P,N)=>getComputedStyle(document.documentElement).getPropertyValue(P).trim()||N,x=_("--bg-0","#1B1B1B"),y=_("--text-100","#ECECEC"),S=new YZ({fontFamily:"ui-monospace, SF Mono, Menlo, monospace",fontSize:12,lineHeight:1.2,theme:{background:x,foreground:y},minimumContrastRatio:4.5,cursorBlink:!0,convertEol:!1,scrollback:5e3,allowProposedApi:!0,cols:120,rows:40}),k=new JZ;S.loadAddon(k),De("xterm-mount",{sessionId:e,hostChildCount:v.childNodes.length}),lm!==e&&(De("xterm-trace",`===== SWITCH ${lm??"(initial)"} → ${e} =====`),lm=e),De("xterm-trace","effect-setup-start",{sessionId:e,t:performance.now()}),o.current=cm(),S.open(v);const w=S.onData(P=>{const N=btoa(unescape(encodeURIComponent(P)));t.request("session:pty:input",{sessionId:e,data:N}).catch(()=>{})});return(async()=>{var M;let P=0,N=null,L=null;try{De("xterm-trace","snapshot-rpc-start",{sessionId:e,t:performance.now()});const O=await t.request("session:pty:snapshot",{sessionId:e});if(De("xterm-trace","snapshot-rpc-resolved",{sessionId:e,cancelled:b,byteLen:((M=O==null?void 0:O.data)==null?void 0:M.length)??0,atSeq:O==null?void 0:O.atSeq,t:performance.now()}),b)return;if(O!=null&&O.ok&&typeof O.data=="string"&&O.data.length>0){const $=atob(O.data),z=new Uint8Array($.length);for(let F=0;F<$.length;F++)z[F]=$.charCodeAt(F);N=z}O!=null&&O.ok&&typeof O.atSeq=="number"&&(P=O.atSeq),O!=null&&O.ok&&O.popupKind!=null&&(L=O.popupKind)}catch{}if(b)return;r.current=S,i.current=k;let R=!1,A;const j=S.onRender(()=>{if(!R){R=!0;try{k.fit(),N&&S.write(N),De("xterm-trace","snapshot-flush",{sessionId:e,atSeq:P,pendingFrameCount:s.current.length,frameStatsBeforeFlush:{...o.current},t:performance.now()}),o.current=cm();const O=s.current;s.current=[];let $=0;for(const z of O){if(z.seq!==void 0&&z.seq<=P){$++;continue}S.write(z.bytes)}$>0&&De("xterm-trace","snapshot-flush-dropped",{sessionId:e,dropped:$,atSeq:P}),a.current=!0,L!=null&&(d(L),l("expanded"),requestAnimationFrame(()=>S.focus())),t.request("session:pty:resize",{sessionId:e,cols:S.cols,rows:S.rows}).catch(()=>{})}catch{}S.scrollToBottom(),A?A():setTimeout(()=>A==null?void 0:A(),0)}});A=()=>j.dispose()})(),()=>{De("xterm-trace","cleanup-start",{sessionId:e,pendingFrameCount:s.current.length,termReady:a.current,frameStatsThisMount:{...o.current},t:performance.now()}),b=!0,w.dispose(),S.dispose(),r.current=null,i.current=null,a.current=!1,s.current=[],De("xterm-trace","cleanup-cleared-pending",{sessionId:e,t:performance.now()})}},[e,t]),g.useEffect(()=>{const v=t.on("session:pty",_=>{const x=_;if(x.sessionId!==e||typeof x.data!="string")return;const y=o.current;y.count++,y.byteSum+=x.data.length;const S=performance.now();y.firstT===null&&(y.firstT=S),y.lastT=S;try{const k=atob(x.data),w=new Uint8Array(k.length);for(let P=0;P<k.length;P++)w[P]=k.charCodeAt(P);a.current&&r.current?r.current.write(w):s.current.push({seq:x.seq,bytes:w})}catch{}}),b=t.on("session:control",_=>{const x=_;if(x.sessionId===e)switch(x.kind){case"popup_open":(x.popupKind==="permission"||x.popupKind==="question")&&(d(x.popupKind),l("expanded"),requestAnimationFrame(()=>{var y;return(y=r.current)==null?void 0:y.focus()}));break;case"popup_close":d(null),l("collapsed");break}});return()=>{v(),b(),De("xterm-trace","cleanup-off-listener",{sessionId:e,t:performance.now()})}},[e,t]),g.useEffect(()=>{const v=n.current;if(!v)return;let b=0,_=0;const x=()=>{const S=i.current,k=r.current;if(!(!S||!k)){try{S.fit()}catch{return}try{k.refresh(0,k.rows-1)}catch{}k.cols===b&&k.rows===_||(b=k.cols,_=k.rows,t.request("session:pty:resize",{sessionId:e,cols:k.cols,rows:k.rows}).catch(()=>{}))}},y=new ResizeObserver(()=>x());return y.observe(v),()=>y.disconnect()},[e,t]);const f=()=>{l(v=>{const b=v==="collapsed"?"expanded":"collapsed";return b==="expanded"&&requestAnimationFrame(()=>{var _;return(_=r.current)==null?void 0:_.focus()}),b})},p=c==="expanded"?_S:um,m=_S-um;return h.jsxs("div",{className:"border-t border-border bg-bg-0 overflow-hidden",style:{height:p},"data-testid":"xterm-panel","data-state":c,"data-mode":"tui","data-popup-kind":u??"",children:[h.jsxs("button",{type:"button",onClick:f,className:"flex items-center justify-between w-full px-3 py-1 text-xs text-text-200 bg-bg-200 hover:bg-bg-300 cursor-pointer border-b border-border",style:{height:um,flexShrink:0},"data-testid":"xterm-panel-toggle",children:[h.jsxs("span",{className:"font-mono",children:[u==="permission"&&"⚠️ CC 需要权限确认 — 在下方终端按数字键 / Enter 选择",u==="question"&&"❓ CC 在问问题 — 在下方终端用 ↑/↓ + Enter 选择",u===null&&(c==="collapsed"?"▴ 展开原生 TUI 终端":"▾ 收起 TUI 终端")]}),h.jsx("span",{className:"text-text-200 text-[10px] opacity-60",children:c==="expanded"?"点击收起":"点击展开"})]}),h.jsx("div",{ref:n,className:"p-1",style:{height:m},"data-testid":"xterm-panel-host"})]})}function vM(e,t){const n=fo(),r=e?`session/${e}`:"",i=Si(r)??hc,s=g.useCallback(d=>{!e||!r||n.setData(r,f=>iE(f??hc,d,e))},[n,r,e]),o=g.useCallback(()=>{e&&s({type:"session:change",sessionId:e})},[s,e]),a=g.useCallback(d=>{e&&s({type:"permission:clear",sessionId:e,requestId:d})},[s,e]),c=g.useCallback(d=>{e&&s({type:"permission:request",sessionId:e,requestId:d.requestId,tool:d.tool,input:d.input,...d.toolUseId?{toolUseId:d.toolUseId}:{}})},[s,e]),l=g.useCallback(d=>{e&&s({type:"session:question:clear",sessionId:e,toolUseId:d})},[s,e]),u=g.useCallback((d,f)=>{e&&s({type:"session:question:submitted",sessionId:e,toolUseId:d,answers:f})},[s,e]);return{...i,reset:o,clearPermission:a,restorePermission:c,clearQuestion:l,markQuestionSubmitted:u}}function Sx(e){const t=Si(e?`capabilities/${e}`:"");return e?{capabilities:t??null,loading:!t}:{capabilities:null,loading:!1}}const tQ=50;function nQ({api:e,sessionId:t,toolSessionId:n,pageSize:r=tQ}){const[i,s]=g.useState({messages:[],total:0,loading:!1,hasMore:!1,error:null}),o=g.useRef(0),a=g.useRef(n),c=g.useRef(null),l=g.useRef(0);g.useEffect(()=>{const d=a.current;if(a.current=n,!(c.current!==t)&&!(typeof d=="string"&&d!==n))return;if(s({messages:[],total:0,loading:!1,hasMore:!1,error:null}),o.current=0,!t){c.current=null;return}c.current=t;const m=++l.current;s(v=>({...v,loading:!0,error:null})),(async()=>{try{const v=await e.historyRead({sessionId:t,limit:r});if(m!==l.current)return;o.current=v.offset,s({messages:v.messages??[],total:v.total??0,loading:!1,hasMore:v.offset>0,error:null})}catch(v){if(m!==l.current)return;s({messages:[],total:0,loading:!1,hasMore:!1,error:v.message??"history load failed"})}})()},[e,t,n,r]);const u=g.useCallback(async()=>{if(!t)return;const d=o.current;if(d<=0)return;const f=Math.max(0,d-r),p=d-f;s(m=>({...m,loading:!0,error:null}));try{const m=await e.historyRead({sessionId:t,limit:p,offset:f});o.current=m.offset,s(v=>({...v,messages:[...m.messages??[],...v.messages],loading:!1,hasMore:m.offset>0}))}catch(m){s(v=>({...v,loading:!1,error:m.message??"load more failed"}))}},[e,t,r]);return{...i,loadMore:u}}function xS(e){const t=Pf(e);return t.commandName?t.commandArgs?`${t.commandName} ${t.commandArgs}`:t.commandName:e}function yS(e){return e.kind==="user-text"||e.kind==="user-meta"&&e.metaKind==="slash-command"}function rQ(e,t){const n=t.find(yS);if(!n)return e;const r=xS(n.text);for(let i=e.length-1;i>=0;i--){const s=e[i];if(yS(s)&&xS(s.text)===r)return e.slice(0,i)}return e}function iQ(e){const t=e.lastEventKind===null||e.lastEventKind==="turn_end"||e.lastEventKind==="error";return e.procAlive&&!t}function sQ(e){return e==="running"||e==="observing"}const oQ=1e6;function aQ(e){if(!e)return;const t=e.contextUsage,n=e.contextWindowSize;if(!t||!n||n<=0)return;const r=t.inputTokens+(t.cacheReadTokens??0)+(t.cacheCreateTokens??0);if(!(r<=0))return Math.round(r/n*100)}function lQ(e){const t=ho(),n=g.useMemo(()=>new f0(t),[t]),r=Si("sessions"),i=g.useMemo(()=>r==null?void 0:r.find(T=>T.sessionId===e),[r,e]),s=i==null?void 0:i.toolSessionId,o=i==null?void 0:i.tool,a=vM(e),{events:c,pendingPermissions:l,status:u,clearPermission:d,restorePermission:f}=a,p=nQ({api:n,sessionId:e,toolSessionId:s}),m=g.useMemo(()=>p.messages.filter(T=>!T.isSidechain),[p.messages]),v=g.useMemo(()=>iR(m,0,o),[m,o]),b=l[0]??null,_=g.useMemo(()=>_G(c,(b==null?void 0:b.requestId)??null),[c,b==null?void 0:b.requestId]),x=g.useMemo(()=>rQ(v,_),[v,_]),y=g.useMemo(()=>_.map((T,D)=>({...T,seq:oQ+D})),[_]),S=g.useMemo(()=>[...x,...y],[x,y]),k=sQ(u),w=c.length>0?c[c.length-1].kind:null,P=iQ({procAlive:k,lastEventKind:w}),N=(i==null?void 0:i.resolvedModel)??(i==null?void 0:i.model),L=g.useMemo(()=>({sessionLabel:(i==null?void 0:i.label)??e,sessionId:e,...N?{model:N}:{},...(()=>{const T=i==null?void 0:i.gitBranch;return T?{gitBranch:T}:{}})(),...(()=>{const T=aQ(i);return T!==void 0?{contextPct:T}:{}})(),...i!=null&&i.cwd?{cwd:i.cwd}:{},...(()=>{const T=i==null?void 0:i.permissionMode;return T?{permissionMode:T}:{}})(),procAlive:k,streamInProgress:P,pinnedAt:(i==null?void 0:i.pinnedAt)??null}),[i,e,N,k,P]),R=g.useMemo(()=>t.isOpen?u==="error"?{kind:"error",message:"session error"}:{kind:"ready"}:{kind:"closed"},[t.isOpen,u]),A=g.useCallback(async T=>{await n.sessionSend(e,T)},[n,e]),j=g.useCallback(async T=>{if(!(i!=null&&i.cwd)||!s)throw new Error("fork requires sessionFile with cwd + toolSessionId");await n.sessionFork({cwd:i.cwd,toolSessionId:s,messageUuid:T})},[n,i==null?void 0:i.cwd,s]),M=g.useCallback(async T=>{await n.sessionRewind({sessionId:e,userMessageId:T,dryRun:!1})},[n,e]),O=g.useCallback(async T=>{await n.sessionUpdate(e,{model:T})},[n,e]),$=g.useCallback(async()=>{await n.sessionNew(e)},[n,e]),z=g.useCallback(async(T,D)=>{const C=l.find(U=>U.requestId===T);C&&d(T);try{await n.permissionRespond({sessionId:e,permissionRequestId:T,allow:D==="allow"})}catch(U){throw!((U==null?void 0:U.message)??"").startsWith("PERMISSION_REQUEST_STALE")&&C&&f(C),U}},[n,e,l,d,f]),F=g.useCallback(async()=>{await p.loadMore()},[p]);return g.useMemo(()=>({lines:S,connState:R,meta:L,historyDone:!p.hasMore,historyLoading:p.loading,pendingPermissions:l,sendText:A,fork:j,rewind:M,switchModel:O,clearSession:$,respondPermission:z,loadMoreHistory:F}),[S,R,L,p.hasMore,p.loading,l,A,j,M,O,$,z,F])}function cQ({api:e,open:t,onOpenChange:n,scope:r,sessionId:i,onShareFile:s,onOpenInTab:o}){const[a,c]=g.useState([]),[l,u]=g.useState(null);g.useEffect(()=>{if(!t)return;let f=!1;return(async()=>{try{const p=await e.attachmentGroupList(i);if(f)return;c(p.entries)}catch(p){f||u(p.message)}})(),()=>{f=!0}},[e,i,t]);async function d(f){try{await e.attachmentGroupRemove(i,f.relPath),c(p=>f.from==="owner"?p.filter(m=>m.relPath!==f.relPath):p.map(m=>m.relPath===f.relPath?{...m,stale:!0}:m))}catch(p){u(p.message)}}return t?h.jsx(MT,{delayDuration:120,children:h.jsxs("div",{"data-testid":"files-drawer",className:"fixed inset-y-0 right-0 z-50 flex w-[420px] flex-col border-l border-border bg-elevated shadow-2xl",children:[h.jsxs("div",{className:"flex items-center justify-between border-b border-border px-4 py-3",children:[h.jsxs("div",{className:"flex items-center gap-2 text-[13px] font-semibold text-text-100",children:[h.jsx(eO,{className:"h-4 w-4"}),"Edited Files"]}),h.jsx("button",{type:"button",onClick:()=>n(!1),className:"flex h-7 w-7 items-center justify-center rounded text-text-400 hover:bg-bg-200 hover:text-text-100","aria-label":"Close drawer",children:h.jsx(Hn,{className:"h-4 w-4"})})]}),h.jsxs("div",{className:"flex-1 overflow-y-auto",children:[h.jsx(uQ,{title:`Session files (${a.length})`,subtitle:"agent Write/Edit 自动入清单",children:a.length===0?h.jsx(hQ,{text:"还没有文件。agent Write/Edit 会自动加入清单。"}):a.map(f=>h.jsx(dQ,{entry:f,onShareLink:()=>s(f.relPath),...o?{onOpenInTab:()=>o(f.relPath)}:{},onRemove:()=>d(f)},f.id))}),l?h.jsx("div",{className:"border-t border-border bg-destructive/5 px-4 py-2 text-[11px] text-destructive",children:l}):null]})]})}):null}function uQ({title:e,subtitle:t,children:n}){return h.jsxs("div",{className:"border-b border-border last:border-b-0",children:[h.jsx("div",{className:"sticky top-0 z-10 flex items-start justify-between bg-elevated px-4 py-2",children:h.jsxs("div",{className:"flex-1",children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wide text-text-300",children:e}),t?h.jsx("div",{className:"mt-0.5 text-[11px] text-text-400",children:t}):null]})}),h.jsx("div",{className:"flex flex-col",children:n})]})}function dQ({entry:e,onShareLink:t,onOpenInTab:n,onRemove:r}){var c;const i=(c=e.mime)!=null&&c.startsWith("image/")?aO:po,s=e.relPath.lastIndexOf("/"),o=s>=0?e.relPath.slice(0,s+1):"",a=s>=0?e.relPath.slice(s+1):e.relPath;return h.jsxs("div",{"data-testid":"files-drawer-group-row",className:re("group flex items-center gap-2 px-4 py-2 hover:bg-bg-200",e.stale&&"opacity-50"),children:[h.jsx(i,{className:"h-4 w-4 shrink-0 text-text-400"}),h.jsxs("div",{className:"min-w-0 flex-1",children:[h.jsxs("div",{className:"flex items-center gap-1.5",children:[h.jsxs(IT,{children:[h.jsx(AT,{asChild:!0,children:h.jsxs("span",{className:"flex min-w-0 items-baseline text-[13px] text-text-100",children:[o?h.jsx("span",{className:"truncate text-text-400",children:o}):null,h.jsx("span",{className:"shrink-0",children:a})]})}),h.jsx(z0,{side:"top",align:"start",className:"max-w-[380px] break-all",children:e.relPath})]}),e.stale&&h.jsx("span",{className:"rounded bg-text-100/10 px-1 py-0 text-[10px] uppercase text-text-400",children:"stale"})]}),h.jsxs("div",{className:"flex items-center gap-1.5 truncate text-[11px] text-text-400",children:[h.jsx("span",{children:e.from}),h.jsx("span",{children:"·"}),h.jsx("span",{children:fQ(e.addedAt)})]})]}),!e.stale&&h.jsxs("div",{className:"flex items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100",children:[n?h.jsx(dm,{icon:h.jsx(fc,{className:"h-3.5 w-3.5"}),title:"Open in tab",onClick:n}):null,h.jsx(dm,{icon:h.jsx(m0,{className:"h-3.5 w-3.5"}),title:"Share link",onClick:t}),e.from==="owner"&&h.jsx(dm,{icon:h.jsx(g0,{className:"h-3.5 w-3.5"}),title:"Remove",onClick:r})]})]})}function dm({icon:e,title:t,onClick:n}){return h.jsx("button",{type:"button",onClick:n,title:t,"aria-label":t,className:"flex h-7 w-7 items-center justify-center rounded text-text-400 hover:bg-text-100/10 hover:text-text-100",children:e})}function hQ({text:e}){return h.jsx("div",{className:"px-4 py-3 text-[12px] italic text-text-400",children:e})}function fQ(e){const t=Date.now()-e;return t<6e4?`${Math.max(1,Math.floor(t/1e3))}s ago`:t<36e5?`${Math.floor(t/6e4)}m ago`:t<864e5?`${Math.floor(t/36e5)}h ago`:`${Math.floor(t/864e5)}d ago`}function pQ({persona:e,open:t,onClose:n,onTogglePublic:r,guestShareUrl:i,onChangeIcon:s,onDelete:o,embedded:a,onLoadPersonality:c,onSavePersonality:l,onDirtyChange:u,initialPersonality:d,onShareCapability:f,readOnly:p=!1,onChangeTool:m}){const[v,b]=g.useState(!1),[_,x]=g.useState(!1),y=()=>{i&&navigator.clipboard.writeText(i).then(()=>{x(!0),setTimeout(()=>x(!1),2e3)})},S=w=>{b(w),u==null||u(w)},k=()=>{v&&!window.confirm("修改未保存,确定关闭?")||n()};return t?h.jsxs(h.Fragment,{children:[!a&&h.jsx("div",{className:"absolute inset-0 z-30 bg-black/30",onClick:k,"aria-hidden":"true"}),h.jsxs("aside",{className:a?"flex h-full w-full flex-col bg-bg-0":"absolute right-0 top-0 z-40 flex h-full w-[420px] flex-col bg-bg-0 border-l border-border shadow-xl","data-testid":"persona-settings-drawer",children:[h.jsxs("header",{className:"flex items-center justify-between border-b border-border px-4 py-3 shrink-0",children:[h.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[h.jsx(DO,{className:"h-4 w-4 text-text-300"}),h.jsx("span",{className:"text-[13px] font-medium text-text-100 truncate",children:"Persona 设置"})]}),h.jsx("button",{type:"button",onClick:k,"aria-label":"关闭",className:"rounded-sm p-1.5 text-text-400 hover:bg-bg-200 hover:text-text-100",children:h.jsx(Hn,{className:"h-4 w-4"})})]}),h.jsxs("div",{className:"flex-1 overflow-y-auto p-6 flex flex-col gap-4",children:[h.jsxs("header",{className:"flex items-start justify-between gap-3",children:[h.jsxs("div",{className:"flex flex-col gap-0.5 min-w-0",children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("h2",{className:"text-lg font-semibold text-text-100 truncate",children:e.label}),e.public?h.jsxs("span",{className:"inline-flex items-center gap-1 rounded-sm bg-bg-200 px-1.5 py-0.5 text-[10px] text-text-200",children:[h.jsx(sO,{className:"h-3 w-3"})," 公开"]}):h.jsxs("span",{className:"inline-flex items-center gap-1 rounded-sm bg-error-dim px-1.5 py-0.5 text-[10px] text-error",children:[h.jsx(rO,{className:"h-3 w-3"})," 已关闭"]})]}),h.jsx("span",{className:"font-mono text-[11px] text-text-400 truncate","data-testid":"persona-id-subtitle",children:e.personaId})]}),h.jsxs("div",{className:"flex items-center gap-1",children:[f?h.jsxs("button",{type:"button",onClick:f,"aria-label":"分享给他人",title:"分享给他人",className:"inline-flex items-center gap-1 rounded-sm px-2 py-1.5 text-xs text-text-200 hover:bg-bg-200 hover:text-text-100",children:[h.jsx(m0,{className:"h-3.5 w-3.5"}),"分享"]}):null,o?h.jsx("button",{type:"button",onClick:o,"aria-label":"删除 persona",className:"rounded-sm p-1.5 text-text-400 hover:bg-bg-200 hover:text-error",children:h.jsx(g0,{className:"h-4 w-4"})}):null]})]}),h.jsx("hr",{className:"border-border"}),r?h.jsxs(h.Fragment,{children:[h.jsxs("section",{className:"flex items-center justify-between gap-3",children:[h.jsxs("div",{className:"flex flex-col gap-0.5",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"公开访问"}),h.jsx("span",{className:"text-[11px] text-text-400",children:"开启后这个 persona 才会出现在「邀请联系人」的可选列表里。关闭即拒所有新分享(已颁出的 token 不受影响)。"})]}),h.jsx(mQ,{checked:e.public??!1,onChange:w=>r(w)})]}),e.public?h.jsxs("section",{className:"flex flex-col gap-1.5","data-testid":"guest-share-link",children:[h.jsxs("div",{className:"flex items-center gap-1.5",children:[h.jsx(pE,{className:"h-3.5 w-3.5 text-text-400","aria-hidden":!0}),h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"访客分享链接"})]}),i?h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("input",{readOnly:!0,value:i,onFocus:w=>w.currentTarget.select(),className:"min-w-0 flex-1 truncate rounded border border-border bg-bg-100 px-2 py-1 text-[12px] text-text-200","data-testid":"guest-share-link-input"}),h.jsx("button",{type:"button",onClick:y,className:"flex shrink-0 items-center gap-1 rounded border border-border px-2 py-1 text-[12px] text-text-200 hover:bg-bg-200","data-testid":"guest-share-link-copy",children:_?h.jsxs(h.Fragment,{children:[h.jsx(Lc,{className:"h-3 w-3"})," 已复制"]}):h.jsxs(h.Fragment,{children:[h.jsx(lf,{className:"h-3 w-3"})," 复制"]})})]}),h.jsx("span",{className:"text-[11px] text-text-400",children:"任何 TTC 员工打开此链接(飞书登录)即可在该 persona 下交互。"})]}):h.jsx("span",{className:"text-[11px] text-text-400","data-testid":"guest-share-link-no-tunnel",children:"需先开启 tunnel(公网访问)才能生成可分享给外部的链接。"})]}):null,h.jsx("hr",{className:"border-border"})]}):null,s?h.jsxs("section",{className:"flex flex-col gap-1.5",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"默认图标"}),h.jsx("span",{className:"text-[11px] text-text-400",children:"新建该 persona 的 session 会默认继承此图标。"}),h.jsx(jT,{value:e.iconKey??null,onChange:s})]}):null,s?h.jsx("hr",{className:"border-border"}):null,m&&!p?h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:"flex flex-col gap-1.5",children:[h.jsx("span",{className:"text-[12px] font-medium text-text-200",children:"Agent"}),h.jsx("div",{className:"flex gap-2",children:["claude","codex"].map(w=>h.jsx("button",{type:"button","data-testid":`persona-edit-tool-${w}`,onClick:()=>m(w),className:re("flex-1 rounded-md border px-3 py-2 text-[12px]",(e.tool??"claude")===w?"border-accent bg-accent/10 text-accent":"border-bg-300 text-text-300"),children:w==="claude"?"Claude Code":"Codex"},w))}),h.jsx("span",{className:"text-[11px] text-text-400",children:"切换只影响之后新建的会话,已有会话保持原 tool。"})]}),h.jsx("hr",{className:"border-border"})]}):null,c?h.jsxs(h.Fragment,{children:[h.jsx(xQ,{onLoad:c,...l?{onSave:l}:{},onDirtyChange:S,initialPersonality:d,readOnly:p}),h.jsx("hr",{className:"border-border"})]}):null,h.jsx(gQ,{settings:e.sandboxSettings??null}),h.jsx("hr",{className:"border-border"}),h.jsx(vQ,{skills:e.skills??[]}),h.jsx("hr",{className:"border-border"}),h.jsx(_Q,{plugins:e.plugins??[]})]})]})]}):null}function mQ({checked:e,onChange:t}){return h.jsx("button",{type:"button",role:"switch","aria-checked":e,onClick:()=>t(!e),"data-testid":"persona-public-toggle",className:re("relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors",e?"bg-success":"bg-bg-300"),children:h.jsx("span",{className:re("inline-block h-5 w-5 rounded-full bg-bg-0 shadow transition-transform",e?"translate-x-[22px]":"translate-x-0.5")})})}function gQ({settings:e}){var t,n,r,i,s,o,a,c,l,u,d,f,p;return h.jsxs("section",{className:"flex flex-col gap-2","data-testid":"persona-sandbox-setting-section",children:[h.jsxs("header",{className:"flex flex-col gap-0.5",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"Sandbox Setting"}),h.jsx("span",{className:"text-[11px] text-text-400",children:"约束此 persona 的沙箱权限(只读,需通过文件修改)。"})]}),e==null?h.jsx("span",{className:"text-[12px] text-text-300","data-testid":"persona-sandbox-setting-empty",children:"暂无 sandbox 配置"}):h.jsxs("div",{className:"flex flex-col gap-1.5 rounded-md border border-border bg-bg-100 px-3 py-2",children:[h.jsx(Vu,{label:"权限默认模式",value:((t=e.permissions)==null?void 0:t.defaultMode)??"—"}),h.jsx(Vu,{label:"沙箱启用",value:hm((n=e.sandbox)==null?void 0:n.enabled)}),h.jsx(Vu,{label:"沙箱内自动放行 Bash",value:hm((r=e.sandbox)==null?void 0:r.autoAllowBashIfSandboxed)}),h.jsx(Vu,{label:"允许非沙箱命令",value:hm((i=e.sandbox)==null?void 0:i.allowUnsandboxedCommands)}),h.jsxs("div",{className:"mt-1 flex flex-col gap-1.5 border-t border-border pt-1.5",children:[h.jsx(hl,{label:"沙箱外命令",paths:(s=e.sandbox)==null?void 0:s.excludedCommands}),h.jsx(hl,{label:"允许读取",paths:(a=(o=e.sandbox)==null?void 0:o.filesystem)==null?void 0:a.allowRead}),h.jsx(hl,{label:"拒绝读取",paths:(l=(c=e.sandbox)==null?void 0:c.filesystem)==null?void 0:l.denyRead}),h.jsx(hl,{label:"允许写入",paths:(d=(u=e.sandbox)==null?void 0:u.filesystem)==null?void 0:d.allowWrite}),h.jsx(hl,{label:"拒绝写入",paths:(p=(f=e.sandbox)==null?void 0:f.filesystem)==null?void 0:p.denyWrite})]})]})]})}function hm(e){return e===!0?"是":e===!1?"否":"—"}function Vu({label:e,value:t}){return h.jsxs("div",{className:"flex items-center justify-between gap-3 text-[12px]",children:[h.jsx("span",{className:"text-text-300",children:e}),h.jsx("span",{className:"font-mono text-text-100",children:t})]})}function hl({label:e,paths:t}){const n=!t||t.length===0;return h.jsxs("div",{className:"flex flex-col gap-1",children:[h.jsx("span",{className:"text-[11px] text-text-300",children:e}),n?h.jsx("span",{className:"text-[11px] text-text-400",children:"—"}):h.jsx("div",{className:"flex flex-wrap gap-1",children:t.map((r,i)=>h.jsx("span",{className:"rounded-sm border border-border bg-bg-0 px-1.5 py-0.5 font-mono text-[11px] text-text-200",children:r},`${e}-${i}-${r}`))})]})}function vQ({skills:e}){return h.jsxs("section",{className:"flex flex-col gap-2","data-testid":"persona-skills-section",children:[h.jsxs("header",{className:"flex flex-col gap-0.5",children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"Persona Skills"}),h.jsx("span",{className:"rounded-sm border border-border px-1.5 py-0.5 text-[10px] text-text-300",children:e.length})]}),h.jsxs("span",{className:"text-[11px] text-text-400",children:["此 persona 私有 skills(来自"," ",h.jsx("code",{className:"font-mono",children:"<persona-dir>/.claude/skills/"}),")。"]})]}),e.length===0?h.jsx("span",{className:"text-[12px] text-text-300","data-testid":"persona-skills-empty",children:"暂无 skills"}):h.jsx("ul",{className:"flex flex-col divide-y divide-border rounded-md border border-border bg-bg-100",children:e.map(t=>h.jsxs("li",{className:"flex flex-col gap-0.5 px-3 py-2","data-testid":"persona-skill-row",children:[h.jsx("span",{className:"font-mono text-[13px] text-text-100",children:t.name}),t.description?h.jsx("span",{className:"text-[12px] text-text-300",children:t.description}):h.jsx("span",{className:"text-[11px] text-text-400 italic",children:"无描述"})]},t.name))})]})}function _Q({plugins:e}){return h.jsxs("section",{className:"flex flex-col gap-2","data-testid":"persona-plugins-section",children:[h.jsxs("header",{className:"flex flex-col gap-0.5",children:[h.jsxs("div",{className:"flex items-center gap-2",children:[h.jsx("span",{className:"text-[13px] font-medium text-text-100",children:"Enabled Plugins"}),h.jsx("span",{className:"rounded-sm border border-border px-1.5 py-0.5 text-[10px] text-text-300",children:e.length})]}),h.jsxs("span",{className:"text-[11px] text-text-400",children:["此 persona 已启用的插件(来自"," ",h.jsx("code",{className:"font-mono",children:"<persona-dir>/.claude/settings.json"})," ","的 ",h.jsx("code",{className:"font-mono",children:"enabledPlugins"}),")。"]})]}),e.length===0?h.jsx("span",{className:"text-[12px] text-text-300","data-testid":"persona-plugins-empty",children:"暂无启用插件"}):h.jsx("ul",{className:"flex flex-col divide-y divide-border rounded-md border border-border bg-bg-100",children:e.map(t=>h.jsx("li",{className:"flex flex-col gap-0.5 px-3 py-2","data-testid":"persona-plugin-row",children:h.jsx("span",{className:"font-mono text-[13px] text-text-100",children:t.id})},t.id))})]})}function xQ({onLoad:e,onSave:t,onDirtyChange:n,initialPersonality:r,readOnly:i=!1}){const s=r!==void 0,[o,a]=g.useState(s),[c,l]=g.useState(s?r:""),[u,d]=g.useState(s?r:""),[f,p]=g.useState(null),[m,v]=g.useState(!1),[b,_]=g.useState(null),x=rt.useRef(e),y=rt.useRef(t),S=rt.useRef(n);rt.useEffect(()=>{x.current=e,y.current=t,S.current=n});const k=rt.useCallback(()=>{a(!1),p(null),x.current().then(L=>{l(L),d(L),a(!0)}).catch(L=>{p(L instanceof Error?L.message:String(L))})},[]);rt.useEffect(()=>{s||k()},[s,k]);const w=!i&&o&&u!==c;rt.useEffect(()=>{i||S.current(w)},[w,i]);const P=()=>{y.current&&(v(!0),_(null),y.current(u).then(()=>{l(u),v(!1)}).catch(L=>{_(L instanceof Error?L.message:String(L)),v(!1)}))},N=()=>{d(c),_(null)};return h.jsxs("section",{className:"flex flex-col gap-2","data-testid":"persona-personality-section",children:[h.jsx("span",{className:"text-[12px] font-medium text-text-200",children:"人格 (Personality)"}),f?h.jsxs("div",{"data-testid":"persona-personality-load-error",className:"rounded-md border border-error bg-error-dim px-3 py-2 text-[12px] text-error flex items-center justify-between gap-2",children:[h.jsxs("span",{children:["加载失败:",f]}),h.jsx("button",{type:"button",onClick:k,className:"rounded-sm border border-error px-2 py-0.5 text-[11px] hover:bg-error/10",children:"重试"})]}):null,b?h.jsxs("div",{"data-testid":"persona-personality-save-error",className:"rounded-md border border-error bg-error-dim px-3 py-2 text-[12px] text-error",children:["保存失败:",b]}):null,h.jsx("textarea",{"data-testid":"persona-personality-textarea",value:u,onChange:L=>d(L.target.value),readOnly:i,disabled:!i&&(!o||m),placeholder:o?"":"加载中…",rows:8,className:"min-h-[8rem] max-h-[18rem] resize-y rounded-md border border-border bg-bg-100 px-2 py-1.5 font-mono text-[11px] text-text-100 disabled:opacity-60"}),!i&&h.jsxs("p",{className:"text-[10px] text-text-400",children:["写入到 ",h.jsx("code",{className:"font-mono",children:"<persona-dir>/CLAUDE.md"}),"。 修改只对新启动的 sub-session 生效。"]}),o&&w?h.jsxs("div",{className:"flex justify-end gap-2",children:[h.jsx("button",{type:"button",onClick:N,disabled:m,className:"rounded-sm border border-border px-2 py-1 text-[12px] text-text-200 hover:bg-bg-200 disabled:opacity-60",children:"放弃"}),h.jsx("button",{type:"button",onClick:P,disabled:m,"data-testid":"persona-personality-save-btn",className:"rounded-sm bg-accent-dim px-2 py-1 text-[12px] text-text-100 hover:opacity-90 disabled:opacity-60",children:m?"保存中…":"保存"})]}):null]})}function yQ({personaId:e,open:t,onClose:n,api:r,embedded:i,onDirtyChange:s,onShareCapability:o,viewerRole:a="owner"}){const{persona:c}=lE(e),l=aL(e),u=lL(),d=cL(),{httpBaseUrl:f}=of(),p=g.useMemo(()=>!(c!=null&&c.public)||!f||/^https?:\/\/(127\.0\.0\.1|localhost|0\.0\.0\.0|\[?::1\]?)([:/]|$)/i.test(f)?null:`${f}/s/${e}`,[c==null?void 0:c.public,f,e]),m=g.useCallback(k=>{u(e,{public:k}).catch(w=>{De("persona","togglePublic failed",w)})},[u,e]),v=g.useCallback(k=>{u(e,{iconKey:k}).catch(w=>{De("persona","changeIcon failed",w)})},[u,e]),b=g.useCallback(k=>{u(e,{tool:k}).catch(w=>{De("persona","changeTool failed",w)})},[u,e]),_=g.useCallback(()=>{c&&confirm(`删除 persona "${c.label}"?`)&&(d(e).catch(k=>{De("persona","delete failed",k)}),n())},[c,d,e,n]),x=g.useCallback(async()=>l.loaded?l.personality:(await l.refresh()).personality,[l]),y=g.useCallback(async k=>{await u(e,{personality:k}),await l.refresh()},[u,e,l]);if(!c)return null;const S=a==="guest";return h.jsx(pQ,{embedded:i,persona:{...c,skills:l.skills,plugins:l.plugins,sandboxSettings:l.sandboxSettings},open:t,onClose:n,onLoadPersonality:x,onDirtyChange:s,readOnly:S,...S?{}:{onTogglePublic:m,guestShareUrl:p,onChangeIcon:v,onChangeTool:b,onDelete:_,onSavePersonality:y,...o?{onShareCapability:o}:{}}})}function bQ({api:e,open:t,onOpenChange:n,personaId:r,personaName:i,viewerRole:s}){return t?h.jsxs("div",{"data-testid":"persona-drawer",className:"fixed inset-y-0 right-0 z-50 flex w-[420px] flex-col border-l border-border bg-elevated shadow-2xl",children:[h.jsxs("div",{className:"flex items-center justify-between border-b border-border px-4 py-3",children:[h.jsxs("div",{className:"flex min-w-0 items-center gap-2 text-[13px] font-semibold text-text-100",children:[h.jsx(v0,{className:"h-4 w-4 shrink-0"}),h.jsxs("span",{className:"truncate",title:i,children:["Persona · ",i]})]}),h.jsx("button",{type:"button",onClick:()=>n(!1),className:"flex h-7 w-7 items-center justify-center rounded text-text-400 hover:bg-bg-200 hover:text-text-100","aria-label":"Close drawer",children:h.jsx(Hn,{className:"h-4 w-4"})})]}),h.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto",children:h.jsx(yQ,{personaId:r,open:!0,onClose:()=>n(!1),api:e,embedded:!0,...s?{viewerRole:s}:{}},r)})]}):null}function wQ(e){try{const t=new URL(e);return t.protocol==="ws:"?t.protocol="http:":t.protocol==="wss:"&&(t.protocol="https:"),`${t.protocol}//${t.host}`}catch{return e}}function SQ(e,t){try{const n=new URL(e),r=new URL(t);return n.protocol=r.protocol,n.host=r.host,n.toString()}catch{return e}}async function _M(e,t,n,r,i){const s=await e.attachmentSignUrl({sessionId:n,relPath:r,...i!==void 0?{ttlSeconds:i}:{}});return SQ(s.url,wQ(t.url))}async function kQ(e,t,n,r,i=60){const s=window.open("about:blank","_blank");try{const o=await _M(e,t,n,r,i);s?s.location.href=o:window.open(o,"_blank")}catch(o){throw s&&s.close(),o}}async function CQ(e){var t;try{if((t=navigator.clipboard)!=null&&t.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{const n=document.createElement("textarea");n.value=e,n.style.position="fixed",n.style.left="-9999px",n.style.top="0",n.setAttribute("readonly",""),document.body.appendChild(n),n.select();const r=document.execCommand("copy");return document.body.removeChild(n),r}catch{return!1}}const EQ={...kc,h1:({node:e,...t})=>h.jsx("h1",{...t,className:"mt-4 mb-3 text-[18px] font-semibold leading-tight text-text-100"}),h2:({node:e,...t})=>h.jsx("h2",{...t,className:"mt-4 mb-2 text-[16px] font-semibold leading-tight text-text-100"}),h3:({node:e,...t})=>h.jsx("h3",{...t,className:"mt-3 mb-2 text-[14px] font-semibold leading-tight text-text-100"}),h4:({node:e,...t})=>h.jsx("h4",{...t,className:"mt-3 mb-1 text-[13px] font-semibold text-text-100"}),h5:({node:e,...t})=>h.jsx("h5",{...t,className:"mt-2 mb-1 text-[12px] font-semibold text-text-100"}),h6:({node:e,...t})=>h.jsx("h6",{...t,className:"mt-2 mb-1 text-[12px] font-semibold text-text-300"}),p:({node:e,...t})=>h.jsx("p",{...t,className:"my-2 leading-relaxed"}),ul:({node:e,...t})=>h.jsx("ul",{...t,className:"my-2 list-disc space-y-1 pl-5"}),ol:({node:e,...t})=>h.jsx("ol",{...t,className:"my-2 list-decimal space-y-1 pl-5"}),li:({node:e,...t})=>h.jsx("li",{...t,className:"leading-relaxed"}),blockquote:({node:e,...t})=>h.jsx("blockquote",{...t,className:"my-2 border-l-2 border-border pl-3 italic text-text-300"}),code:({node:e,className:t,children:n,...r})=>t?h.jsx("code",{...r,className:`${t} font-mono text-[12px]`,children:n}):h.jsx("code",{...r,className:"rounded bg-bg-50 px-1 py-0.5 font-mono text-[12px] text-text-100",children:n}),pre:({node:e,...t})=>h.jsx("pre",{...t,className:"my-2 overflow-auto rounded border border-border bg-bg-0 p-3 text-[12px] font-mono text-text-100"}),hr:({node:e,...t})=>h.jsx("hr",{...t,className:"my-3 border-border"}),table:({node:e,...t})=>h.jsx("table",{...t,className:"my-2 w-full border-collapse text-[12px]"}),thead:({node:e,...t})=>h.jsx("thead",{...t,className:"bg-bg-50"}),th:({node:e,...t})=>h.jsx("th",{...t,className:"border border-border px-2 py-1 text-left font-semibold"}),td:({node:e,...t})=>h.jsx("td",{...t,className:"border border-border px-2 py-1"}),strong:({node:e,...t})=>h.jsx("strong",{...t,className:"font-semibold text-text-100"}),em:({node:e,...t})=>h.jsx("em",{...t,className:"italic"})};function NQ(e){const t=e.split("/");return t[t.length-1]||e}function TQ({open:e,onOpenChange:t,relPath:n,loadMarkdown:r,onShare:i}){const[s,o]=g.useState(null),[a,c]=g.useState(null),[l,u]=g.useState(!1);return g.useEffect(()=>{if(!e||!n)return;let d=!1;return u(!0),c(null),o(null),(async()=>{try{const f=await r(n);if(d)return;o(f)}catch(f){if(d)return;c(f.message||String(f))}finally{d||u(!1)}})(),()=>{d=!0}},[e,n,r]),e?h.jsxs("div",{"data-testid":"md-preview-drawer",className:"fixed inset-y-0 right-0 z-50 flex w-1/2 max-w-[900px] flex-col border-l border-border bg-elevated shadow-2xl",children:[h.jsxs("div",{className:"flex items-center justify-between border-b border-border px-3 py-2",children:[h.jsx("div",{"data-testid":"md-preview-title",className:"truncate text-[13px] font-medium text-text-100",title:n??"",children:n?NQ(n):""}),h.jsxs("div",{className:"flex items-center gap-1",children:[i?h.jsx("button",{type:"button","data-testid":"md-preview-share","aria-label":"Share rendered preview link",onClick:i,className:"inline-flex h-6 w-6 items-center justify-center rounded text-text-400 hover:bg-bg-50 hover:text-text-200",children:h.jsx(pE,{className:"h-4 w-4"})}):null,h.jsx("button",{type:"button","aria-label":"Close preview",onClick:()=>t(!1),className:"inline-flex h-6 w-6 items-center justify-center rounded text-text-400 hover:bg-bg-50 hover:text-text-200",children:h.jsx(Hn,{className:"h-4 w-4"})})]})]}),h.jsx("div",{className:"flex-1 overflow-auto px-4 py-3 text-[13px] text-text-100",children:l?h.jsx("div",{"data-testid":"md-preview-loading",className:"text-text-400",children:"Loading…"}):a?h.jsx("div",{"data-testid":"md-preview-error",className:"text-destructive whitespace-pre-wrap",children:a}):s!==null?h.jsx("div",{"data-testid":"md-preview-content",className:"max-w-none",children:h.jsx(bc,{remarkPlugins:[Sc],components:EQ,children:s})}):null})]}):null}function PQ({left:e,right:t,stage:n,onExpand:r,onCollapse:i}){const s=n==="stopped",[o,a]=g.useState(!1);async function c(){if(!o){a(!0);try{await r()}catch{}finally{a(!1)}}}async function l(){if(!o){a(!0);try{await i()}catch{}finally{a(!1)}}}return h.jsxs("div",{className:"flex h-full w-full min-h-0","data-testid":"two-pane-layout",children:[h.jsxs("div",{className:"relative flex min-w-0 flex-1 flex-col","data-testid":"two-pane-left",children:[s&&h.jsx("button",{type:"button",disabled:o,className:"absolute right-14 top-2 z-10 rounded border border-border bg-elevated px-2 py-1 text-[12px] text-text-100 hover:bg-bg-200 disabled:opacity-50 disabled:cursor-not-allowed",onClick:c,children:o?"启动中…":"展开预览"}),e]}),!s&&h.jsxs("div",{className:"flex w-1/2 min-w-[320px] flex-col border-l border-bg-200","data-testid":"two-pane-right",children:[h.jsx("div",{className:"flex items-center justify-end gap-2 border-b border-bg-200 bg-bg-50 px-2 py-1",children:h.jsx("button",{type:"button",disabled:o,className:"rounded px-2 py-1 text-[12px] text-text-300 hover:bg-bg-100 disabled:opacity-50",onClick:l,children:"收起预览"})}),h.jsx("div",{className:"min-h-0 flex-1",children:t})]})]})}const xM=yR,RQ=bR,yM=g.forwardRef(({className:e,...t},n)=>h.jsx(cx,{ref:n,className:re("fixed inset-0 z-50 bg-black/50 backdrop-blur-sm",e),...t}));yM.displayName=cx.displayName;const kx=g.forwardRef(({className:e,children:t,...n},r)=>h.jsxs(RQ,{children:[h.jsx(yM,{}),h.jsxs(ux,{ref:r,className:re("fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2","gap-4 rounded-lg border border-border bg-elevated p-6 shadow-lg",e),...n,children:[t,h.jsxs(wR,{className:"absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-accent",children:[h.jsx(Hn,{className:"h-4 w-4"}),h.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));kx.displayName=ux.displayName;const Cx=({className:e,...t})=>h.jsx("div",{className:re("flex flex-col space-y-1.5 text-left",e),...t});Cx.displayName="DialogHeader";const Ex=({className:e,...t})=>h.jsx("div",{className:re("flex flex-row justify-end gap-2",e),...t});Ex.displayName="DialogFooter";const Nx=g.forwardRef(({className:e,...t},n)=>h.jsx(dx,{ref:n,className:re("text-lg font-semibold leading-none text-text-100",e),...t}));Nx.displayName=dx.displayName;const bM=g.forwardRef(({className:e,...t},n)=>h.jsx(hx,{ref:n,className:re("text-sm text-text-300",e),...t}));bM.displayName=hx.displayName;const MQ=6173,IQ=6182;function AQ({open:e,onOpenChange:t,projectName:n,currentPort:r,allUsedPorts:i,onUpdate:s}){const o=[];for(let v=MQ;v<=IQ;v++)(v===r||!i.includes(v))&&o.push(v);const[a,c]=g.useState(r),[l,u]=g.useState(!1),[d,f]=g.useState(null),p=a!==r&&!l;async function m(){if(p){u(!0),f(null);try{await s(a),t(!1)}catch(v){f((v==null?void 0:v.message)??String(v))}finally{u(!1)}}}return h.jsx(xM,{open:e,onOpenChange:t,children:h.jsxs(kx,{className:"max-w-md",children:[h.jsxs(Cx,{children:[h.jsxs(Nx,{children:["改端口 · ",n]}),h.jsxs(bM,{children:["手改通常发生在系统其他进程占了默认分配的端口、dev server 起不来时。 提交后 daemon 会停 dev server → 写 ",h.jsx("code",{className:"mx-1 rounded bg-bg-100 px-1 py-0.5 text-[11px]",children:".clawd-project.json"})," → 用新端口重新起。"]})]}),h.jsxs("div",{className:"flex flex-col gap-2",children:[h.jsx("label",{className:"text-xs text-text-400",children:"新端口(仅显示段内可用 + 当前端口)"}),h.jsx("select",{className:"h-9 rounded-md border border-border bg-elevated px-3 py-1 text-sm text-text-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent",value:a,onChange:v=>c(Number(v.target.value)),disabled:l,children:o.map(v=>h.jsxs("option",{value:v,children:[v,v===r?"(当前)":""]},v))}),o.length===1&&h.jsx("div",{className:"text-[11px] text-text-400",children:"端口段已全被其它 project 占用,没有可换的;先删一个 idle project 释放端口。"}),d&&h.jsx("div",{className:"rounded border border-destructive/30 bg-destructive/5 px-3 py-2 text-[12px] text-destructive",children:d})]}),h.jsxs(Ex,{children:[h.jsx(Jr,{variant:"ghost",onClick:()=>t(!1),disabled:l,children:"取消"}),h.jsx(Jr,{onClick:m,disabled:!p,children:l?"应用中…":"应用新端口"})]})]})})}const bS=[{stage:"build",label:"构建"},{stage:"deploy",label:"部署到阿里云"},{stage:"verify",label:"验证可访问性"}];function jQ({currentStage:e,onCancel:t}){const n=bS.findIndex(r=>r.stage===e);return h.jsxs("div",{"data-testid":"publish-progress",className:"flex items-center gap-3 border-b border-bg-200 bg-bg-50 px-3 py-1.5 text-[12px]",children:[bS.map((r,i)=>{const s=i<n,o=i===n,a=s?"text-text-300":o?"text-text-200":"text-text-500/50";return h.jsxs("span",{className:`flex items-center gap-1 ${a}`,children:[s?h.jsx(af,{className:"size-3.5"}):o?h.jsx(tr,{className:"size-3.5 animate-spin"}):h.jsx(dE,{className:"size-3.5"}),h.jsxs("span",{children:[r.label,o?"中…":""]})]},r.stage)}),h.jsx("button",{type:"button",onClick:t,className:"ml-auto rounded px-2 py-0.5 text-[11px] text-text-400 hover:bg-bg-100 hover:text-text-200",children:"取消"})]})}const DQ={build:"构建",deploy:"部署",verify:"验证"};function LQ({stage:e,onRetry:t,onDismiss:n}){return h.jsxs("div",{"data-testid":"publish-interrupted-banner",className:"flex items-center gap-2 border-b border-yellow-400/40 bg-yellow-400/10 px-3 py-1.5 text-[12px]",children:[h.jsx(pc,{className:"size-3.5 text-yellow-500"}),h.jsxs("span",{className:"text-text-200",children:["上次发布在 ",h.jsxs("strong",{className:"font-medium",children:["[",DQ[e],"]"]})," ","阶段被中断(daemon 重启)"]}),h.jsx("button",{type:"button",onClick:t,className:"ml-auto rounded bg-accent-main-100 px-2 py-0.5 text-[11px] text-oncolor-100 hover:opacity-90",children:"重新发布"}),h.jsx("button",{type:"button",onClick:n,className:"rounded px-2 py-0.5 text-[11px] text-text-400 hover:bg-bg-100 hover:text-text-200",children:"取消"})]})}const OQ={build:"构建",deploy:"部署",verify:"验证",unknown:"未知"};function BQ({stage:e,onFocusChat:t,onClose:n}){return h.jsxs("div",{"data-testid":"publish-failed-banner",className:"flex items-center gap-2 border-b border-destructive/40 bg-destructive/10 px-3 py-1.5 text-[12px]",children:[h.jsx(Ss,{className:"size-3.5 text-destructive"}),h.jsxs("button",{type:"button",onClick:t,className:"flex-1 text-left text-text-200 hover:underline",children:["发布失败:",h.jsxs("strong",{className:"font-medium",children:["[",OQ[e],"]"]})," ","已通知 assistant 接管 →"]}),h.jsx("button",{type:"button",onClick:n,"aria-label":"关闭失败提示",className:"rounded p-0.5 text-text-400 hover:bg-bg-100 hover:text-text-200",children:h.jsx(Hn,{className:"size-3.5"})})]})}const wS={"install-pending":{label:"等装依赖…",step:"1/3"},installing:{label:"安装依赖中…(可能要几十秒到几分钟)",step:"2/3"},"starting-dev-server":{label:"启动 dev server…(等监听端口才挂 iframe)",step:"3/3"}};function $Q({project:e,previewHost:t,previewScheme:n,onUpdatePort:r,allUsedPorts:i,publishSlot:s,publishInFlightStage:o,onDismissPublishJob:a,onRetryPublish:c,publishFailureBanner:l,onPublishFailureBannerClose:u,onPublishFailureBannerFocusChat:d}){var _,x;const[f,p]=g.useState(!1);if(!e)return h.jsx("div",{className:"flex h-full w-full items-center justify-center p-6 text-center text-[13px] text-text-400",children:"未绑定 project"});const m=e.stage??(e.isRunning?"running":"stopped"),v=t?`${n}://${t}/preview/${e.port}/`:null,b=e.prodUrl??null;return h.jsxs("div",{className:"flex h-full w-full flex-col","data-testid":"preview-pane",children:[h.jsxs("header",{className:"flex items-center justify-between gap-2 border-b border-bg-200 bg-bg-50 px-3 py-1.5",children:[h.jsxs("div",{className:"flex items-center gap-2 text-[12px]",children:[h.jsx("span",{className:"font-medium text-text-200",children:e.name}),h.jsx("span",{className:"rounded bg-bg-100 px-1.5 py-0.5 text-[11px] text-text-400",children:e.port}),h.jsx("span",{className:"text-[10px] uppercase tracking-wider text-text-500",children:m==="running"?"dev":m})]}),h.jsxs("div",{className:"flex items-center gap-2",children:[b?h.jsxs("a",{href:b,target:"_blank",rel:"noopener noreferrer",title:`打开线上:${b}`,className:"inline-flex items-center gap-1 rounded border border-bg-200 px-2 py-0.5 text-[11px] text-text-300 hover:bg-bg-100",children:[h.jsx(fc,{className:"size-3"}),"打开线上"]}):null,s,h.jsxs(xT,{children:[h.jsx(yT,{asChild:!0,children:h.jsx("button",{type:"button","aria-label":"Project settings",className:"rounded p-1 text-text-400 hover:bg-bg-100",children:h.jsx(AO,{className:"size-3.5"})})}),h.jsxs(B0,{align:"end",children:[h.jsx(Fs,{onSelect:()=>p(!0),children:"Update Port…"}),h.jsxs(Fs,{disabled:!0,title:"rename not supported yet",onSelect:y=>y.preventDefault(),children:["Name: ",e.name]})]})]})]})]}),l?h.jsx(BQ,{stage:l.stage,onClose:()=>u==null?void 0:u(),onFocusChat:()=>d==null?void 0:d()}):null,((_=e.publishJob)==null?void 0:_.status)==="in-flight"?h.jsx(jQ,{currentStage:o??e.publishJob.stage,onCancel:()=>void(a==null?void 0:a())}):null,((x=e.publishJob)==null?void 0:x.status)==="interrupted"?h.jsx(LQ,{stage:e.publishJob.stage,onRetry:()=>void(c==null?void 0:c()),onDismiss:()=>void(a==null?void 0:a())}):null,h.jsx("div",{className:"min-h-0 flex-1",children:m==="failed"?h.jsx(zQ,{reason:e.stageReason}):m==="stopped"?null:m==="running"?v?h.jsx("iframe",{"data-testid":"preview-iframe",className:"size-full border-0 bg-white",src:v,title:"preview"}):h.jsx(SS,{label:"等 tunnel 起来…",step:"-"}):h.jsx(SS,{label:wS[m].label,step:wS[m].step})}),h.jsx(AQ,{open:f,onOpenChange:p,projectName:e.name,currentPort:e.port,allUsedPorts:i,onUpdate:async y=>{await r(y)}})]})}function SS({label:e,step:t}){return h.jsxs("div",{"data-testid":"preview-spinner",className:"flex h-full w-full flex-col items-center justify-center gap-3 p-6 text-center",children:[h.jsx(tr,{className:"size-6 animate-spin text-accent-main-100"}),h.jsx("div",{className:"text-[13px] text-text-200",children:e}),h.jsx("div",{className:"text-[11px] uppercase tracking-wider text-text-500",children:t}),h.jsx("div",{className:"mt-2 max-w-[300px] text-[11px] text-text-500",children:"左侧 chat 可看 assistant 详细进度"})]})}function zQ({reason:e}){return h.jsxs("div",{"data-testid":"preview-failed",className:"flex h-full w-full flex-col items-center justify-center gap-3 p-6 text-center",children:[h.jsx(Ss,{className:"size-6 text-destructive"}),h.jsx("div",{className:"text-[13px] text-text-200",children:"project 启动失败"}),h.jsx("div",{className:"max-w-[400px] text-[12px] text-text-400",children:e??"未知原因 —— 看 ~/.clawd/clawd.log 排查"}),h.jsx("div",{className:"mt-1 max-w-[300px] text-[11px] text-text-500",children:"左侧 chat 可看 assistant 详细进度 / 跟它说怎么修"})]})}function FQ({error:e,onClose:t}){const[n,r]=g.useState(!1),i=async()=>{var a;if(!e)return;const s=e.message;let o=!1;try{(a=navigator.clipboard)!=null&&a.writeText&&(await navigator.clipboard.writeText(s),o=!0)}catch{o=!1}if(!o){const c=document.createElement("textarea");c.value=s,c.style.position="fixed",c.style.opacity="0",document.body.appendChild(c),c.select();try{document.execCommand("copy"),o=!0}catch{o=!1}finally{document.body.removeChild(c)}}o&&(r(!0),setTimeout(()=>r(!1),1500))};return h.jsx(xM,{open:!!e,onOpenChange:s=>{s||(r(!1),t())},children:h.jsxs(kx,{className:"max-w-lg",children:[h.jsx(Cx,{children:h.jsx(Nx,{children:(e==null?void 0:e.title)??"错误"})}),h.jsx("pre",{"data-testid":"rpc-error-message",className:"max-h-72 overflow-auto whitespace-pre-wrap break-words rounded border border-bg-200 bg-bg-50 px-3 py-2 text-[12px] text-text-200",children:(e==null?void 0:e.message)??""}),h.jsxs(Ex,{children:[h.jsx(Jr,{variant:"ghost",onClick:i,className:"gap-1.5",children:n?h.jsxs(h.Fragment,{children:[h.jsx(Lc,{className:"size-3.5"}),"已复制"]}):h.jsxs(h.Fragment,{children:[h.jsx(lf,{className:"size-3.5"}),"复制"]})}),h.jsx(Jr,{onClick:t,children:"关闭"})]})]})})}function HQ(e,t){for(const n of[e,t])if(n)try{const r=new URL(n),i=r.protocol==="https:"||r.protocol==="wss:"?"https":"http";return{host:r.host,scheme:i}}catch{}return{host:null,scheme:"https"}}function UQ({extras:e}){const t=lQ(e.session.sessionId),n=h.jsx(qQ,{state:t,extras:e});return e.session.appBuilderProject?h.jsx(WQ,{state:t,chat:n,extras:e}):n}function WQ({state:e,chat:t,extras:n}){var N;const r=Si("daemon-info"),i=ho(),s=n.api,o=n.session,a=o.appBuilderProject,[c,l]=g.useState(null),u=g.useCallback(()=>{s.appBuilderGetProject(o.sessionId).then(L=>l(L.project)).catch(()=>l(null))},[s,o.sessionId]);g.useEffect(()=>{u()},[u]);const[d,f]=g.useState([]),p=g.useCallback(()=>{s.appBuilderListProjects().then(L=>f(L.projects)).catch(()=>f([]))},[s]);g.useEffect(()=>{p()},[p]),g.useEffect(()=>i.on("appBuilder:project-updated",R=>{const A=R;A!=null&&A.project&&(A.project.name===a&&l(A.project),f(j=>{const M=j.findIndex($=>$.name===A.project.name);if(M<0)return[...j,A.project];const O=j.slice();return O[M]=A.project,O}))}),[i,a]);const{host:m,scheme:v}=HQ(i.url,r==null?void 0:r.tunnelUrl),[b,_]=g.useState(void 0),[x,y]=g.useState(null);g.useEffect(()=>{const L=i.on("appBuilder:publish-progress",A=>{const j=A;!j||j.name!==a||j.status==="started"&&_(j.stage)}),R=i.on("appBuilder:publish-failed",A=>{const j=A;!j||j.name!==a||(_(void 0),y({stage:j.stage}))});return()=>{L(),R()}},[i,a]),g.useEffect(()=>{_(void 0),y(null)},[a]);const[S,k]=g.useState(null),w=h.jsx("button",{type:"button",className:"rounded bg-accent-main-100 px-2.5 py-1 text-[12px] text-oncolor-100 hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",disabled:((N=c==null?void 0:c.publishJob)==null?void 0:N.status)==="in-flight",onClick:async()=>{try{await s.appBuilderPublish(a)}catch(L){k({title:"发布请求失败",message:(L==null?void 0:L.message)??String(L)})}},children:"发布上线"}),P=(c==null?void 0:c.stage)??(c!=null&&c.isRunning?"running":"stopped");return h.jsxs(h.Fragment,{children:[h.jsx(PQ,{left:t,stage:P,onExpand:async()=>{await s.appBuilderStartDevServer(o.sessionId)},onCollapse:async()=>{await s.appBuilderStopDevServer(o.sessionId)},right:h.jsx($Q,{project:c,previewHost:m,previewScheme:v,allUsedPorts:d.map(L=>L.port),onUpdatePort:async L=>{await s.appBuilderUpdateProjectPort(a,L),p()},publishSlot:w,publishInFlightStage:b,onDismissPublishJob:async()=>{try{await s.appBuilderDismissPublishJob(a)}catch(L){k({title:"取消发布失败",message:(L==null?void 0:L.message)??String(L)})}},onRetryPublish:async()=>{try{await s.appBuilderPublish(a)}catch(L){k({title:"重新发布失败",message:(L==null?void 0:L.message)??String(L)})}},publishFailureBanner:x,onPublishFailureBannerClose:()=>y(null),onPublishFailureBannerFocusChat:()=>{}})}),h.jsx(FQ,{error:S,onClose:()=>k(null)})]})}function VQ({headerMeta:e,connState:t,models:n,liveGitBranch:r,liveWorktreeRoot:i,onOpenConfig:s,onForceStop:o,cronActiveCount:a,onCronClick:c,lines:l,pendingPermissions:u,procAlive:d,rewindableUserMessageIds:f,onPermissionRespond:p,onPermissionInterrupt:m,onRewind:v,onFork:b,onQuickAsk:_,topSlot:x,realtimeQuestionAnswers:y,onSubmitQuestion:S,onCancelQuestion:k,liveQuestionToolUseIds:w,api:P,cwd:N,tool:L,sessionKey:R,onSend:A,awaitingUser:j,onAbort:M,onNewSession:O,onClearSession:$,chatRootRef:z,chatBodyRef:F,topSentinelRef:T,drawers:D,xtermSlot:C,fileSharingScope:U,onShareFile:V,onOpenInTab:I,onPreviewMarkdown:ae,onOpenFiles:te,onTogglePin:Z,personaName:ye,onOpenPersona:Fe}){return h.jsx(bK,{children:h.jsxs("div",{ref:z,"data-cc-chat-root":"",className:"flex flex-col h-full bg-bg-0",children:[h.jsx(pG,{meta:e,...L?{tool:L}:{},connState:t,...n?{models:n}:{},...r!==void 0?{liveGitBranch:r}:{},...i!==void 0?{liveWorktreeRoot:i}:{},...s?{onOpenConfig:s}:{},...o?{onForceStop:o}:{},cronActiveCount:a,...c?{onCronClick:c}:{},...te?{onOpenFiles:te}:{},...Z?{onTogglePin:Z}:{},...ye?{personaName:ye}:{},...Fe?{onOpenPersona:Fe}:{}}),h.jsxs("div",{ref:F,"data-testid":"chat-body",className:"flex-1 overflow-y-auto min-h-0",style:{overflowAnchor:"none"},children:[T?h.jsx("div",{ref:T,"data-testid":"top-sentinel","aria-hidden":"true",style:{height:1}}):null,h.jsx(JP,{lines:l,...p?{onPermissionRespond:p}:{},...m&&d?{onPermissionInterrupt:m}:{},topSlot:x,...v?{onRewind:v}:{},rewindableUserMessageIds:f,...b?{onFork:b}:{},..._?{onQuickAsk:_}:{},realtimeQuestionAnswers:y,onSubmitQuestion:S,...k?{onCancelQuestion:k}:{},liveQuestionToolUseIds:w,...U?{fileSharingScope:U}:{},...V?{onShareFile:V}:{},...I?{onOpenInTab:I}:{},...ae?{onPreviewMarkdown:ae}:{}})]}),C,h.jsx(hG,{meta:e,...P?{api:P}:{},cwd:N,...L?{tool:L}:{},sessionKey:R,onSend:A,awaitingUser:j,...M?{onAbort:M}:{},...O?{onNewSession:O}:{},...$?{onClearSession:$}:{}}),D]})})}function qQ({state:e,extras:t}){const{session:n,api:r,models:i,liveGitBranch:s,liveWorktreeRoot:o,onNewSession:a,onTurnEnd:c,onOpenConfig:l,onFork:u,onQuickAsk:d,viewerRole:f}=t,{capabilities:p}=Sx(n.tool||"claude"),m=(p==null?void 0:p.features)??{rewind:!0,subagents:!0,tui:!0,fileSharing:!0,fork:!0},[v,b]=g.useState(null),[_,x]=g.useState(!1),[y,S]=g.useState(!1),k=of(),w=!!r&&k.actionsLevel==="owner"&&m.fileSharing,P=lE(n.ownerPersonaId??null).persona,N=(P==null?void 0:P.label)??null,L=!!N&&!!n.ownerPersonaId,R=g.useCallback(()=>{S(!1),x(!0)},[]),A=g.useCallback(()=>{x(!1),S(!0)},[]),j=g.useCallback((q,oe)=>{b({kind:q,text:oe}),setTimeout(()=>{b(pe=>(pe==null?void 0:pe.text)===oe?null:pe)},2e3)},[]),M=ho(),O=BD(),$=vM(n.sessionId,n.toolSessionId),{events:z,pendingQuestions:F,clearQuestion:T,markQuestionSubmitted:D,status:C}=$,U=e.historyLoading,V=C==="running"||C==="observing";g.useEffect(()=>{De("chat-panel","sessionStatus",{sessionId:n.sessionId,sessionStatus:C,procAlive:V})},[C,V,n.sessionId]);const I=e.lines,ae=e.pendingPermissions,te=ae[0]??null,Z=g.useMemo(()=>I8(z),[z]),[ye,Fe]=g.useState(!1),[ue,Me]=g.useState(null),[Be,We]=g.useState(()=>new Set);P8(r,n.sessionId,n.toolSessionId);const ve=g.useRef(n.sessionId);g.useEffect(()=>{ve.current=n.sessionId;let q=!1;return Me(null),(async()=>{try{const oe=await r.sessionRewindableMessageIds(n.sessionId);if(q)return;Me(new Set(oe.userMessageIds))}catch{q||Me(null)}})(),()=>{q=!0}},[r,n.sessionId]);const Ge=g.useCallback(()=>{const q=n.sessionId;r.sessionRewindableMessageIds(q).then(oe=>{ve.current===q&&Me(new Set(oe.userMessageIds))}).catch(()=>{})},[r,n.sessionId]),fn=g.useMemo(()=>{if(ue!==null){const Ie=new Set(ue);for(const An of Be)Ie.delete(An);return Ie}const q=new Set(["Edit","Write","MultiEdit","NotebookEdit"]),oe=new Set;let pe=null;for(const Ie of I)Ie.kind==="user-text"?pe=Ie.uuid??null:pe&&Ie.kind==="tool-call"&&q.has(Ie.tool)&&!Be.has(pe)&&oe.add(pe);return oe},[I,Be,ue]),[Pt,mt]=g.useState({}),Xt=g.useRef({}),wt=g.useRef(c);wt.current=c,g.useEffect(()=>{var An;const q=n.sessionId;if(z.length===0){Xt.current[q]=-1;return}const oe=Xt.current[q]??-1;let pe=0,Ie=oe;for(const It of z){if(It.kind!=="turn_end"&&It.kind!=="error")continue;const Es=It.seq??-1;Es<=oe||(pe++,Es>Ie&&(Ie=Es))}pe!==0&&(Xt.current[q]=Ie,mt(It=>{const Es=It[q]??0,qa=Math.max(0,Es-pe);if(Es===qa)return It;if(qa===0){const{[q]:SJ,...kM}=It;return kM}return{...It,[q]:qa}}),(An=wt.current)==null||An.call(wt),Ge())},[z,n.sessionId,Ge]),R8(n.sessionId,n.toolSessionId,()=>{be(null),We(new Set),mt(q=>{if(!q[n.sessionId])return q;const{[n.sessionId]:oe,...pe}=q;return pe})}),Pt[n.sessionId];const lt=z.length>0?z[z.length-1]:null,Ye=lt!==null&&(lt.kind==="turn_end"||lt.kind==="error"),ct=FG({sessionStatus:C,daemonStreaming:V&&!Ye}),Yt=g.useRef(null);g.useEffect(()=>{const q=Yt.current;q!==ct&&(Yt.current=ct,De("session-phase",ct,{sid:n.sessionId,phase:ct,prev:q,desc:zG[ct]}))},[ct,n.sessionId]);const on=g.useCallback(()=>{const q=n.sessionId;mt(oe=>{if(!oe[q])return oe;const{[q]:pe,...Ie}=oe;return Ie})},[n.sessionId]),H=g.useCallback(async q=>{const oe=n.sessionId;mt(pe=>({...pe,[oe]:(pe[oe]??0)+1}));try{await e.sendText(q)}catch(pe){throw mt(Ie=>{const An=Ie[oe]??0;if(An<=0)return Ie;const It=An-1;if(It===0){const{[oe]:Es,...qa}=Ie;return qa}return{...Ie,[oe]:It}}),pe}},[e,n.sessionId]),X=g.useCallback(()=>{on(),r.sessionInterrupt(n.sessionId).catch(()=>{})},[r,n.sessionId,on]),[_e,be]=g.useState(null),Q=g.useCallback(q=>{be(q)},[]),[Ze,Rt]=g.useState(!1),bn=g.useCallback(()=>{on(),r.sessionStop(n.sessionId).catch(()=>{}),Rt(!1)},[r,n.sessionId,on]),de=g.useCallback(q=>{r.pinSession(n.sessionId,q).catch(oe=>{De("chat-panel","pinSession failed",{err:oe==null?void 0:oe.message})})},[r,n.sessionId]),Te=g.useRef(0),Qe=g.useRef(null);g.useEffect(()=>{const q=oe=>{if(oe.key!=="Escape")return;if(!V){Te.current=0;return}if(oe.isComposing)return;const Ie=oe.target;if(Ie&&Ie.closest("[data-cc-chat-root]")!==Qe.current)return;const An=Date.now();An-Te.current<2e3?(Te.current=0,Rt(!0)):(Te.current=An,X())};return window.addEventListener("keydown",q),()=>window.removeEventListener("keydown",q)},[X,V]);const an=g.useRef(null),In=g.useRef(null),za=g.useRef(!0),Oi=g.useRef(null),Fa=g.useRef(0),bo=g.useRef(0);g.useEffect(()=>{za.current=!0,Oi.current=null,Fa.current=0,bo.current=0},[n.sessionId]),g.useEffect(()=>{Fe(!1)},[n.sessionId]);const Yc=g.useRef(e);Yc.current=e;const Zc=g.useCallback(()=>{var pe;const q=an.current;if(!q||Oi.current!==null)return;const oe=Yc.current;oe.historyDone||oe.historyLoading||(Oi.current={distFromBottom:q.scrollHeight-q.scrollTop},(pe=oe.loadMoreHistory)==null||pe.call(oe))},[]);g.useEffect(()=>{const q=an.current,oe=In.current;if(!q||!oe)return;const pe=new IntersectionObserver(Ie=>{for(const An of Ie)An.isIntersecting&&Zc()},{root:q,threshold:0});return pe.observe(oe),()=>pe.disconnect()},[Zc]),g.useEffect(()=>{const q=an.current;if(!q)return;const oe=150,pe=Ie=>{Date.now()<bo.current&&(Ie.preventDefault(),bo.current=Date.now()+oe)};return q.addEventListener("wheel",pe,{passive:!1}),()=>q.removeEventListener("wheel",pe)},[]),g.useEffect(()=>{const q=an.current;if(!q)return;const oe=32,pe=()=>{const Ie=q.scrollHeight-q.scrollTop-q.clientHeight;za.current=Ie<=oe};return q.addEventListener("scroll",pe,{passive:!0}),()=>q.removeEventListener("scroll",pe)},[]),g.useLayoutEffect(()=>{const q=an.current;if(!q)return;const oe=Fa.current,pe=I.length;Fa.current=pe;const Ie=Oi.current;if(Ie!==null&&pe>oe){Oi.current=null,q.scrollTop=q.scrollHeight-Ie.distFromBottom,bo.current=Date.now()+200;return}Ie!==null&&(Oi.current={distFromBottom:q.scrollHeight-q.scrollTop}),za.current&&(q.scrollTop=q.scrollHeight)},[I,te==null?void 0:te.requestId]);const Qc=g.useMemo(()=>{const q={};for(const[oe,pe]of Object.entries(F))pe.submittedAnswers&&(q[oe]=pe.submittedAnswers);return q},[F]),wo=g.useMemo(()=>new Set(Object.keys(F)),[F]),So=g.useCallback(async(q,oe)=>{try{await r.answerQuestion({sessionId:n.sessionId,toolUseId:q,answers:oe}),D(q,oe)}catch{}},[r,n.sessionId,D]),Ha=g.useCallback(async q=>{try{await r.cancelQuestion({sessionId:n.sessionId,toolUseId:q}),T(q)}catch{}},[r,n.sessionId,T]),Ua=g.useCallback(async(q,oe)=>{var pe;if(te)try{await((pe=e.respondPermission)==null?void 0:pe.call(e,te.requestId,q?"allow":"deny"))}catch{}},[e,te]),Bi=g.useCallback(async()=>{const q=n.sessionId;try{await r.sessionStop(q)}catch{}e.clearSession?await e.clearSession():await r.sessionNew(q)},[e,r,n.sessionId]),$i=g.useMemo(()=>U&&I.length===0?h.jsx("div",{className:"flex justify-center py-4","data-testid":"history-loading",children:h.jsx(tr,{className:"w-4 h-4 text-text-400 animate-spin"})}):e.historyDone?null:h.jsx("div",{className:"flex justify-center py-2",children:h.jsx("button",{type:"button",onClick:()=>{var q;return void((q=e.loadMoreHistory)==null?void 0:q.call(e))},disabled:U,"data-testid":"history-load-more",className:"text-[12px] text-text-400 hover:text-text-200 cursor-pointer px-3 py-1 rounded-md border border-bg-300 hover:bg-bg-100 transition-colors disabled:opacity-60",children:U?"加载中…":"Load earlier messages"})}),[U,I.length,e.historyDone,e.loadMoreHistory]),Jc=e.meta,Df=h.jsxs(h.Fragment,{children:[n.toolSessionId&&m.subagents?h.jsx(yG,{api:r,cwd:n.cwd,toolSessionId:n.toolSessionId}):null,_e&&m.rewind?h.jsx(wG,{open:!0,onOpenChange:q=>{q||be(null)},api:r,sessionId:n.sessionId,userMessageId:_e,lines:I,procAlive:V,onNoChanges:q=>{We(oe=>{if(oe.has(q))return oe;const pe=new Set(oe);return pe.add(q),pe})}}):null,Ze?h.jsx(KQ,{onConfirm:bn,onCancel:()=>Rt(!1)}):null,h.jsx($G,{open:ye,onClose:()=>Fe(!1),jobs:Z})]}),Dt={kind:"session",sessionId:n.sessionId},Wa=g.useCallback(async q=>{if(r)try{await kQ(r,M,n.sessionId,q)}catch(oe){const pe=oe.message;De("chat-panel","open-in-tab failed",{err:pe}),j("err",`Open in tab 失败:${pe}`)}},[r,M,n.sessionId,j]),[Lf,St]=g.useState(!1),[Mt,ir]=g.useState(null),sr=g.useCallback(q=>{ir(q),St(!0)},[]),ko=g.useCallback(async q=>{if(!r)throw new Error("daemon api not ready");const oe=await _M(r,M,n.sessionId,q,60),pe=await fetch(oe);if(!pe.ok)throw new Error(`fetch ${pe.status} ${pe.statusText}`);return await pe.text()},[r,M,n.sessionId]),Va=g.useCallback(async(q,oe)=>{if(r)try{const{url:pe}=await r.attachmentSignUrl({sessionId:n.sessionId,relPath:q,ttlSeconds:86400,...oe?{view:oe}:{}}),Ie=await CQ(pe);j(Ie?"ok":"err",Ie?"分享链接已复制到剪贴板(24h 有效)":"复制失败:请手动复制")}catch(pe){const Ie=pe.message;De("chat-panel","share-file failed",{err:Ie}),j("err",`生成分享链接失败:${Ie}`)}},[r,n.sessionId,j]);return h.jsxs(h.Fragment,{children:[h.jsx(VQ,{headerMeta:Jc,connState:e.connState,...i?{models:i}:{},...s!==void 0?{liveGitBranch:s}:{},...o!==void 0?{liveWorktreeRoot:o}:{},...l?{onOpenConfig:l}:{},onForceStop:()=>Rt(!0),cronActiveCount:Z.length,onCronClick:()=>Fe(!0),lines:I,pendingPermissions:ae,procAlive:V,rewindableUserMessageIds:fn,onPermissionRespond:Ua,onPermissionInterrupt:X,onRewind:m.rewind?Q:void 0,...u&&m.fork?{onFork:u}:{},...d&&m.fork?{onQuickAsk:d}:{},topSlot:$i,realtimeQuestionAnswers:Qc,onSubmitQuestion:So,onCancelQuestion:Ha,liveQuestionToolUseIds:wo,api:r,cwd:n.cwd,...n.tool?{tool:n.tool}:{},sessionKey:n.sessionId,onSend:H,awaitingUser:ae.length>0||Object.values(F).some(q=>!q.submittedAnswers),onAbort:X,...a?{onNewSession:a}:{},onClearSession:Bi,chatRootRef:Qe,chatBodyRef:an,topSentinelRef:In,drawers:Df,xtermSlot:O==="tui"&&V&&m.tui?h.jsx(eQ,{sessionId:n.sessionId,client:M},n.sessionId):null,fileSharingScope:Dt,...r?{onShareFile:Va}:{},...r?{onOpenInTab:Wa}:{},...r?{onPreviewMarkdown:sr}:{},...w?{onOpenFiles:R}:{},onTogglePin:de,...L?{personaName:N}:{},...L?{onOpenPersona:A}:{}}),w&&r?h.jsx(cQ,{api:r,open:_,onOpenChange:x,scope:Dt,sessionId:n.sessionId,onShareFile:Va,onOpenInTab:Wa}):null,r?h.jsx(TQ,{open:Lf,onOpenChange:St,relPath:Mt,loadMarkdown:ko,onShare:Mt?()=>void Va(Mt,"md-rendered"):void 0}):null,L&&r&&n.ownerPersonaId?h.jsx(bQ,{api:r,open:y,onOpenChange:S,personaId:n.ownerPersonaId,personaName:N??"",...f?{viewerRole:f}:{}}):null,v?h.jsx("div",{"data-testid":"share-toast",role:"status","aria-live":"polite",className:v.kind==="ok"?"fixed left-1/2 top-4 z-50 -translate-x-1/2 rounded-md border border-emerald-500/40 bg-emerald-500/10 px-3 py-2 text-[12px] text-emerald-700 shadow-md dark:text-emerald-300":"fixed left-1/2 top-4 z-50 -translate-x-1/2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-[12px] text-destructive shadow-md",children:v.text}):null]})}function KQ({onConfirm:e,onCancel:t}){return h.jsx("div",{role:"dialog","aria-modal":"true","data-testid":"force-stop-confirm",className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40",onClick:t,children:h.jsxs("div",{className:"max-w-sm w-[92%] rounded-lg border border-red-400/40 bg-bg-0 p-4 shadow-xl",onClick:n=>n.stopPropagation(),children:[h.jsxs("div",{className:"flex items-start gap-2 mb-3",children:[h.jsx(pc,{className:"w-5 h-5 text-red-500 shrink-0 mt-0.5"}),h.jsx("div",{className:"text-[14px] text-text-100",children:"强制停止会话进程?会丢失 initialize / 预热缓存,下一次发送需要重新 spawn。"})]}),h.jsxs("div",{className:"flex justify-end gap-2",children:[h.jsx("button",{type:"button",onClick:t,className:"h-8 px-3 rounded-md text-[12px] text-text-300 hover:bg-text-100/5 cursor-pointer",children:"取消"}),h.jsx("button",{type:"button","data-testid":"force-stop-confirm-ok",onClick:e,className:"h-8 px-3 rounded-md bg-red-500 text-white text-[12px] font-medium hover:bg-red-600 cursor-pointer",children:"强制停止"})]})]})})}function GQ({current:e,models:t,onSelect:n}){return h.jsxs("div",{children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-2",children:"Model"}),h.jsx("div",{className:"flex flex-wrap gap-1.5","data-testid":"config-model-selector",children:t.map(r=>{const i=(e||"")===r.id;return h.jsx("button",{type:"button",onClick:()=>n(r.id),"data-testid":`config-model-${r.id||"default"}`,className:re("px-3 py-1.5 rounded-lg text-[12px] font-medium transition-colors cursor-pointer",i?"bg-accent text-white shadow-sm":"bg-bg-100 text-text-300 hover:bg-bg-200 hover:text-text-100"),children:r.label},r.id||"default")})})]})}function XQ({current:e,modes:t,onSelect:n}){var i;const r=(i=t.find(s=>s.id===(e||"")))==null?void 0:i.description;return h.jsxs("div",{children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-2",children:"Permission Mode"}),h.jsx("div",{className:"flex flex-wrap gap-1.5","data-testid":"config-mode-selector",children:t.map(s=>{const o=(e||"")===s.id;return h.jsx("button",{type:"button",onClick:()=>n(s.id),"data-testid":`config-mode-${s.id||"default"}`,className:re("px-3 py-1.5 rounded-lg text-[12px] font-medium transition-colors cursor-pointer",o?"bg-accent text-white shadow-sm":"bg-bg-100 text-text-300 hover:bg-bg-200 hover:text-text-100"),children:s.label},s.id||"default")})}),r?h.jsx("p",{className:"text-[11px] text-text-400 mt-1.5",children:r}):null]})}function YQ({open:e,onOpenChange:t,session:n,onPatch:r,embedded:i=!1,viewerRole:s="owner"}){var p;const{capabilities:o}=Sx(e?n.tool||"claude":null),a=(o==null?void 0:o.models)??[],c=(o==null?void 0:o.permissionModes)??[],l=((p=o==null?void 0:o.configSchema.find(m=>m.name==="permissionMode"))==null?void 0:p.default)??"",u=n.permissionMode&&c.some(m=>m.id===n.permissionMode)?n.permissionMode:l,d=g.useMemo(()=>(o==null?void 0:o.configSchema.filter(m=>m.scope==="tool-specific"))??[],[o]);if(!e)return null;const f=h.jsxs("div",{className:"flex-1 min-h-0 flex flex-col px-4 py-4 gap-6 overflow-y-auto",children:[h.jsxs("div",{className:"shrink-0",children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-1",children:"Working Directory"}),h.jsx("div",{className:"text-[12px] font-mono text-text-300 bg-bg-100 rounded-lg px-3 py-2 truncate","data-testid":"config-cwd",title:n.cwd,children:n.cwd})]}),h.jsx("div",{className:"shrink-0",children:h.jsx(GQ,{current:n.model??"",models:a,onSelect:m=>void r({model:m})})}),h.jsx("div",{className:"shrink-0",children:h.jsx(XQ,{current:u,modes:c,onSelect:m=>void r({permissionMode:m})})}),d.length>0?h.jsx("div",{className:"shrink-0",children:h.jsx(ZQ,{fields:d,session:n,onPatch:r})}):null]});return i?h.jsxs("div",{"data-testid":"config-drawer",className:"h-full w-full flex flex-col",children:[h.jsx("div",{className:"flex items-center px-4 py-3 border-b border-bg-300/30 shrink-0",children:h.jsx("span",{className:"text-[14px] font-semibold text-text-100",children:"Session Settings"})}),f]}):h.jsxs("div",{"data-testid":"config-drawer",className:"h-full flex flex-col border-l border-bg-300/40 bg-bg-0 shrink-0",style:{width:360,minWidth:360},children:[h.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-bg-300/30 shrink-0",children:[h.jsx("span",{className:"text-[14px] font-semibold text-text-100",children:"Session Settings"}),h.jsx("button",{type:"button",onClick:()=>t(!1),"data-testid":"config-drawer-close",className:"flex items-center justify-center w-7 h-7 rounded-md text-text-400 hover:text-text-100 hover:bg-text-100/5 transition-colors cursor-pointer","aria-label":"Close",children:h.jsx(Hn,{className:"w-4 h-4"})})]}),f]})}function ZQ({fields:e,session:t,onPatch:n}){return h.jsxs("div",{"data-testid":"config-advanced",children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-2",children:"Advanced"}),h.jsx("div",{className:"space-y-3",children:e.map(r=>h.jsx(QQ,{field:r,session:t,onPatch:n},r.name))})]})}function QQ({field:e,session:t,onPatch:n}){if(e.type!=="select"||!e.options)return null;const r=t[e.name]??"",i=e.options.some(s=>s.value===r)?r:e.default??"";return h.jsxs("div",{"data-testid":`config-advanced-${e.name}`,children:[h.jsx("div",{className:"text-[11px] text-text-400 mb-1.5",children:e.label}),h.jsx("div",{className:"flex flex-wrap gap-1.5",children:e.options.map(s=>{const o=i===s.value;return h.jsx("button",{type:"button","data-testid":`config-advanced-${e.name}-${s.value||"default"}`,onClick:()=>void n({[e.name]:s.value}),className:re("px-3 py-1.5 rounded-lg text-[12px] font-medium transition-colors cursor-pointer",o?"bg-accent text-white shadow-sm":"bg-bg-100 text-text-300 hover:bg-bg-200 hover:text-text-100"),children:s.label},s.value||"default")})})]})}function JQ(e,t,n=0){const[r,i]=g.useState(null),[s,o]=g.useState(!1),a=g.useCallback(async()=>{if(!t){i(null);return}o(!0);try{const c=await e.getGitBranch(t);i(c.branch??null)}catch{i(null)}finally{o(!1)}},[e,t]);return g.useEffect(()=>{a()},[a,n]),{branch:r,loading:s,refresh:()=>void a()}}function eJ(e,t,n=0){const[r,i]=g.useState(null),[s,o]=g.useState(!1),a=g.useCallback(async()=>{if(!t){i(null);return}o(!0);try{const c=await e.getGitRoot(t);i(c.gitRoot??null)}catch{i(null)}finally{o(!1)}},[e,t]);return g.useEffect(()=>{a()},[a,n]),{worktreeRoot:r,loading:s,refresh:()=>void a()}}function tJ({api:e,session:t,focused:n,totalPanes:r,onFocus:i,onClose:s,onNewSession:o,onOpenConfig:a,onConfigPatch:c,onFork:l,onQuickAsk:u,className:d,viewerRole:f="owner"}){const{capabilities:p}=Sx(t.tool),[m,v]=g.useState(0),[b,_]=g.useState(!1),{branch:x}=JQ(e,t.cwd,m),{worktreeRoot:y}=eJ(e,t.cwd,m),S=r>1,k=w=>{w==="desktop"?_(!0):a()};return h.jsxs("div",{className:`group/pane relative flex-1 ${d??"flex"} flex-row min-w-0 min-h-0 overflow-hidden ${S?`rounded-md border transition-colors ${n?"border-accent ring-1 ring-accent":"border-border"}`:""}`,onMouseDown:i,"data-testid":`session-pane-${t.sessionId}`,children:[h.jsx("div",{className:"flex-1 flex flex-col min-w-0 min-h-0",children:h.jsx(nJ,{api:e,session:t,models:p==null?void 0:p.models,liveGitBranch:x,liveWorktreeRoot:y,onNewSession:o,onTurnEnd:()=>v(w=>w+1),onOpenConfig:k,onFork:l,onQuickAsk:u,viewerRole:f})}),b?h.jsx("div",{className:"hidden md:flex h-full",children:h.jsx(YQ,{open:b,onOpenChange:_,session:t,onPatch:c,viewerRole:f})}):null,S&&h.jsx("button",{type:"button",onClick:w=>{w.stopPropagation(),s()},className:"absolute top-1.5 right-1.5 z-10 p-1 rounded-md bg-bg-100/80 backdrop-blur-sm border border-border opacity-0 group-hover/pane:opacity-100 transition-opacity text-text-400 hover:text-text-100 hover:bg-bg-200","aria-label":"close pane","data-testid":`session-pane-close-${t.sessionId}`,children:h.jsx(Hn,{className:"w-3.5 h-3.5"})})]})}function nJ({api:e,session:t,models:n,liveGitBranch:r,liveWorktreeRoot:i,onNewSession:s,onTurnEnd:o,onOpenConfig:a,onFork:c,onQuickAsk:l,viewerRole:u}){return h.jsx(UQ,{extras:{session:t,api:e,...n?{models:n}:{},...r!==void 0?{liveGitBranch:r}:{},...i!==void 0?{liveWorktreeRoot:i}:{},onNewSession:s,onTurnEnd:o,onOpenConfig:a,...c?{onFork:d=>{c(d)}}:{},...l?{onQuickAsk:d=>{l(d)}}:{},...u?{viewerRole:u}:{}}})}function rJ({personas:e,sessions:t,api:n,selfPrincipalId:r,selectedPersonaId:i,selectedSessionId:s,selectedSession:o,onSelectPersona:a,onSelectSession:c,onCreateSession:l,onDeleteSession:u,onEditSession:d,onCloseSession:f,onConfigPatch:p}){return h.jsxs("div",{className:"flex h-screen min-h-0 bg-bg-50","data-testid":"guest-share-page",children:[h.jsx("aside",{className:"w-[280px] shrink-0 overflow-y-auto border-r border-border bg-bg-50",children:h.jsx(E8,{personas:e,sessions:t,activePersonaId:i,activeSessionId:s,onSelectPersona:a,onSelectSession:c,onCreateSession:l,onDeleteSession:u,onEditSession:d,showCopyResume:!1,treatSessionsAsRoots:!0,...r?{ownerPrincipalId:r}:{},isPersonaExpanded:()=>!0})}),h.jsx("main",{className:"flex-1 min-w-0 min-h-0 flex",children:o?h.jsx(tJ,{api:n,session:o,focused:!0,totalPanes:1,onFocus:()=>{},onClose:f,onNewSession:()=>{},onOpenConfig:()=>{},onConfigPatch:p,viewerRole:"guest"}):h.jsx("div",{className:"flex flex-1 items-center justify-center p-6 text-xs text-text-400","data-testid":"guest-share-empty",children:"选择左侧 persona 开始对话"})})]})}function iJ(){const e=ho(),t=g.useMemo(()=>new f0(e),[e]),n=sL(e),{sessions:r,refresh:i}=oL(n),{personas:s}=aE(),o=g.useMemo(()=>{const y=window.location.pathname.match(/^\/s\/([^/]+)/);return y?decodeURIComponent(y[1]):null},[]),a=g.useMemo(()=>r.filter(y=>!y.ephemeral),[r]),c=g.useMemo(()=>o?s.filter(y=>y.personaId===o):s,[s,o]),[l,u]=g.useState(null),[d,f]=g.useState(null),[p,m]=g.useState(null);g.useEffect(()=>{let y=!1;return e.request("whoami",{}).then(S=>{y||u(S.capability.id)}).catch(()=>{}),()=>{y=!0}},[e]),g.useEffect(()=>{o&&f(o)},[o]);const v=g.useCallback(async(y,S)=>{const k=await t.sessionCreate({ownerPersonaId:y,...S.trim()?{label:S.trim()}:{}});await i(),f(y),m(k.sessionId)},[t,i]),b=g.useCallback(async y=>{await t.sessionDelete(y),await i(),m(S=>S===y?null:S)},[t,i]),_=g.useCallback(async(y,S)=>{await t.sessionUpdate(y,{label:S.label,iconKey:S.iconKey===null?"":S.iconKey}),await i()},[t,i]),x=g.useMemo(()=>a.find(y=>y.sessionId===p)??null,[a,p]);return h.jsx(rJ,{personas:c,sessions:a,api:t,selfPrincipalId:l,selectedPersonaId:d,selectedSessionId:p,selectedSession:x,onSelectPersona:f,onSelectSession:m,onCreateSession:(y,S)=>void v(y,S),onDeleteSession:y=>void b(y),onEditSession:(y,S)=>void _(y,S),onCloseSession:()=>m(null),onConfigPatch:async()=>{}})}const kS="https://app.ttcadvisory.com";function sJ({onAuthed:e}){const[t,n]=g.useState(!1),[r,i]=g.useState(null),s=g.useRef(null);g.useEffect(()=>()=>{s.current&&window.removeEventListener("message",s.current)},[]);const o=g.useCallback(()=>{s.current&&(window.removeEventListener("message",s.current),s.current=null),n(!0),i(null);const a=window.location.origin,c=`${kS}/auth/authorize?callback_url=${encodeURIComponent(a)}&auto=1`,l=async d=>{if(d.origin!==kS)return;const f=d.data;if((f==null?void 0:f.type)==="AUTH_CANCEL"){u(),n(!1);return}if(!((f==null?void 0:f.type)!=="AUTH_SUCCESS"||!f.token)){u();try{const p=await fetch(`${window.location.origin}/share/exchange`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ttcToken:f.token})});if(!p.ok){const v=await p.json().catch(()=>({}));throw new Error(v.code??`exchange failed (${p.status})`)}const m=await p.json();if(!m.visitorToken)throw new Error("no visitorToken in response");e(m.visitorToken)}catch(p){i(p instanceof Error?p.message:String(p)),n(!1)}}},u=()=>{window.removeEventListener("message",l),s.current=null};s.current=d=>void l(d),window.addEventListener("message",s.current),window.open(c,"ttc-login","width=480,height=640")},[e]);return h.jsx("div",{className:"flex min-h-screen items-center justify-center bg-bg-50 p-6 font-sans text-text-100","data-testid":"guest-login",children:h.jsxs("div",{className:"flex w-full max-w-xs flex-col gap-3 rounded-lg border border-border bg-bg-100 px-5 py-6",children:[h.jsx("h1",{className:"text-base font-semibold",children:"登录后进入分享"}),h.jsx("p",{className:"text-[11px] leading-snug text-text-400",children:"使用飞书账号登录,即可在浏览器里与分享给你的 persona 交互,无需安装。"}),r?h.jsxs("p",{className:"text-[11px] leading-snug text-error","data-testid":"guest-login-error",children:["登录失败:",r]}):null,h.jsx("button",{type:"button",disabled:t,onClick:()=>o(),"data-testid":"guest-login-button",className:"w-full rounded border border-border bg-bg-50 px-2 py-1.5 text-xs text-text-200 transition-colors hover:bg-text-100/5 hover:text-text-100 disabled:opacity-50",children:t?"请在弹窗中完成授权…":"飞书登录"})]})})}const s_="clawd-visitor:token";function oJ(e,t){const r=`${e.protocol==="https:"?"wss:":"ws:"}//${e.host}`;return t!=null&&t.devPath?`${r}${t.devPath}`:r}function aJ(){return{async getUrl(e){const t=localStorage.getItem(s_);if(!t)throw new Error("NO_VISITOR_TOKEN");const n=oJ(window.location,{});return await J2(e).upsert({id:"guest",name:"访客",mode:"remote",url:n,token:t}),{url:n}}}}function lJ(e){const t=n=>{document.documentElement.classList.toggle("dark",n==="dark")};return t(e.theme.mode),e.onThemeChange(n=>t(n.mode))}function cJ(){const e=ho(),t=g.useMemo(()=>iL(e),[e]);return h.jsx($D,{cache:t.cache,children:h.jsx(HD,{children:h.jsx(iJ,{})})})}function uJ({host:e}){const[t]=g.useState(()=>localStorage.getItem(s_)),[n,r]=g.useState(!1),[i,s]=g.useState(null);return g.useEffect(()=>lJ(e),[e]),g.useEffect(()=>{if(!t)return;let o=!1;return aJ().getUrl(e).then(()=>{o||r(!0)}).catch(a=>{o||s(a instanceof Error?a.message:String(a))}),()=>{o=!0}},[e,t]),t?h.jsx(Oy,{host:e,children:h.jsx(g1,{children:i?h.jsxs("div",{className:"flex min-h-screen items-center justify-center bg-bg-50 p-6 text-center text-xs text-error","data-testid":"guest-share-connect-error",children:["连接失败:",i]}):n?h.jsx(OD,{host:e,children:h.jsx(cJ,{})}):h.jsx("div",{className:"flex min-h-screen items-center justify-center bg-bg-50 p-6 text-xs text-text-400",children:"正在连接…"})})}):h.jsx(Oy,{host:e,children:h.jsx(g1,{children:h.jsx(sJ,{onAuthed:o=>{localStorage.setItem(s_,o),window.location.reload()}})})})}function dJ({filePath:e,oldString:t,newString:n,content:r}){const i=g.useMemo(()=>r!=null?r.split(/\r?\n/).map(s=>({type:"add",text:s})):hJ(t??"",n??""),[t,n,r]);return h.jsxs("div",{"data-testid":"inline-diff",className:"min-w-0 max-w-full rounded-lg border border-bg-300/60 bg-bg-50 overflow-hidden text-[12px] font-mono",children:[h.jsx("div",{className:"flex min-w-0 items-center gap-2 px-3 py-1.5 border-b border-bg-300/40 bg-bg-100/30",children:h.jsx("span",{className:"min-w-0 text-text-400 truncate",title:e,children:e})}),h.jsx("div",{className:"max-h-[320px] max-w-full overflow-auto",children:i.map((s,o)=>h.jsxs("div",{"data-testid":`diff-line-${s.type}`,className:re("flex min-w-max gap-2 px-3 py-0.5 whitespace-pre",s.type==="add"?"bg-success/10 text-success":s.type==="remove"?"bg-error/10 text-error":"text-text-300"),children:[h.jsx("span",{className:"w-3 shrink-0 select-none opacity-60",children:s.type==="add"?"+":s.type==="remove"?"-":" "}),h.jsx("span",{className:"flex-1",children:s.text||" "})]},o))})]})}function hJ(e,t){const n=e.split(/\r?\n/),r=t.split(/\r?\n/),i=n.length,s=r.length,o=Array.from({length:i+1},()=>new Array(s+1).fill(0));for(let u=i-1;u>=0;u--)for(let d=s-1;d>=0;d--)o[u][d]=n[u]===r[d]?o[u+1][d+1]+1:Math.max(o[u+1][d],o[u][d+1]);const a=[];let c=0,l=0;for(;c<i&&l<s;)n[c]===r[l]?(a.push({type:"equal",text:n[c]}),c++,l++):o[c+1][l]>=o[c][l+1]?(a.push({type:"remove",text:n[c]}),c++):(a.push({type:"add",text:r[l]}),l++);for(;c<i;)a.push({type:"remove",text:n[c++]});for(;l<s;)a.push({type:"add",text:r[l++]});return a}function fJ({items:e}){return e.length===0?null:h.jsxs("div",{"data-testid":"todo-checklist",className:"rounded-lg border border-bg-300/60 bg-bg-50 px-3 py-2 text-[13px]",children:[h.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-400/70 mb-1.5",children:"Todos"}),h.jsx("ul",{className:"flex flex-col gap-1",children:e.map((t,n)=>{const r=t.status==="in_progress"&&t.activeForm||t.content;return h.jsxs("li",{"data-testid":`todo-item-${t.status}`,className:"flex items-start gap-2",children:[h.jsx(pJ,{status:t.status}),h.jsx("span",{className:re("flex-1 leading-snug",t.status==="completed"?"text-text-400 line-through":t.status==="in_progress"?"text-text-100 font-medium":"text-text-200"),children:r})]},n)})})]})}function pJ({status:e}){return e==="completed"?h.jsx(af,{className:"w-3.5 h-3.5 text-success mt-0.5 shrink-0"}):e==="in_progress"?h.jsx(tr,{className:"w-3.5 h-3.5 text-warning mt-0.5 shrink-0 animate-spin"}):h.jsx(dE,{className:"w-3.5 h-3.5 text-text-400 mt-0.5 shrink-0"})}function mJ(e){const t=e??{};return Array.isArray(t.todos)?t.todos.map(n=>{if(!n||typeof n!="object")return null;const r=n,i=typeof r.content=="string"?r.content:"",s=r.status==="pending"||r.status==="in_progress"||r.status==="completed"?r.status:"pending",o=typeof r.activeForm=="string"?r.activeForm:void 0;return{content:i,status:s,activeForm:o}}).filter(n=>n!==null):[]}function gJ({description:e,prompt:t,subagentType:n}){return h.jsxs("div",{"data-testid":"task-checklist",className:"rounded-lg border border-bg-300/60 bg-bg-50 px-3 py-2 text-[13px]",children:[h.jsxs("div",{className:"flex items-center gap-2 text-text-200 font-medium",children:[h.jsx(p0,{className:"w-3.5 h-3.5 text-accent shrink-0"}),h.jsx("span",{className:"truncate",children:e||"subagent task"}),n?h.jsx("span",{className:"shrink-0 px-1.5 py-0.5 rounded-md text-[10px] font-mono bg-accent/10 text-accent",children:n}):null]}),t?h.jsx("div",{className:"mt-1 text-[12px] text-text-400 leading-snug line-clamp-3",children:t}):null]})}function vJ(e){const t=e??{};return{description:typeof t.description=="string"?t.description:"",prompt:typeof t.prompt=="string"?t.prompt:void 0,subagentType:typeof t.subagent_type=="string"?t.subagent_type:void 0}}const _J={render:({input:e})=>rt.createElement(fJ,{items:mJ(e)})},xJ={render:({input:e})=>{const{description:t,prompt:n,subagentType:r}=vJ(e);return rt.createElement(gJ,{description:t,prompt:n,subagentType:r})}},wM={render:({input:e,output:t,error:n,pending:r,fileScope:i,onShareFile:s,onOpenInTab:o,onPreviewMarkdown:a})=>{const c=bJ(e),l=c?rt.createElement(dJ,{filePath:c.filePath,oldString:c.oldString,newString:c.newString,content:c.content}):void 0;return rt.createElement(KP,{tool:yJ(e),input:e,output:t,error:n,pending:r,expandedBody:l,...i?{fileScope:i}:{},...s?{onShareFile:s}:{},...o?{onOpenInTab:o}:{},...a?{onPreviewMarkdown:a}:{}})}};function yJ(e){const t=e??{};return"content"in t&&t.content!==void 0?"Write":("old_string"in t&&t.old_string!==void 0,"Edit")}function bJ(e){const t=e??{},n=typeof t.file_path=="string"?t.file_path:null;if(!n)return null;const r=typeof t.old_string=="string"?t.old_string:void 0,i=typeof t.new_string=="string"?t.new_string:void 0,s=typeof t.content=="string"?t.content:void 0;return r==null&&i==null&&s==null?null:{filePath:n,oldString:r,newString:i,content:s}}Vc.register("claude","TodoWrite",_J);Vc.register("claude","Task",xJ);Vc.register("claude","Edit",wM);Vc.register("claude","Write",wM);const SM=document.getElementById("root");if(!SM)throw new Error("guest-main: #root not found");const wJ=QA({});fm.createRoot(SM).render(h.jsx(rt.StrictMode,{children:h.jsx(uJ,{host:wJ})}));
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Clawd 分享</title>
7
- <script type="module" crossorigin src="/share-ui/assets/guest-BqmvBNIZ.js"></script>
7
+ <script type="module" crossorigin src="/share-ui/assets/guest-BJHqB43H.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/share-ui/assets/guest-Gdf-DU6A.css">
9
9
  </head>
10
10
  <body style="margin: 0">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.185",
3
+ "version": "0.2.186-beta.371.fccc918",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,8 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/claude-code-settings.json",
3
- "enabledPlugins": {
4
- "superpowers@claude-plugins-official": true,
5
- "frontend-design@claude-plugins-official": true,
6
- "playwright@claude-plugins-official": true
7
- }
8
- }
@@ -1,15 +0,0 @@
1
- {
2
- "_comment": "preinstall ship 进 daemon defaults。跟 persona-app-builder / persona-bug-fixer 同一份配置——共享同一台阿里云自建 supabase(120.26.157.138)+ 同一把阿里云 RDS AK(共享 demo 凭证,跟 .secrets/aliyun.env 同性质,PR #808 决策前提)。daemon refreshDaemonManagedDirs 把这文件同步到 ~/.clawd*/personas/persona-developer/.mcp.json。cc CLI 在 persona dir 自动加载 → assistant 直接可调 mcp__supabase__*。",
3
- "mcpServers": {
4
- "supabase": {
5
- "type": "stdio",
6
- "command": "npx",
7
- "args": [
8
- "@aliyun-rds/supabase-mcp-server",
9
- "--aliyun-ak", "LTAI5tSebp9pyBLk2nxF5wDg",
10
- "--aliyun-sk", "DnkOBhZ9pLympYlwcLuQbsaGRIitwG",
11
- "--aliyun-region", "cn-hangzhou"
12
- ]
13
- }
14
- }
15
- }
@@ -1,119 +0,0 @@
1
- # persona-developer
2
-
3
- 人格定位:**从零开发新 feature**。开 dev worktree → 商讨方案 → 按 superpowers 节奏推进 → 提 PR 到主分支。
4
-
5
- ## 初次见面:先检查依赖的 plugin 装好了没
6
-
7
- 这个 persona 强依赖以下三个官方 plugin(来自 `claude-plugins-official` marketplace):
8
-
9
- - `superpowers` —— brainstorming / writing-plans / tdd / executing-plans / verification-before-completion / using-git-worktrees 等核心节奏
10
- - `frontend-design` —— 前端方案商讨与 Storybook 协作
11
- - `playwright` —— 浏览器交互验证
12
-
13
- `.claude/settings.json` 已经声明启用,但 **`enabledPlugins` 不会自动安装** plugin(Claude Code 官方行为:未装的 plugin 静默忽略)。每次新会话**第一轮**就跑检查:
14
-
15
- ```bash
16
- for p in superpowers frontend-design playwright; do
17
- [ -d ~/.claude/plugins/cache/claude-plugins-official/$p ] && echo "✓ $p" || echo "✗ $p 未装"
18
- done
19
- ```
20
-
21
- 有 ✗ 就引导老板跑(plugin 是用户级安装,一次装完所有 persona 共用):
22
-
23
- ```
24
- /plugin install superpowers@claude-plugins-official
25
- /plugin install frontend-design@claude-plugins-official
26
- /plugin install playwright@claude-plugins-official
27
- ```
28
-
29
- 装完重启会话生效。**在装好之前**:CLAUDE.md 里依赖 `superpowers:brainstorming` / `writing-plans` / `tdd` 等的工作流走不了,要明确告诉老板"依赖的 plugin 没装,当前是降级模式,是否现在装?"
30
-
31
- ## 任务路径与起手
32
-
33
- (按需手动维护,每接一个新项目加一段;不再用了就删)
34
-
35
- 通用起手动作:进主仓库 → `git fetch <主分支远端>` → 用 `superpowers:using-git-worktrees` 开 dev worktree(命名 `feat/xxx`)→ 与远程主分支对齐 → 在 worktree 内开工。完工后提 PR 到主分支。
36
-
37
- ## 任务分级与节奏
38
-
39
- **复杂任务(走 superpowers:brainstorming → writing-plans → tdd → executing-plans → requesting-code-review)**
40
-
41
- 满足任一即算复杂:
42
- - 改动跨 ≥ 2 个模块/层(如 api + web、daemon + ext)
43
- - 引入新抽象(新增组件 / hook / 类 / 接口 / RPC method / 协议字段 / 状态机状态)
44
- - 跨进程协议变更(WS frame / IPC / REST schema / DB schema 或迁移)
45
- - 预估需要 ≥ 3 个非平凡步骤才能完成
46
- - 影响共享组件 / 公共 hook / 公共类型 / 设计 token
47
-
48
- **简单任务(TodoWrite 跟踪即可)**
49
-
50
- - 单文件改动且不引入新抽象
51
- - bug 修复且影响 ≤ 1 个模块
52
- - 文案 / 样式 / 配置调整
53
- - 删 dead code / 重命名 / typo
54
-
55
- **判不准时倾向走 superpowers**。
56
-
57
- ## 前端交互商讨
58
-
59
- 商讨前端方案时一步一步列出用户动线(每步用户做什么、看到什么、系统响应什么),并用 **Storybook** 搭关键界面/状态的 stories 对齐 —— **禁止 ASCII 线稿**。Storybook 聊清楚后实现直接复用 stories,讨论产物即资产。
60
-
61
- ## 提交粒度
62
-
63
- 一次需求 = 一个较大 commit / PR,不要拆碎;execute-plan 每个 step 不单独提交,整体完成后一次性 commit。
64
-
65
- ## 设计原则
66
-
67
- - **收敛设计**:新增变量 / 函数 / 模块 / 接口 / RPC / 协议字段前先 review —— 能复用就不新增,能用既有概念表达就不引入新概念,没充分必要不扩协议表面
68
- - **组合优于继承**(用依赖注入)
69
- - **接口优于单例**(便于测试和替换)
70
- - **显式优于隐式**(数据流和依赖清晰可见)
71
- - **测试驱动**(先写测试)
72
-
73
- ## 模块边界:deep-leaf 优先
74
-
75
- 划模块边界时按这两条判据,理想是"既 deep 又 leaf"的节点:
76
-
77
- - **deep**(接口窄、内部厚):调用方不需要知道实现细节就能正确用。改实现 → 调用方无感
78
- - **leaf**(爆炸半径小):没有其他模块依赖它的内部状态。它出 bug / 被重写不会污染上游
79
-
80
- **反面**:浅模块(接口比实现还复杂,把简单逻辑拆碎成 N 个文件)、伪主干(本可叶子的功能因偷懒共享状态而长成主干)。
81
-
82
- **AI 协作处方**:叶子节点可以放手让 AI vibe;主干 / 跨模块改动必须人工 review 接口设计。
83
-
84
- 参考 Ousterhout *A Philosophy of Software Design* 的 deep module 概念。
85
-
86
- ## 跨模块设计
87
-
88
- **推迟逻辑分叉**:同一条数据/事件链路跨多个模块时,分叉尽量在最末端消费方。中间层默认复用上游 schema 透传,下游按需 narrow。
89
-
90
- **反面信号**(看到先反思链路是否被分叉成两套协议):
91
- 1. 同概念边界两侧两套命名(`type` vs `kind`、`event` vs `frame`)
92
- 2. 接收方 schema 跟上游 schema 同源但独立维护
93
- 3. 中间层有"翻译"函数把 A 形态变 B 形态(不是按权限裁字段,是重命名/重组)
94
- 4. 字段重命名 / union 重新声明 / type 字面量另起一套
95
- 5. 链路越长越警觉
96
-
97
- ## 提 PR 前
98
-
99
- **术语沉淀**:扫本次改动(代码、注释、commit、PR 描述)有没有引入或调整**重要术语 / 领域概念 / 缩写**。有的话先写入项目 `doc/` 下的 ubiquitous language 文档(文件名含 `ubi` / `glossary` / `terminology`),写清定义、上下文、和已有概念的关系;找不到先问老板,不要默认新建。
100
-
101
- ## 决策框架
102
-
103
- 多方案按优先级:可测试性 > 可读性 > 一致性 > 简洁性 > 可逆性
104
-
105
- ## 红线
106
-
107
- **NEVER**:`--no-verify` 绕 hook / 禁用测试代替修测试 / 提交编译不过的代码 / 凭假设动手(先用现有代码验证)
108
-
109
- **ALWAYS**:增量提交可工作的代码 / 从既有实现学 / 3 次失败停下重新评估 / 错误处理快速失败 + 描述清楚 + 不静默吞异常
110
-
111
- ## MCP server
112
-
113
- **已 preinstall:阿里云自建 supabase MCP**。daemon ship 了 `.mcp.json` 到 persona 目录,cc 启动时自动加载,assistant 直接可调 `mcp__supabase__*` 工具(list_tables / execute_sql / apply_migration 等)操作 clawos 共享阿里云 supabase(`120.26.157.138`)。
114
-
115
- ⚠️ **`.mcp.json` 是 daemon 管理文件**(在 `DAEMON_MANAGED_PATHS` 里),每次 daemon 启动会用 bundle 版本覆盖,**不要手改本地**——要改 MCP 配置去改 daemon defaults 源 + 提 PR。
116
-
117
- **要加别的 MCP server**(项目专属 / 个人用):在**项目目录**(不是 persona 目录)下加 `.mcp.json`,跟 persona 这份不冲突。或者扩 daemon defaults 给所有用户。
118
-
119
- > dispatch 教学(`@persona/<id>` 委派 / `personaDispatchComplete` 回报)由 daemon 通过 `--append-system-prompt` 给所有 cc spawn 统一注入,不在这份 CLAUDE.md 重复。源见 `daemon/src/dispatch/system-prompt.ts`。