@tom2012/cc-web 1.5.10 → 1.5.11
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/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A self-hosted web application (and macOS Electron desktop app) that provides a browser-based interface for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI sessions. Create projects, each with a persistent terminal running Claude Code, and interact with them through a real-time terminal UI.
|
|
4
4
|
|
|
5
|
-
**Current version**: v1.5.
|
|
5
|
+
**Current version**: v1.5.11 | [GitHub](https://github.com/zbc0315/cc-web) | MIT License
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
@@ -32,10 +32,10 @@ The fastest way to get running:
|
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
# Try without installing (one-time)
|
|
35
|
-
npx cc-web
|
|
35
|
+
npx @tom2012/cc-web
|
|
36
36
|
|
|
37
37
|
# Or install globally
|
|
38
|
-
npm install -g cc-web
|
|
38
|
+
npm install -g @tom2012/cc-web
|
|
39
39
|
ccweb
|
|
40
40
|
```
|
|
41
41
|
|
|
@@ -338,7 +338,7 @@ Error generating stack: `+a.message+`
|
|
|
338
338
|
|
|
339
339
|
If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component.
|
|
340
340
|
|
|
341
|
-
For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return S.useEffect(()=>{e&&(document.getElementById(e)||console.error(n))},[n,e]),null},F2="DialogDescriptionWarning",P2=({contentRef:e,descriptionId:t})=>{const r=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${s1(F2).contentName}}.`;return S.useEffect(()=>{var a;const i=(a=e.current)==null?void 0:a.getAttribute("aria-describedby");t&&i&&(document.getElementById(t)||console.warn(r))},[r,e,t]),null},B2=qC,U2=XC,o1=ZC,l1=QC,u1=e1,c1=n1,z2=i1;const Xu=B2,$2=U2,d1=S.forwardRef(({className:e,...t},n)=>g.jsx(o1,{ref:n,className:J("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...t}));d1.displayName=o1.displayName;const po=S.forwardRef(({className:e,children:t,...n},r)=>g.jsxs($2,{children:[g.jsx(d1,{}),g.jsxs(l1,{ref:r,className:J("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",e),...n,children:[t,g.jsxs(z2,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[g.jsx(wa,{className:"h-4 w-4"}),g.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));po.displayName=l1.displayName;const fo=({className:e,...t})=>g.jsx("div",{className:J("flex flex-col space-y-1.5 text-center sm:text-left",e),...t});fo.displayName="DialogHeader";const go=({className:e,...t})=>g.jsx("div",{className:J("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",e),...t});go.displayName="DialogFooter";const mo=S.forwardRef(({className:e,...t},n)=>g.jsx(u1,{ref:n,className:J("text-lg font-semibold leading-none tracking-tight",e),...t}));mo.displayName=u1.displayName;const bo=S.forwardRef(({className:e,...t},n)=>g.jsx(c1,{ref:n,className:J("text-sm text-muted-foreground",e),...t}));bo.displayName=c1.displayName;function h1({onSelect:e}){const[t,n]=S.useState(""),[r,i]=S.useState(null),[a,s]=S.useState([]),[o,l]=S.useState(!0),[u,d]=S.useState(null),[c,h]=S.useState(!1),[p,f]=S.useState(""),[b,y]=S.useState(null),[m,_]=S.useState(!1),v=S.useRef(null),w=async L=>{l(!0),d(null);try{const T=await kC(L);n(T.path),i(T.parent),s(T.entries)}catch(T){d(T instanceof Error?T.message:"Failed to load directory")}finally{l(!1)}};S.useEffect(()=>{w()},[]),S.useEffect(()=>{c&&setTimeout(()=>{var L;return(L=v.current)==null?void 0:L.focus()},0)},[c]);const C=()=>{f(""),y(null),h(!0)},k=()=>{h(!1),f(""),y(null)},A=async()=>{const L=p.trim();if(L){_(!0),y(null);try{const{path:T}=await vL(t,L);h(!1),f(""),await w(t),w(T)}catch(T){y(T instanceof Error?T.message:"Failed to create folder")}finally{_(!1)}}},O=L=>{L.key==="Enter"?(L.preventDefault(),A()):L.key==="Escape"&&k()},P=t.split("/").filter(Boolean),I=L=>{const T="/"+P.slice(0,L+1).join("/");w(T)};return g.jsxs("div",{className:"flex flex-col h-64 border rounded-md overflow-hidden",children:[g.jsxs("div",{className:"flex items-center gap-1 px-2 py-2 bg-muted border-b flex-shrink-0",children:[g.jsx(se,{variant:"ghost",size:"sm",className:"h-6 px-1 flex-shrink-0",onClick:()=>void w(),title:"Home",children:g.jsx(PL,{className:"h-3 w-3"})}),g.jsx("div",{className:"flex items-center gap-1 flex-1 overflow-x-auto min-w-0",children:P.map((L,T)=>g.jsxs(vn.Fragment,{children:[g.jsx(Hf,{className:"h-3 w-3 text-muted-foreground flex-shrink-0"}),g.jsx("button",{className:"text-xs hover:text-foreground text-muted-foreground whitespace-nowrap",onClick:()=>I(T),children:L})]},T))}),g.jsxs(se,{variant:"ghost",size:"sm",className:"h-6 px-1.5 flex-shrink-0 gap-1 text-xs",onClick:C,disabled:c||o||!!u,title:"New folder",children:[g.jsx(FL,{className:"h-3.5 w-3.5"}),g.jsx("span",{className:"hidden sm:inline",children:"New folder"})]})]}),g.jsxs("div",{className:"flex-1 overflow-y-auto",children:[o&&g.jsx("div",{className:"flex items-center justify-center h-full text-sm text-muted-foreground",children:"Loading..."}),u&&g.jsx("div",{className:"flex items-center justify-center h-full text-sm text-destructive px-4 text-center",children:u}),!o&&!u&&g.jsxs("div",{className:"p-1",children:[r&&g.jsxs("button",{className:"flex items-center gap-2 w-full px-2 py-1.5 text-sm rounded hover:bg-accent hover:text-accent-foreground",onClick:()=>void w(r),children:[g.jsx(Rh,{className:"h-4 w-4 text-muted-foreground"}),g.jsx("span",{children:".."})]}),c&&g.jsxs("div",{className:"flex items-center gap-1 px-2 py-1.5",children:[g.jsx(Ih,{className:"h-4 w-4 text-blue-500 flex-shrink-0"}),g.jsx("input",{ref:v,className:J("flex-1 text-sm bg-background border rounded px-1.5 py-0.5 outline-none","focus:ring-1 focus:ring-ring",b&&"border-destructive"),placeholder:"Folder name",value:p,onChange:L=>{f(L.target.value),y(null)},onKeyDown:O,disabled:m}),g.jsx("button",{className:"p-1 rounded hover:bg-accent disabled:opacity-50",onClick:()=>void A(),disabled:!p.trim()||m,title:"Create",children:g.jsx(IL,{className:"h-3.5 w-3.5 text-green-600"})}),g.jsx("button",{className:"p-1 rounded hover:bg-accent",onClick:k,disabled:m,title:"Cancel",children:g.jsx(wa,{className:"h-3.5 w-3.5 text-muted-foreground"})})]}),b&&g.jsx("p",{className:"px-3 pb-1 text-xs text-destructive",children:b}),a.length===0&&!c&&g.jsx("div",{className:"text-sm text-muted-foreground px-2 py-4 text-center",children:"Empty directory"}),a.map(L=>g.jsxs("button",{className:J("flex items-center gap-2 w-full px-2 py-1.5 text-sm rounded text-left",L.type==="dir"?"hover:bg-accent hover:text-accent-foreground cursor-pointer":"opacity-40 cursor-not-allowed"),onClick:()=>{L.type==="dir"&&w(L.path)},disabled:L.type==="file",children:[L.type==="dir"?g.jsx(Ih,{className:"h-4 w-4 text-blue-500 flex-shrink-0"}):g.jsx(ML,{className:"h-4 w-4 text-muted-foreground flex-shrink-0"}),g.jsx("span",{className:"truncate",children:L.name})]},L.path))]})]}),g.jsxs("div",{className:"border-t px-3 py-2 flex items-center justify-between gap-2 flex-shrink-0 bg-background",children:[g.jsx("span",{className:"text-xs text-muted-foreground truncate flex-1",children:t}),g.jsx(se,{size:"sm",onClick:()=>e(t),disabled:!t,children:"Select this folder"})]})]})}const j2=[{value:"claude",label:"Claude",desc:"Anthropic Claude Code CLI"},{value:"opencode",label:"OpenCode",desc:"OpenCode CLI (sst/opencode)"},{value:"codex",label:"Codex",desc:"OpenAI Codex CLI"},{value:"qwen",label:"Qwen",desc:"Qwen Code CLI (QwenLM)"}],bw={claude:{limited:"claude",unlimited:"claude --dangerously-skip-permissions"},opencode:{limited:"opencode",unlimited:"opencode --dangerously-skip-permissions"},codex:{limited:"codex",unlimited:"codex --ask-for-approval never --sandbox danger-full-access"},qwen:{limited:"qwen-code",unlimited:"qwen-code --yolo"}};function H2({open:e,onOpenChange:t,onCreated:n}){const[r,i]=S.useState("name"),[a,s]=S.useState(""),[o,l]=S.useState(""),[u,d]=S.useState("claude"),[c,h]=S.useState("limited"),[p,f]=S.useState(!1),[b,y]=S.useState(null),m=()=>{i("name"),s(""),l(""),d("claude"),h("limited"),y(null),f(!1)},_=O=>{O||m(),t(O)},v=()=>{if(!a.trim()){y("Please enter a project name");return}y(null),i("folder")},w=O=>{l(O),i("settings")},C=async()=>{f(!0),y(null);try{const O=await oL({name:a.trim(),folderPath:o,permissionMode:c,cliTool:u});n(O),_(!1)}catch(O){y(O instanceof Error?O.message:"Failed to create project")}finally{f(!1)}},k={name:"New Project — Name",folder:"New Project — Select Folder",settings:"New Project — Settings"},A=["name","folder","settings"];return g.jsx(Xu,{open:e,onOpenChange:_,children:g.jsxs(po,{className:"sm:max-w-lg",children:[g.jsxs(fo,{children:[g.jsx(mo,{children:k[r]}),g.jsxs(bo,{children:[r==="name"&&"Give your project a name.",r==="folder"&&"Choose the working directory for this project.",r==="settings"&&"Choose the AI coding tool and run mode."]})]}),g.jsx("div",{className:"flex gap-2 mb-2",children:A.map((O,P)=>g.jsx("div",{className:`h-1.5 flex-1 rounded-full ${r===O?"bg-primary":A.indexOf(r)>P?"bg-primary/40":"bg-muted"}`},O))}),r==="name"&&g.jsxs("div",{className:"space-y-4",children:[g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{htmlFor:"project-name",children:"Project Name"}),g.jsx(Hs,{id:"project-name",placeholder:"My Project",value:a,onChange:O=>s(O.target.value),onKeyDown:O=>{O.key==="Enter"&&v()},autoFocus:!0})]}),b&&g.jsx("p",{className:"text-sm text-destructive",children:b})]}),r==="folder"&&g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{children:"Working Directory"}),g.jsx(h1,{onSelect:w})]}),r==="settings"&&g.jsxs("div",{className:"space-y-5",children:[g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{children:"AI Coding Tool"}),g.jsx("div",{className:"grid grid-cols-2 gap-2",children:j2.map(O=>g.jsxs("label",{className:`flex items-center gap-2.5 cursor-pointer p-3 rounded-md border transition-colors ${u===O.value?"border-primary bg-primary/5":"hover:bg-accent"}`,children:[g.jsx("input",{type:"radio",name:"cliTool",value:O.value,checked:u===O.value,onChange:()=>d(O.value),className:"accent-primary"}),g.jsxs("div",{children:[g.jsx("div",{className:"font-medium text-sm",children:O.label}),g.jsx("div",{className:"text-xs text-muted-foreground",children:O.desc})]})]},O.value))})]}),g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{children:"Permission Mode"}),g.jsxs("div",{className:"space-y-2",children:[g.jsxs("label",{className:"flex items-start gap-3 cursor-pointer p-3 rounded-md border hover:bg-accent transition-colors",children:[g.jsx("input",{type:"radio",name:"permissionMode",value:"limited",checked:c==="limited",onChange:()=>h("limited"),className:"mt-0.5"}),g.jsxs("div",{children:[g.jsx("div",{className:"font-medium text-sm",children:"Limited"}),g.jsxs("div",{className:"text-xs text-muted-foreground",children:["Runs ",g.jsx("code",{className:"bg-muted px-1 rounded",children:bw[u].limited})," — asks for permission before file changes."]})]})]}),g.jsxs("label",{className:"flex items-start gap-3 cursor-pointer p-3 rounded-md border hover:bg-accent transition-colors",children:[g.jsx("input",{type:"radio",name:"permissionMode",value:"unlimited",checked:c==="unlimited",onChange:()=>h("unlimited"),className:"mt-0.5"}),g.jsxs("div",{children:[g.jsx("div",{className:"font-medium text-sm",children:"Unlimited"}),g.jsxs("div",{className:"text-xs text-muted-foreground",children:["Runs ",g.jsx("code",{className:"bg-muted px-1 rounded",children:bw[u].unlimited})," — acts autonomously."]})]})]})]})]}),g.jsxs("div",{className:"text-xs text-muted-foreground",children:[g.jsx("span",{className:"font-medium",children:"Folder:"})," ",g.jsx("span",{className:"font-mono",children:o})]}),b&&g.jsx("p",{className:"text-sm text-destructive",children:b})]}),g.jsxs(go,{children:[r!=="name"&&g.jsx(se,{variant:"outline",onClick:()=>i(r==="settings"?"folder":"name"),disabled:p,children:"Back"}),r==="name"&&g.jsx(se,{onClick:v,children:"Next"}),r==="folder"&&g.jsx(se,{variant:"outline",onClick:()=>t(!1),children:"Cancel"}),r==="settings"&&g.jsx(se,{onClick:()=>void C(),disabled:p,children:p?"Creating...":"Create Project"})]})]})})}function G2({open:e,onOpenChange:t,onOpened:n}){const[r,i]=S.useState(""),[a,s]=S.useState(!1),[o,l]=S.useState(null),u=()=>{i(""),l(null),s(!1)},d=h=>{h||u(),t(h)},c=async h=>{i(h),s(!0),l(null);try{const p=await lL(h);n(p),d(!1)}catch(p){l(p instanceof Error?p.message:"Failed to open project"),s(!1)}};return g.jsx(Xu,{open:e,onOpenChange:d,children:g.jsxs(po,{className:"sm:max-w-lg",children:[g.jsxs(fo,{children:[g.jsx(mo,{children:"Open Existing Project"}),g.jsxs(bo,{children:["Select a folder that contains a ",g.jsx("code",{className:"bg-muted px-1 rounded text-xs",children:".ccweb/"})," configuration. The project's history and settings will be restored."]})]}),g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{children:"Project Folder"}),g.jsx(h1,{onSelect:h=>void c(h)})]}),o&&g.jsx("p",{className:"text-sm text-destructive",children:o}),r&&!o&&a&&g.jsxs("p",{className:"text-sm text-muted-foreground",children:["Opening project from ",r,"..."]}),g.jsx(go,{children:g.jsx(se,{variant:"outline",onClick:()=>d(!1),disabled:a,children:"Cancel"})})]})})}function W2(e){if(!e)return"";const t=new Date(e).getTime()-Date.now();if(t<=0)return"即将重置";const n=Math.floor(t/36e5),r=Math.floor(t%36e5/6e4);return n>0?`${n}h${r}m`:`${r}m`}function Jo({label:e,bucket:t}){if(!t||t.utilization===void 0)return null;const n=t.utilization,r=n<50?"text-green-400":n<80?"text-yellow-400":"text-red-400",i=W2(t.resetAt);return g.jsxs("span",{className:"text-muted-foreground whitespace-nowrap",children:[e," ",g.jsxs("span",{className:J("font-medium",r),children:[n,"%"]}),i&&g.jsxs("span",{className:"text-muted-foreground/70 ml-0.5",children:["(",i,")"]})]})}function p1({className:e}){const[t,n]=S.useState("loading"),[r,i]=S.useState(!1);S.useEffect(()=>{const c=async()=>{try{n(await _L())}catch{n(null)}};c();const h=setInterval(()=>void c(),5*60*1e3);return()=>clearInterval(h)},[]);const a=async()=>{i(!0);try{n(await yL())}catch{n(null)}finally{i(!1)}};if(t==="loading"||!t)return null;const s=!!t.fiveHour,o=!!t.sevenDay,l=!!t.sevenDaySonnet,u=!!t.sevenDayOpus,d=s||o||l||u;return g.jsxs("div",{className:J("flex items-center gap-1.5 text-xs",e),children:[t.planName&&g.jsx("span",{className:"font-medium text-foreground bg-muted border border-border px-2 py-0.5 rounded-full",children:t.planName}),d&&g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"text-muted-foreground/50",children:"|"}),g.jsx(Jo,{label:"5h",bucket:t.fiveHour}),o&&g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"text-muted-foreground/50",children:"·"}),g.jsx(Jo,{label:"7d",bucket:t.sevenDay})]}),l&&g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"text-muted-foreground/50",children:"·"}),g.jsx(Jo,{label:"7d Sonnet",bucket:t.sevenDaySonnet})]}),u&&g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"text-muted-foreground/50",children:"·"}),g.jsx(Jo,{label:"7d Opus",bucket:t.sevenDayOpus})]})]}),g.jsx("button",{onClick:()=>void a(),className:"text-muted-foreground hover:text-foreground transition-colors",title:"刷新用量信息",children:g.jsx(Ws,{className:J("h-3 w-3",r&&"animate-spin")})})]})}const _w="v1.5.10",el=!!window.electronUpdater;function V2(e,t){const n=e.split(".").map(Number),r=t.split(".").map(Number);for(let i=0;i<Math.max(n.length,r.length);i++){const a=n[i]||0,s=r[i]||0;if(a!==s)return a-s}return 0}function q2(){const[e,t]=S.useState("idle"),[n,r]=S.useState(!1),[i,a]=S.useState(""),[s,o]=S.useState(0),[l,u]=S.useState([]),[d,c]=S.useState([]),[h,p]=S.useState(null),[f,b]=S.useState(null);S.useEffect(()=>window.electronUpdater?window.electronUpdater.onUpdateStatus(k=>{switch(k.type){case"progress":{const A=k.info;o(Math.round((A==null?void 0:A.percent)??0));break}case"downloaded":t("downloaded");break;case"error":p(k.info||"Download failed"),t("error");break}}):void 0,[]);const y=S.useCallback(async()=>{t("checking"),p(null),r(!0);try{if(el){const k=await window.electronUpdater.checkForUpdate();if(k.error)throw new Error(k.error);if(!k.available){t("no_update");return}a(k.version?`v${k.version}`:"new version")}else{const k=await fetch("https://api.github.com/repos/zbc0315/cc-web/releases/latest");if(k.status===404){t("no_update");return}if(!k.ok)throw new Error(`GitHub API ${k.status}`);const A=await k.json(),O=A.tag_name.replace(/^v/,""),P=_w.replace(/^v/,"");if(V2(O,P)<=0){t("no_update");return}a(A.tag_name)}const C=await wL();u(C.projects),t(C.runningCount>0?"confirm_prepare":"update_available")}catch(C){p(C instanceof Error?C.message:"Check failed"),t("error")}},[]),m=async()=>{t("preparing");try{const C=await EL();c(C.results),t("update_available")}catch(C){p(C instanceof Error?C.message:"Prepare failed"),t("error")}},_=async()=>{if(el){t("downloading"),o(0);const C=await window.electronUpdater.downloadUpdate();C.success?C.path&&b(C.path):(p(C.error||"Download failed"),t("error"))}else window.open("https://github.com/zbc0315/cc-web/releases/latest","_blank")},v=()=>{var C;(C=window.electronUpdater)==null||C.quitAndInstall(f||void 0)},w=()=>{r(!1),setTimeout(()=>{t("idle"),a(""),u([]),c([]),p(null),o(0)},200)};return g.jsxs(g.Fragment,{children:[g.jsxs(se,{variant:"ghost",size:"sm",onClick:()=>void y(),disabled:e==="checking"||e==="preparing"||e==="downloading",children:[e==="checking"||e==="preparing"||e==="downloading"?g.jsx(Oh,{className:"h-4 w-4 mr-2 animate-spin"}):g.jsx(LL,{className:"h-4 w-4 mr-2"}),"Update"]}),g.jsx(Xu,{open:n,onOpenChange:C=>{C||w()},children:g.jsxs(po,{className:"sm:max-w-md",children:[g.jsxs(fo,{children:[g.jsxs(mo,{children:[e==="checking"&&"Checking for updates...",e==="no_update"&&"Up to date",e==="update_available"&&`Update ${i} available`,e==="confirm_prepare"&&"Save project memory first",e==="preparing"&&"Saving project memory...",e==="downloading"&&"Downloading update...",e==="downloaded"&&"Update ready to install",e==="error"&&"Update error"]}),g.jsxs(bo,{children:[e==="checking"&&"Checking for the latest version...",e==="no_update"&&`Current version ${_w} is the latest.`,e==="update_available"&&(d.length>0?"All projects saved and stopped. Ready to update.":`A new version is available. ${el?"Click download to update automatically.":""}`),e==="confirm_prepare"&&`${l.length} project(s) running. Each Claude will be asked to save memory, then terminals will stop.`,e==="preparing"&&"Sending save commands and waiting for Claude to finish...",e==="downloading"&&`Downloading... ${s}%`,e==="downloaded"&&"The update has been downloaded. Click install to restart and apply.",e==="error"&&(h||"An error occurred.")]})]}),e==="downloading"&&g.jsx("div",{className:"w-full bg-muted rounded-full h-2 overflow-hidden",children:g.jsx("div",{className:"bg-primary h-full transition-all duration-300",style:{width:`${s}%`}})}),e==="confirm_prepare"&&l.length>0&&g.jsx("div",{className:"space-y-1 text-sm",children:l.map(C=>g.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 rounded bg-muted",children:[g.jsx("span",{className:"h-2 w-2 rounded-full bg-green-500 shrink-0"}),g.jsx("span",{className:"truncate",children:C.name})]},C.id))}),e==="preparing"&&g.jsx("div",{className:"flex items-center justify-center py-6",children:g.jsx(Oh,{className:"h-8 w-8 animate-spin text-muted-foreground"})}),e==="update_available"&&d.length>0&&g.jsx("div",{className:"space-y-1 text-sm",children:d.map(C=>g.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 rounded bg-muted",children:[C.status==="stopped"?g.jsx(RL,{className:"h-4 w-4 text-green-500 shrink-0"}):g.jsx(TL,{className:"h-4 w-4 text-yellow-500 shrink-0"}),g.jsx("span",{className:"truncate",children:C.name}),g.jsx("span",{className:"text-xs text-muted-foreground ml-auto shrink-0",children:C.message})]},C.id))}),g.jsxs(go,{children:[e==="no_update"&&g.jsx(se,{onClick:w,children:"OK"}),e==="update_available"&&g.jsxs(g.Fragment,{children:[g.jsx(se,{variant:"outline",onClick:w,children:"Later"}),g.jsx(se,{onClick:()=>void _(),children:el?"Download & Install":`Download ${i}`})]}),e==="confirm_prepare"&&g.jsxs(g.Fragment,{children:[g.jsx(se,{variant:"outline",onClick:w,children:"Cancel"}),g.jsx(se,{onClick:()=>void m(),children:"Save Memory & Stop All"})]}),e==="downloaded"&&g.jsxs(g.Fragment,{children:[g.jsx(se,{variant:"outline",onClick:w,children:"Later"}),g.jsx(se,{onClick:v,children:"Restart & Install"})]}),e==="error"&&g.jsx(se,{onClick:w,children:"Close"})]})]})})]})}function Y2(){const[e,t]=S.useState([]),[n,r]=S.useState(!1),[i,a]=S.useState(""),[s,o]=S.useState(""),[l,u]=S.useState(""),[d,c]=S.useState(null),[h,p]=S.useState(""),[f,b]=S.useState(""),[y,m]=S.useState(""),_=S.useRef(null),v=S.useRef(null);S.useEffect(()=>{EC().then(t).catch(()=>t([]))},[]),S.useEffect(()=>{n&&setTimeout(()=>{var A;return(A=_.current)==null?void 0:A.focus()},0)},[n]),S.useEffect(()=>{d&&setTimeout(()=>{var A;return(A=v.current)==null?void 0:A.focus()},0)},[d]);const w=async()=>{const A=s.trim();if(A)try{const O=await gL({label:i.trim()||A,command:A,...l?{parentId:l}:{}});t(P=>[...P,O]),a(""),o(""),u(""),r(!1)}catch(O){console.error("[GlobalShortcuts] Failed to add:",O)}},C=async A=>{try{await bL(A),t(O=>O.filter(P=>P.id!==A)),d===A&&c(null)}catch(O){console.error("[GlobalShortcuts] Failed to delete:",O)}},k=async()=>{const A=f.trim();if(!(!A||!d))try{const O=await mL(d,{label:h.trim()||A,command:A,parentId:y||null});t(P=>P.map(I=>I.id===d?O:I)),c(null)}catch(O){console.error("[GlobalShortcuts] Failed to save:",O)}};return g.jsxs("section",{className:"mt-10",children:[g.jsxs("div",{className:"flex items-center justify-between mb-4",children:[g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(hu,{className:"h-4 w-4 text-muted-foreground"}),g.jsx("h2",{className:"text-lg font-semibold",children:"全局快捷命令"}),g.jsx("span",{className:"text-xs text-muted-foreground",children:"在所有项目的终端中可用"})]}),g.jsxs("button",{onClick:()=>{r(A=>!A),c(null)},className:J("flex items-center gap-1.5 text-sm px-3 py-1.5 rounded-md border transition-colors",n?"border-border text-foreground bg-muted":"border-border text-muted-foreground hover:text-foreground hover:bg-muted"),children:[g.jsx(du,{className:"h-3.5 w-3.5"}),"新建"]})]}),n&&g.jsxs("div",{className:"mb-4 p-4 rounded-lg border border-border bg-background space-y-3",children:[g.jsx("input",{ref:_,placeholder:"名称(可选)",value:i,onChange:A=>a(A.target.value),className:"w-full text-sm bg-muted border border-border rounded px-3 py-1.5 text-foreground placeholder:text-muted-foreground outline-none focus:border-border transition-colors"}),g.jsx("textarea",{placeholder:"命令内容…",value:s,onChange:A=>o(A.target.value),rows:3,className:"w-full text-sm bg-muted border border-border rounded px-3 py-1.5 text-foreground placeholder:text-muted-foreground font-mono outline-none focus:border-border transition-colors resize-none",onKeyDown:A=>{A.key==="Enter"&&(A.metaKey||A.ctrlKey)&&(A.preventDefault(),w()),A.key==="Escape"&&(r(!1),a(""),o(""),u(""))}}),g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(xl,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),g.jsxs("select",{value:l,onChange:A=>u(A.target.value),className:"flex-1 text-sm bg-muted border border-border rounded px-3 py-1.5 text-foreground outline-none focus:border-border transition-colors",children:[g.jsx("option",{value:"",children:"无继承"}),e.map(A=>g.jsx("option",{value:A.id,children:A.label},A.id))]})]}),g.jsxs("div",{className:"flex items-center justify-between",children:[g.jsx("span",{className:"text-xs text-muted-foreground",children:"⌘↩ 保存 · Esc 取消"}),g.jsxs("div",{className:"flex gap-2",children:[g.jsx("button",{onClick:()=>{r(!1),a(""),o("")},className:"text-sm px-3 py-1 rounded bg-secondary hover:bg-accent text-foreground transition-colors",children:"取消"}),g.jsx("button",{onClick:()=>void w(),disabled:!s.trim(),className:J("text-sm px-3 py-1 rounded transition-colors text-white",s.trim()?"bg-blue-600 hover:bg-blue-500":"bg-secondary opacity-40 cursor-not-allowed"),children:"保存"})]})]})]}),e.length===0&&!n?g.jsxs("div",{className:"flex flex-col items-center gap-2 py-10 text-muted-foreground/50 border border-dashed border-border rounded-lg",children:[g.jsx(hu,{className:"h-6 w-6"}),g.jsx("p",{className:"text-sm",children:"还没有全局快捷命令"})]}):g.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",children:e.map(A=>d===A.id?g.jsxs("div",{className:"rounded-lg border border-border bg-background p-3 space-y-2",children:[g.jsx("input",{ref:v,value:h,onChange:O=>p(O.target.value),placeholder:"名称(可选)",className:"w-full text-sm bg-muted border border-border rounded px-2.5 py-1 text-foreground placeholder:text-muted-foreground outline-none focus:border-border transition-colors"}),g.jsx("textarea",{value:f,onChange:O=>b(O.target.value),rows:3,className:"w-full text-sm bg-muted border border-border rounded px-2.5 py-1 text-foreground font-mono outline-none focus:border-border transition-colors resize-none",onKeyDown:O=>{O.key==="Enter"&&(O.metaKey||O.ctrlKey)&&(O.preventDefault(),k()),O.key==="Escape"&&c(null)}}),g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(xl,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),g.jsxs("select",{value:y,onChange:O=>m(O.target.value),className:"flex-1 text-sm bg-muted border border-border rounded px-2.5 py-1 text-foreground outline-none focus:border-border transition-colors",children:[g.jsx("option",{value:"",children:"无继承"}),e.filter(O=>O.id!==A.id).map(O=>g.jsx("option",{value:O.id,children:O.label},O.id))]})]}),g.jsxs("div",{className:"flex gap-2 justify-end",children:[g.jsx("button",{onClick:()=>c(null),className:"text-xs px-2.5 py-1 rounded bg-secondary hover:bg-accent text-foreground transition-colors",children:"取消"}),g.jsx("button",{onClick:()=>void k(),disabled:!f.trim(),className:J("text-xs px-2.5 py-1 rounded transition-colors text-white",f.trim()?"bg-blue-600 hover:bg-blue-500":"bg-secondary opacity-40 cursor-not-allowed"),children:"保存"})]})]},A.id):g.jsxs("div",{className:"group relative rounded-lg border border-border bg-background hover:border-muted-foreground/30 transition-colors p-3",children:[g.jsx("div",{className:"text-sm font-medium text-foreground truncate pr-14",children:A.label}),A.parentId&&(()=>{const O=e.find(P=>P.id===A.parentId);return O?g.jsxs("div",{className:"flex items-center gap-1 mt-1",children:[g.jsx(xl,{className:"h-3 w-3 text-muted-foreground"}),g.jsxs("span",{className:"text-xs text-muted-foreground truncate",children:["继承: ",O.label]})]}):null})(),!A.parentId&&A.label!==A.command&&g.jsx("div",{className:"text-xs text-muted-foreground font-mono truncate mt-1 pr-14",children:A.command}),g.jsxs("div",{className:"absolute top-2.5 right-2.5 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity",children:[g.jsx("button",{onClick:()=>{c(A.id),p(A.label),b(A.command),m(A.parentId||""),r(!1)},className:"p-1 rounded text-muted-foreground hover:text-blue-400 transition-colors",title:"编辑",children:g.jsx(Vf,{className:"h-3.5 w-3.5"})}),g.jsx("button",{onClick:()=>void C(A.id),className:"p-1 rounded text-muted-foreground hover:text-red-400 transition-colors",title:"删除",children:g.jsx(wa,{className:"h-3.5 w-3.5"})})]})]},A.id))})]})}const f1=S.createContext({theme:"system",resolved:"dark",setTheme:()=>{}}),yw="cc_web_theme";function K2(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function X2(){return S.useSyncExternalStore(e=>{const t=window.matchMedia("(prefers-color-scheme: dark)");return t.addEventListener("change",e),()=>t.removeEventListener("change",e)},()=>K2())}function Z2({children:e}){const[t,n]=S.useState(()=>{try{return localStorage.getItem(yw)||"system"}catch{return"system"}}),r=X2(),i=t==="system"?r:t;S.useEffect(()=>{const s=document.documentElement;s.classList.remove("light","dark"),s.classList.add(i)},[i]);const a=s=>{n(s);try{localStorage.setItem(yw,s)}catch{}};return g.jsx(f1.Provider,{value:{theme:t,resolved:i,setTheme:a},children:e})}function Xf(){return S.useContext(f1)}function g1(){const{theme:e,setTheme:t}=Xf(),n=[{value:"light",icon:YL,label:"浅色"},{value:"dark",icon:$L,label:"深色"},{value:"system",icon:zL,label:"系统"}];return g.jsx("div",{className:"flex items-center rounded-md border border-border bg-muted/50 p-0.5",children:n.map(({value:r,icon:i,label:a})=>g.jsx("button",{onClick:()=>t(r),className:J("p-1 rounded-sm transition-colors",e===r?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:a,children:g.jsx(i,{className:"h-3.5 w-3.5"})},r))})}function Q2(){const e=ho(),[t,n]=S.useState([]),[r,i]=S.useState(!0),[a,s]=S.useState(null),[o,l]=S.useState(!1),[u,d]=S.useState(!1),[c,h]=S.useState(new Set),[p,f]=S.useState(!!document.fullscreenElement),[b,y]=S.useState(!1),m=()=>{document.fullscreenElement?document.exitFullscreen():document.documentElement.requestFullscreen()};S.useEffect(()=>{const T=()=>f(!!document.fullscreenElement);return document.addEventListener("fullscreenchange",T),()=>document.removeEventListener("fullscreenchange",T)},[]);const _=async()=>{try{const T=await wC();n(T)}catch(T){s(T instanceof Error?T.message:"Failed to load projects")}finally{i(!1)}};S.useEffect(()=>{_()},[]),S.useEffect(()=>{let N=null;const M=async()=>{if(!document.hidden)try{const D=await fL(),$=Date.now(),x=new Set(Object.entries(D).filter(([,V])=>typeof V=="number"&&$-V<2e3).map(([V])=>V));h(x)}catch{}},F=()=>{M(),N=setInterval(()=>void M(),2e3)},z=()=>{N&&(clearInterval(N),N=null)},j=()=>{document.hidden?z():F()};return F(),document.addEventListener("visibilitychange",j),()=>{z(),document.removeEventListener("visibilitychange",j)}},[]);const v=()=>{vC(),e("/login")},w=T=>{n(N=>[...N,T])},C=T=>{n(N=>[...N,T])},k=async T=>{try{await uL(T),n(N=>N.filter(M=>M.id!==T))}catch(N){alert(N instanceof Error?N.message:"Failed to delete project")}},A=async T=>{try{const N=await hL(T);n(M=>M.map(F=>F.id===T?N:F))}catch(N){alert(N instanceof Error?N.message:"Failed to archive project")}},O=async T=>{try{const N=await pL(T);n(M=>M.map(F=>F.id===T?N:F))}catch(N){alert(N instanceof Error?N.message:"Failed to restore project")}},P=t.filter(T=>!T.archived),I=t.filter(T=>T.archived),L={onDelete:T=>void k(T),onArchive:T=>void A(T),onUnarchive:T=>void O(T)};return g.jsxs("div",{className:"min-h-screen bg-background",children:[g.jsx("header",{className:"border-b sticky top-0 bg-background z-10",children:g.jsxs("div",{className:"max-w-6xl mx-auto px-4 h-14 flex items-center justify-between",children:[g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(rw,{className:"h-5 w-5"}),g.jsx("span",{className:"font-semibold text-lg",children:"CC Web"})]}),g.jsx(p1,{}),g.jsx(q2,{}),g.jsx(se,{variant:"ghost",size:"sm",onClick:m,title:p?"Exit fullscreen":"Fullscreen",children:p?g.jsx(Wf,{className:"h-4 w-4"}):g.jsx(Gf,{className:"h-4 w-4"})}),g.jsx(g1,{}),g.jsxs(se,{variant:"ghost",size:"sm",onClick:v,children:[g.jsx(BL,{className:"h-4 w-4 mr-2"}),"Logout"]})]})}),g.jsxs("main",{className:"max-w-6xl mx-auto px-4 py-8",children:[g.jsxs("div",{className:"flex items-center justify-between mb-6",children:[g.jsxs("div",{children:[g.jsx("h1",{className:"text-2xl font-bold",children:"Projects"}),g.jsx("p",{className:"text-muted-foreground text-sm mt-1",children:"Each project runs Claude CLI in a dedicated terminal session."})]}),g.jsxs("div",{className:"flex gap-2",children:[g.jsxs(se,{variant:"outline",onClick:()=>d(!0),children:[g.jsx(Gs,{className:"h-4 w-4 mr-2"}),"Open Project"]}),g.jsxs(se,{onClick:()=>l(!0),children:[g.jsx(du,{className:"h-4 w-4 mr-2"}),"New Project"]})]})]}),r&&g.jsx("div",{className:"text-center text-muted-foreground py-12",children:"Loading projects..."}),a&&g.jsx("div",{className:"text-center text-destructive py-12",children:a}),!r&&!a&&t.length===0&&g.jsxs("div",{className:"text-center py-20",children:[g.jsx(rw,{className:"h-12 w-12 text-muted-foreground mx-auto mb-4"}),g.jsx("h2",{className:"text-lg font-semibold mb-2",children:"No projects yet"}),g.jsx("p",{className:"text-muted-foreground text-sm mb-6",children:"Create a new project or open an existing one."}),g.jsxs("div",{className:"flex gap-2 justify-center",children:[g.jsxs(se,{variant:"outline",onClick:()=>d(!0),children:[g.jsx(Gs,{className:"h-4 w-4 mr-2"}),"Open Project"]}),g.jsxs(se,{onClick:()=>l(!0),children:[g.jsx(du,{className:"h-4 w-4 mr-2"}),"New Project"]})]})]}),!r&&!a&&P.length>0&&g.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",children:P.map(T=>g.jsx(iw,{project:T,active:c.has(T.id),...L},T.id))}),!r&&!a&&I.length>0&&g.jsxs("div",{className:"mt-10",children:[g.jsxs("button",{className:"flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors mb-4 group",onClick:()=>y(T=>!T),children:[b?g.jsx(AC,{className:"h-4 w-4"}):g.jsx(Hf,{className:"h-4 w-4"}),g.jsx("span",{className:"font-medium",children:"Archived"}),g.jsx("span",{className:"text-xs bg-muted rounded-full px-2 py-0.5",children:I.length})]}),b&&g.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",children:I.map(T=>g.jsx(iw,{project:T,active:!1,...L},T.id))})]}),g.jsx(Y2,{})]}),g.jsx(H2,{open:o,onOpenChange:l,onCreated:w}),g.jsx(G2,{open:u,onOpenChange:d,onOpened:C})]})}/**
|
|
341
|
+
For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return S.useEffect(()=>{e&&(document.getElementById(e)||console.error(n))},[n,e]),null},F2="DialogDescriptionWarning",P2=({contentRef:e,descriptionId:t})=>{const r=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${s1(F2).contentName}}.`;return S.useEffect(()=>{var a;const i=(a=e.current)==null?void 0:a.getAttribute("aria-describedby");t&&i&&(document.getElementById(t)||console.warn(r))},[r,e,t]),null},B2=qC,U2=XC,o1=ZC,l1=QC,u1=e1,c1=n1,z2=i1;const Xu=B2,$2=U2,d1=S.forwardRef(({className:e,...t},n)=>g.jsx(o1,{ref:n,className:J("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...t}));d1.displayName=o1.displayName;const po=S.forwardRef(({className:e,children:t,...n},r)=>g.jsxs($2,{children:[g.jsx(d1,{}),g.jsxs(l1,{ref:r,className:J("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",e),...n,children:[t,g.jsxs(z2,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[g.jsx(wa,{className:"h-4 w-4"}),g.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));po.displayName=l1.displayName;const fo=({className:e,...t})=>g.jsx("div",{className:J("flex flex-col space-y-1.5 text-center sm:text-left",e),...t});fo.displayName="DialogHeader";const go=({className:e,...t})=>g.jsx("div",{className:J("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",e),...t});go.displayName="DialogFooter";const mo=S.forwardRef(({className:e,...t},n)=>g.jsx(u1,{ref:n,className:J("text-lg font-semibold leading-none tracking-tight",e),...t}));mo.displayName=u1.displayName;const bo=S.forwardRef(({className:e,...t},n)=>g.jsx(c1,{ref:n,className:J("text-sm text-muted-foreground",e),...t}));bo.displayName=c1.displayName;function h1({onSelect:e}){const[t,n]=S.useState(""),[r,i]=S.useState(null),[a,s]=S.useState([]),[o,l]=S.useState(!0),[u,d]=S.useState(null),[c,h]=S.useState(!1),[p,f]=S.useState(""),[b,y]=S.useState(null),[m,_]=S.useState(!1),v=S.useRef(null),w=async L=>{l(!0),d(null);try{const T=await kC(L);n(T.path),i(T.parent),s(T.entries)}catch(T){d(T instanceof Error?T.message:"Failed to load directory")}finally{l(!1)}};S.useEffect(()=>{w()},[]),S.useEffect(()=>{c&&setTimeout(()=>{var L;return(L=v.current)==null?void 0:L.focus()},0)},[c]);const C=()=>{f(""),y(null),h(!0)},k=()=>{h(!1),f(""),y(null)},A=async()=>{const L=p.trim();if(L){_(!0),y(null);try{const{path:T}=await vL(t,L);h(!1),f(""),await w(t),w(T)}catch(T){y(T instanceof Error?T.message:"Failed to create folder")}finally{_(!1)}}},O=L=>{L.key==="Enter"?(L.preventDefault(),A()):L.key==="Escape"&&k()},P=t.split("/").filter(Boolean),I=L=>{const T="/"+P.slice(0,L+1).join("/");w(T)};return g.jsxs("div",{className:"flex flex-col h-64 border rounded-md overflow-hidden",children:[g.jsxs("div",{className:"flex items-center gap-1 px-2 py-2 bg-muted border-b flex-shrink-0",children:[g.jsx(se,{variant:"ghost",size:"sm",className:"h-6 px-1 flex-shrink-0",onClick:()=>void w(),title:"Home",children:g.jsx(PL,{className:"h-3 w-3"})}),g.jsx("div",{className:"flex items-center gap-1 flex-1 overflow-x-auto min-w-0",children:P.map((L,T)=>g.jsxs(vn.Fragment,{children:[g.jsx(Hf,{className:"h-3 w-3 text-muted-foreground flex-shrink-0"}),g.jsx("button",{className:"text-xs hover:text-foreground text-muted-foreground whitespace-nowrap",onClick:()=>I(T),children:L})]},T))}),g.jsxs(se,{variant:"ghost",size:"sm",className:"h-6 px-1.5 flex-shrink-0 gap-1 text-xs",onClick:C,disabled:c||o||!!u,title:"New folder",children:[g.jsx(FL,{className:"h-3.5 w-3.5"}),g.jsx("span",{className:"hidden sm:inline",children:"New folder"})]})]}),g.jsxs("div",{className:"flex-1 overflow-y-auto",children:[o&&g.jsx("div",{className:"flex items-center justify-center h-full text-sm text-muted-foreground",children:"Loading..."}),u&&g.jsx("div",{className:"flex items-center justify-center h-full text-sm text-destructive px-4 text-center",children:u}),!o&&!u&&g.jsxs("div",{className:"p-1",children:[r&&g.jsxs("button",{className:"flex items-center gap-2 w-full px-2 py-1.5 text-sm rounded hover:bg-accent hover:text-accent-foreground",onClick:()=>void w(r),children:[g.jsx(Rh,{className:"h-4 w-4 text-muted-foreground"}),g.jsx("span",{children:".."})]}),c&&g.jsxs("div",{className:"flex items-center gap-1 px-2 py-1.5",children:[g.jsx(Ih,{className:"h-4 w-4 text-blue-500 flex-shrink-0"}),g.jsx("input",{ref:v,className:J("flex-1 text-sm bg-background border rounded px-1.5 py-0.5 outline-none","focus:ring-1 focus:ring-ring",b&&"border-destructive"),placeholder:"Folder name",value:p,onChange:L=>{f(L.target.value),y(null)},onKeyDown:O,disabled:m}),g.jsx("button",{className:"p-1 rounded hover:bg-accent disabled:opacity-50",onClick:()=>void A(),disabled:!p.trim()||m,title:"Create",children:g.jsx(IL,{className:"h-3.5 w-3.5 text-green-600"})}),g.jsx("button",{className:"p-1 rounded hover:bg-accent",onClick:k,disabled:m,title:"Cancel",children:g.jsx(wa,{className:"h-3.5 w-3.5 text-muted-foreground"})})]}),b&&g.jsx("p",{className:"px-3 pb-1 text-xs text-destructive",children:b}),a.length===0&&!c&&g.jsx("div",{className:"text-sm text-muted-foreground px-2 py-4 text-center",children:"Empty directory"}),a.map(L=>g.jsxs("button",{className:J("flex items-center gap-2 w-full px-2 py-1.5 text-sm rounded text-left",L.type==="dir"?"hover:bg-accent hover:text-accent-foreground cursor-pointer":"opacity-40 cursor-not-allowed"),onClick:()=>{L.type==="dir"&&w(L.path)},disabled:L.type==="file",children:[L.type==="dir"?g.jsx(Ih,{className:"h-4 w-4 text-blue-500 flex-shrink-0"}):g.jsx(ML,{className:"h-4 w-4 text-muted-foreground flex-shrink-0"}),g.jsx("span",{className:"truncate",children:L.name})]},L.path))]})]}),g.jsxs("div",{className:"border-t px-3 py-2 flex items-center justify-between gap-2 flex-shrink-0 bg-background",children:[g.jsx("span",{className:"text-xs text-muted-foreground truncate flex-1",children:t}),g.jsx(se,{size:"sm",onClick:()=>e(t),disabled:!t,children:"Select this folder"})]})]})}const j2=[{value:"claude",label:"Claude",desc:"Anthropic Claude Code CLI"},{value:"opencode",label:"OpenCode",desc:"OpenCode CLI (sst/opencode)"},{value:"codex",label:"Codex",desc:"OpenAI Codex CLI"},{value:"qwen",label:"Qwen",desc:"Qwen Code CLI (QwenLM)"}],bw={claude:{limited:"claude",unlimited:"claude --dangerously-skip-permissions"},opencode:{limited:"opencode",unlimited:"opencode --dangerously-skip-permissions"},codex:{limited:"codex",unlimited:"codex --ask-for-approval never --sandbox danger-full-access"},qwen:{limited:"qwen-code",unlimited:"qwen-code --yolo"}};function H2({open:e,onOpenChange:t,onCreated:n}){const[r,i]=S.useState("name"),[a,s]=S.useState(""),[o,l]=S.useState(""),[u,d]=S.useState("claude"),[c,h]=S.useState("limited"),[p,f]=S.useState(!1),[b,y]=S.useState(null),m=()=>{i("name"),s(""),l(""),d("claude"),h("limited"),y(null),f(!1)},_=O=>{O||m(),t(O)},v=()=>{if(!a.trim()){y("Please enter a project name");return}y(null),i("folder")},w=O=>{l(O),i("settings")},C=async()=>{f(!0),y(null);try{const O=await oL({name:a.trim(),folderPath:o,permissionMode:c,cliTool:u});n(O),_(!1)}catch(O){y(O instanceof Error?O.message:"Failed to create project")}finally{f(!1)}},k={name:"New Project — Name",folder:"New Project — Select Folder",settings:"New Project — Settings"},A=["name","folder","settings"];return g.jsx(Xu,{open:e,onOpenChange:_,children:g.jsxs(po,{className:"sm:max-w-lg",children:[g.jsxs(fo,{children:[g.jsx(mo,{children:k[r]}),g.jsxs(bo,{children:[r==="name"&&"Give your project a name.",r==="folder"&&"Choose the working directory for this project.",r==="settings"&&"Choose the AI coding tool and run mode."]})]}),g.jsx("div",{className:"flex gap-2 mb-2",children:A.map((O,P)=>g.jsx("div",{className:`h-1.5 flex-1 rounded-full ${r===O?"bg-primary":A.indexOf(r)>P?"bg-primary/40":"bg-muted"}`},O))}),r==="name"&&g.jsxs("div",{className:"space-y-4",children:[g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{htmlFor:"project-name",children:"Project Name"}),g.jsx(Hs,{id:"project-name",placeholder:"My Project",value:a,onChange:O=>s(O.target.value),onKeyDown:O=>{O.key==="Enter"&&v()},autoFocus:!0})]}),b&&g.jsx("p",{className:"text-sm text-destructive",children:b})]}),r==="folder"&&g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{children:"Working Directory"}),g.jsx(h1,{onSelect:w})]}),r==="settings"&&g.jsxs("div",{className:"space-y-5",children:[g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{children:"AI Coding Tool"}),g.jsx("div",{className:"grid grid-cols-2 gap-2",children:j2.map(O=>g.jsxs("label",{className:`flex items-center gap-2.5 cursor-pointer p-3 rounded-md border transition-colors ${u===O.value?"border-primary bg-primary/5":"hover:bg-accent"}`,children:[g.jsx("input",{type:"radio",name:"cliTool",value:O.value,checked:u===O.value,onChange:()=>d(O.value),className:"accent-primary"}),g.jsxs("div",{children:[g.jsx("div",{className:"font-medium text-sm",children:O.label}),g.jsx("div",{className:"text-xs text-muted-foreground",children:O.desc})]})]},O.value))})]}),g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{children:"Permission Mode"}),g.jsxs("div",{className:"space-y-2",children:[g.jsxs("label",{className:"flex items-start gap-3 cursor-pointer p-3 rounded-md border hover:bg-accent transition-colors",children:[g.jsx("input",{type:"radio",name:"permissionMode",value:"limited",checked:c==="limited",onChange:()=>h("limited"),className:"mt-0.5"}),g.jsxs("div",{children:[g.jsx("div",{className:"font-medium text-sm",children:"Limited"}),g.jsxs("div",{className:"text-xs text-muted-foreground",children:["Runs ",g.jsx("code",{className:"bg-muted px-1 rounded",children:bw[u].limited})," — asks for permission before file changes."]})]})]}),g.jsxs("label",{className:"flex items-start gap-3 cursor-pointer p-3 rounded-md border hover:bg-accent transition-colors",children:[g.jsx("input",{type:"radio",name:"permissionMode",value:"unlimited",checked:c==="unlimited",onChange:()=>h("unlimited"),className:"mt-0.5"}),g.jsxs("div",{children:[g.jsx("div",{className:"font-medium text-sm",children:"Unlimited"}),g.jsxs("div",{className:"text-xs text-muted-foreground",children:["Runs ",g.jsx("code",{className:"bg-muted px-1 rounded",children:bw[u].unlimited})," — acts autonomously."]})]})]})]})]}),g.jsxs("div",{className:"text-xs text-muted-foreground",children:[g.jsx("span",{className:"font-medium",children:"Folder:"})," ",g.jsx("span",{className:"font-mono",children:o})]}),b&&g.jsx("p",{className:"text-sm text-destructive",children:b})]}),g.jsxs(go,{children:[r!=="name"&&g.jsx(se,{variant:"outline",onClick:()=>i(r==="settings"?"folder":"name"),disabled:p,children:"Back"}),r==="name"&&g.jsx(se,{onClick:v,children:"Next"}),r==="folder"&&g.jsx(se,{variant:"outline",onClick:()=>t(!1),children:"Cancel"}),r==="settings"&&g.jsx(se,{onClick:()=>void C(),disabled:p,children:p?"Creating...":"Create Project"})]})]})})}function G2({open:e,onOpenChange:t,onOpened:n}){const[r,i]=S.useState(""),[a,s]=S.useState(!1),[o,l]=S.useState(null),u=()=>{i(""),l(null),s(!1)},d=h=>{h||u(),t(h)},c=async h=>{i(h),s(!0),l(null);try{const p=await lL(h);n(p),d(!1)}catch(p){l(p instanceof Error?p.message:"Failed to open project"),s(!1)}};return g.jsx(Xu,{open:e,onOpenChange:d,children:g.jsxs(po,{className:"sm:max-w-lg",children:[g.jsxs(fo,{children:[g.jsx(mo,{children:"Open Existing Project"}),g.jsxs(bo,{children:["Select a folder that contains a ",g.jsx("code",{className:"bg-muted px-1 rounded text-xs",children:".ccweb/"})," configuration. The project's history and settings will be restored."]})]}),g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{children:"Project Folder"}),g.jsx(h1,{onSelect:h=>void c(h)})]}),o&&g.jsx("p",{className:"text-sm text-destructive",children:o}),r&&!o&&a&&g.jsxs("p",{className:"text-sm text-muted-foreground",children:["Opening project from ",r,"..."]}),g.jsx(go,{children:g.jsx(se,{variant:"outline",onClick:()=>d(!1),disabled:a,children:"Cancel"})})]})})}function W2(e){if(!e)return"";const t=new Date(e).getTime()-Date.now();if(t<=0)return"即将重置";const n=Math.floor(t/36e5),r=Math.floor(t%36e5/6e4);return n>0?`${n}h${r}m`:`${r}m`}function Jo({label:e,bucket:t}){if(!t||t.utilization===void 0)return null;const n=t.utilization,r=n<50?"text-green-400":n<80?"text-yellow-400":"text-red-400",i=W2(t.resetAt);return g.jsxs("span",{className:"text-muted-foreground whitespace-nowrap",children:[e," ",g.jsxs("span",{className:J("font-medium",r),children:[n,"%"]}),i&&g.jsxs("span",{className:"text-muted-foreground/70 ml-0.5",children:["(",i,")"]})]})}function p1({className:e}){const[t,n]=S.useState("loading"),[r,i]=S.useState(!1);S.useEffect(()=>{const c=async()=>{try{n(await _L())}catch{n(null)}};c();const h=setInterval(()=>void c(),5*60*1e3);return()=>clearInterval(h)},[]);const a=async()=>{i(!0);try{n(await yL())}catch{n(null)}finally{i(!1)}};if(t==="loading"||!t)return null;const s=!!t.fiveHour,o=!!t.sevenDay,l=!!t.sevenDaySonnet,u=!!t.sevenDayOpus,d=s||o||l||u;return g.jsxs("div",{className:J("flex items-center gap-1.5 text-xs",e),children:[t.planName&&g.jsx("span",{className:"font-medium text-foreground bg-muted border border-border px-2 py-0.5 rounded-full",children:t.planName}),d&&g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"text-muted-foreground/50",children:"|"}),g.jsx(Jo,{label:"5h",bucket:t.fiveHour}),o&&g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"text-muted-foreground/50",children:"·"}),g.jsx(Jo,{label:"7d",bucket:t.sevenDay})]}),l&&g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"text-muted-foreground/50",children:"·"}),g.jsx(Jo,{label:"7d Sonnet",bucket:t.sevenDaySonnet})]}),u&&g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"text-muted-foreground/50",children:"·"}),g.jsx(Jo,{label:"7d Opus",bucket:t.sevenDayOpus})]})]}),g.jsx("button",{onClick:()=>void a(),className:"text-muted-foreground hover:text-foreground transition-colors",title:"刷新用量信息",children:g.jsx(Ws,{className:J("h-3 w-3",r&&"animate-spin")})})]})}const _w="v1.5.11",el=!!window.electronUpdater;function V2(e,t){const n=e.split(".").map(Number),r=t.split(".").map(Number);for(let i=0;i<Math.max(n.length,r.length);i++){const a=n[i]||0,s=r[i]||0;if(a!==s)return a-s}return 0}function q2(){const[e,t]=S.useState("idle"),[n,r]=S.useState(!1),[i,a]=S.useState(""),[s,o]=S.useState(0),[l,u]=S.useState([]),[d,c]=S.useState([]),[h,p]=S.useState(null),[f,b]=S.useState(null);S.useEffect(()=>window.electronUpdater?window.electronUpdater.onUpdateStatus(k=>{switch(k.type){case"progress":{const A=k.info;o(Math.round((A==null?void 0:A.percent)??0));break}case"downloaded":t("downloaded");break;case"error":p(k.info||"Download failed"),t("error");break}}):void 0,[]);const y=S.useCallback(async()=>{t("checking"),p(null),r(!0);try{if(el){const k=await window.electronUpdater.checkForUpdate();if(k.error)throw new Error(k.error);if(!k.available){t("no_update");return}a(k.version?`v${k.version}`:"new version")}else{const k=await fetch("https://api.github.com/repos/zbc0315/cc-web/releases/latest");if(k.status===404){t("no_update");return}if(!k.ok)throw new Error(`GitHub API ${k.status}`);const A=await k.json(),O=A.tag_name.replace(/^v/,""),P=_w.replace(/^v/,"");if(V2(O,P)<=0){t("no_update");return}a(A.tag_name)}const C=await wL();u(C.projects),t(C.runningCount>0?"confirm_prepare":"update_available")}catch(C){p(C instanceof Error?C.message:"Check failed"),t("error")}},[]),m=async()=>{t("preparing");try{const C=await EL();c(C.results),t("update_available")}catch(C){p(C instanceof Error?C.message:"Prepare failed"),t("error")}},_=async()=>{if(el){t("downloading"),o(0);const C=await window.electronUpdater.downloadUpdate();C.success?C.path&&b(C.path):(p(C.error||"Download failed"),t("error"))}else window.open("https://github.com/zbc0315/cc-web/releases/latest","_blank")},v=()=>{var C;(C=window.electronUpdater)==null||C.quitAndInstall(f||void 0)},w=()=>{r(!1),setTimeout(()=>{t("idle"),a(""),u([]),c([]),p(null),o(0)},200)};return g.jsxs(g.Fragment,{children:[g.jsxs(se,{variant:"ghost",size:"sm",onClick:()=>void y(),disabled:e==="checking"||e==="preparing"||e==="downloading",children:[e==="checking"||e==="preparing"||e==="downloading"?g.jsx(Oh,{className:"h-4 w-4 mr-2 animate-spin"}):g.jsx(LL,{className:"h-4 w-4 mr-2"}),"Update"]}),g.jsx(Xu,{open:n,onOpenChange:C=>{C||w()},children:g.jsxs(po,{className:"sm:max-w-md",children:[g.jsxs(fo,{children:[g.jsxs(mo,{children:[e==="checking"&&"Checking for updates...",e==="no_update"&&"Up to date",e==="update_available"&&`Update ${i} available`,e==="confirm_prepare"&&"Save project memory first",e==="preparing"&&"Saving project memory...",e==="downloading"&&"Downloading update...",e==="downloaded"&&"Update ready to install",e==="error"&&"Update error"]}),g.jsxs(bo,{children:[e==="checking"&&"Checking for the latest version...",e==="no_update"&&`Current version ${_w} is the latest.`,e==="update_available"&&(d.length>0?"All projects saved and stopped. Ready to update.":`A new version is available. ${el?"Click download to update automatically.":""}`),e==="confirm_prepare"&&`${l.length} project(s) running. Each Claude will be asked to save memory, then terminals will stop.`,e==="preparing"&&"Sending save commands and waiting for Claude to finish...",e==="downloading"&&`Downloading... ${s}%`,e==="downloaded"&&"The update has been downloaded. Click install to restart and apply.",e==="error"&&(h||"An error occurred.")]})]}),e==="downloading"&&g.jsx("div",{className:"w-full bg-muted rounded-full h-2 overflow-hidden",children:g.jsx("div",{className:"bg-primary h-full transition-all duration-300",style:{width:`${s}%`}})}),e==="confirm_prepare"&&l.length>0&&g.jsx("div",{className:"space-y-1 text-sm",children:l.map(C=>g.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 rounded bg-muted",children:[g.jsx("span",{className:"h-2 w-2 rounded-full bg-green-500 shrink-0"}),g.jsx("span",{className:"truncate",children:C.name})]},C.id))}),e==="preparing"&&g.jsx("div",{className:"flex items-center justify-center py-6",children:g.jsx(Oh,{className:"h-8 w-8 animate-spin text-muted-foreground"})}),e==="update_available"&&d.length>0&&g.jsx("div",{className:"space-y-1 text-sm",children:d.map(C=>g.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 rounded bg-muted",children:[C.status==="stopped"?g.jsx(RL,{className:"h-4 w-4 text-green-500 shrink-0"}):g.jsx(TL,{className:"h-4 w-4 text-yellow-500 shrink-0"}),g.jsx("span",{className:"truncate",children:C.name}),g.jsx("span",{className:"text-xs text-muted-foreground ml-auto shrink-0",children:C.message})]},C.id))}),g.jsxs(go,{children:[e==="no_update"&&g.jsx(se,{onClick:w,children:"OK"}),e==="update_available"&&g.jsxs(g.Fragment,{children:[g.jsx(se,{variant:"outline",onClick:w,children:"Later"}),g.jsx(se,{onClick:()=>void _(),children:el?"Download & Install":`Download ${i}`})]}),e==="confirm_prepare"&&g.jsxs(g.Fragment,{children:[g.jsx(se,{variant:"outline",onClick:w,children:"Cancel"}),g.jsx(se,{onClick:()=>void m(),children:"Save Memory & Stop All"})]}),e==="downloaded"&&g.jsxs(g.Fragment,{children:[g.jsx(se,{variant:"outline",onClick:w,children:"Later"}),g.jsx(se,{onClick:v,children:"Restart & Install"})]}),e==="error"&&g.jsx(se,{onClick:w,children:"Close"})]})]})})]})}function Y2(){const[e,t]=S.useState([]),[n,r]=S.useState(!1),[i,a]=S.useState(""),[s,o]=S.useState(""),[l,u]=S.useState(""),[d,c]=S.useState(null),[h,p]=S.useState(""),[f,b]=S.useState(""),[y,m]=S.useState(""),_=S.useRef(null),v=S.useRef(null);S.useEffect(()=>{EC().then(t).catch(()=>t([]))},[]),S.useEffect(()=>{n&&setTimeout(()=>{var A;return(A=_.current)==null?void 0:A.focus()},0)},[n]),S.useEffect(()=>{d&&setTimeout(()=>{var A;return(A=v.current)==null?void 0:A.focus()},0)},[d]);const w=async()=>{const A=s.trim();if(A)try{const O=await gL({label:i.trim()||A,command:A,...l?{parentId:l}:{}});t(P=>[...P,O]),a(""),o(""),u(""),r(!1)}catch(O){console.error("[GlobalShortcuts] Failed to add:",O)}},C=async A=>{try{await bL(A),t(O=>O.filter(P=>P.id!==A)),d===A&&c(null)}catch(O){console.error("[GlobalShortcuts] Failed to delete:",O)}},k=async()=>{const A=f.trim();if(!(!A||!d))try{const O=await mL(d,{label:h.trim()||A,command:A,parentId:y||null});t(P=>P.map(I=>I.id===d?O:I)),c(null)}catch(O){console.error("[GlobalShortcuts] Failed to save:",O)}};return g.jsxs("section",{className:"mt-10",children:[g.jsxs("div",{className:"flex items-center justify-between mb-4",children:[g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(hu,{className:"h-4 w-4 text-muted-foreground"}),g.jsx("h2",{className:"text-lg font-semibold",children:"全局快捷命令"}),g.jsx("span",{className:"text-xs text-muted-foreground",children:"在所有项目的终端中可用"})]}),g.jsxs("button",{onClick:()=>{r(A=>!A),c(null)},className:J("flex items-center gap-1.5 text-sm px-3 py-1.5 rounded-md border transition-colors",n?"border-border text-foreground bg-muted":"border-border text-muted-foreground hover:text-foreground hover:bg-muted"),children:[g.jsx(du,{className:"h-3.5 w-3.5"}),"新建"]})]}),n&&g.jsxs("div",{className:"mb-4 p-4 rounded-lg border border-border bg-background space-y-3",children:[g.jsx("input",{ref:_,placeholder:"名称(可选)",value:i,onChange:A=>a(A.target.value),className:"w-full text-sm bg-muted border border-border rounded px-3 py-1.5 text-foreground placeholder:text-muted-foreground outline-none focus:border-border transition-colors"}),g.jsx("textarea",{placeholder:"命令内容…",value:s,onChange:A=>o(A.target.value),rows:3,className:"w-full text-sm bg-muted border border-border rounded px-3 py-1.5 text-foreground placeholder:text-muted-foreground font-mono outline-none focus:border-border transition-colors resize-none",onKeyDown:A=>{A.key==="Enter"&&(A.metaKey||A.ctrlKey)&&(A.preventDefault(),w()),A.key==="Escape"&&(r(!1),a(""),o(""),u(""))}}),g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(xl,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),g.jsxs("select",{value:l,onChange:A=>u(A.target.value),className:"flex-1 text-sm bg-muted border border-border rounded px-3 py-1.5 text-foreground outline-none focus:border-border transition-colors",children:[g.jsx("option",{value:"",children:"无继承"}),e.map(A=>g.jsx("option",{value:A.id,children:A.label},A.id))]})]}),g.jsxs("div",{className:"flex items-center justify-between",children:[g.jsx("span",{className:"text-xs text-muted-foreground",children:"⌘↩ 保存 · Esc 取消"}),g.jsxs("div",{className:"flex gap-2",children:[g.jsx("button",{onClick:()=>{r(!1),a(""),o("")},className:"text-sm px-3 py-1 rounded bg-secondary hover:bg-accent text-foreground transition-colors",children:"取消"}),g.jsx("button",{onClick:()=>void w(),disabled:!s.trim(),className:J("text-sm px-3 py-1 rounded transition-colors text-white",s.trim()?"bg-blue-600 hover:bg-blue-500":"bg-secondary opacity-40 cursor-not-allowed"),children:"保存"})]})]})]}),e.length===0&&!n?g.jsxs("div",{className:"flex flex-col items-center gap-2 py-10 text-muted-foreground/50 border border-dashed border-border rounded-lg",children:[g.jsx(hu,{className:"h-6 w-6"}),g.jsx("p",{className:"text-sm",children:"还没有全局快捷命令"})]}):g.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",children:e.map(A=>d===A.id?g.jsxs("div",{className:"rounded-lg border border-border bg-background p-3 space-y-2",children:[g.jsx("input",{ref:v,value:h,onChange:O=>p(O.target.value),placeholder:"名称(可选)",className:"w-full text-sm bg-muted border border-border rounded px-2.5 py-1 text-foreground placeholder:text-muted-foreground outline-none focus:border-border transition-colors"}),g.jsx("textarea",{value:f,onChange:O=>b(O.target.value),rows:3,className:"w-full text-sm bg-muted border border-border rounded px-2.5 py-1 text-foreground font-mono outline-none focus:border-border transition-colors resize-none",onKeyDown:O=>{O.key==="Enter"&&(O.metaKey||O.ctrlKey)&&(O.preventDefault(),k()),O.key==="Escape"&&c(null)}}),g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(xl,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),g.jsxs("select",{value:y,onChange:O=>m(O.target.value),className:"flex-1 text-sm bg-muted border border-border rounded px-2.5 py-1 text-foreground outline-none focus:border-border transition-colors",children:[g.jsx("option",{value:"",children:"无继承"}),e.filter(O=>O.id!==A.id).map(O=>g.jsx("option",{value:O.id,children:O.label},O.id))]})]}),g.jsxs("div",{className:"flex gap-2 justify-end",children:[g.jsx("button",{onClick:()=>c(null),className:"text-xs px-2.5 py-1 rounded bg-secondary hover:bg-accent text-foreground transition-colors",children:"取消"}),g.jsx("button",{onClick:()=>void k(),disabled:!f.trim(),className:J("text-xs px-2.5 py-1 rounded transition-colors text-white",f.trim()?"bg-blue-600 hover:bg-blue-500":"bg-secondary opacity-40 cursor-not-allowed"),children:"保存"})]})]},A.id):g.jsxs("div",{className:"group relative rounded-lg border border-border bg-background hover:border-muted-foreground/30 transition-colors p-3",children:[g.jsx("div",{className:"text-sm font-medium text-foreground truncate pr-14",children:A.label}),A.parentId&&(()=>{const O=e.find(P=>P.id===A.parentId);return O?g.jsxs("div",{className:"flex items-center gap-1 mt-1",children:[g.jsx(xl,{className:"h-3 w-3 text-muted-foreground"}),g.jsxs("span",{className:"text-xs text-muted-foreground truncate",children:["继承: ",O.label]})]}):null})(),!A.parentId&&A.label!==A.command&&g.jsx("div",{className:"text-xs text-muted-foreground font-mono truncate mt-1 pr-14",children:A.command}),g.jsxs("div",{className:"absolute top-2.5 right-2.5 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity",children:[g.jsx("button",{onClick:()=>{c(A.id),p(A.label),b(A.command),m(A.parentId||""),r(!1)},className:"p-1 rounded text-muted-foreground hover:text-blue-400 transition-colors",title:"编辑",children:g.jsx(Vf,{className:"h-3.5 w-3.5"})}),g.jsx("button",{onClick:()=>void C(A.id),className:"p-1 rounded text-muted-foreground hover:text-red-400 transition-colors",title:"删除",children:g.jsx(wa,{className:"h-3.5 w-3.5"})})]})]},A.id))})]})}const f1=S.createContext({theme:"system",resolved:"dark",setTheme:()=>{}}),yw="cc_web_theme";function K2(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function X2(){return S.useSyncExternalStore(e=>{const t=window.matchMedia("(prefers-color-scheme: dark)");return t.addEventListener("change",e),()=>t.removeEventListener("change",e)},()=>K2())}function Z2({children:e}){const[t,n]=S.useState(()=>{try{return localStorage.getItem(yw)||"system"}catch{return"system"}}),r=X2(),i=t==="system"?r:t;S.useEffect(()=>{const s=document.documentElement;s.classList.remove("light","dark"),s.classList.add(i)},[i]);const a=s=>{n(s);try{localStorage.setItem(yw,s)}catch{}};return g.jsx(f1.Provider,{value:{theme:t,resolved:i,setTheme:a},children:e})}function Xf(){return S.useContext(f1)}function g1(){const{theme:e,setTheme:t}=Xf(),n=[{value:"light",icon:YL,label:"浅色"},{value:"dark",icon:$L,label:"深色"},{value:"system",icon:zL,label:"系统"}];return g.jsx("div",{className:"flex items-center rounded-md border border-border bg-muted/50 p-0.5",children:n.map(({value:r,icon:i,label:a})=>g.jsx("button",{onClick:()=>t(r),className:J("p-1 rounded-sm transition-colors",e===r?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:a,children:g.jsx(i,{className:"h-3.5 w-3.5"})},r))})}function Q2(){const e=ho(),[t,n]=S.useState([]),[r,i]=S.useState(!0),[a,s]=S.useState(null),[o,l]=S.useState(!1),[u,d]=S.useState(!1),[c,h]=S.useState(new Set),[p,f]=S.useState(!!document.fullscreenElement),[b,y]=S.useState(!1),m=()=>{document.fullscreenElement?document.exitFullscreen():document.documentElement.requestFullscreen()};S.useEffect(()=>{const T=()=>f(!!document.fullscreenElement);return document.addEventListener("fullscreenchange",T),()=>document.removeEventListener("fullscreenchange",T)},[]);const _=async()=>{try{const T=await wC();n(T)}catch(T){s(T instanceof Error?T.message:"Failed to load projects")}finally{i(!1)}};S.useEffect(()=>{_()},[]),S.useEffect(()=>{let N=null;const M=async()=>{if(!document.hidden)try{const D=await fL(),$=Date.now(),x=new Set(Object.entries(D).filter(([,V])=>typeof V=="number"&&$-V<2e3).map(([V])=>V));h(x)}catch{}},F=()=>{M(),N=setInterval(()=>void M(),2e3)},z=()=>{N&&(clearInterval(N),N=null)},j=()=>{document.hidden?z():F()};return F(),document.addEventListener("visibilitychange",j),()=>{z(),document.removeEventListener("visibilitychange",j)}},[]);const v=()=>{vC(),e("/login")},w=T=>{n(N=>[...N,T])},C=T=>{n(N=>[...N,T])},k=async T=>{try{await uL(T),n(N=>N.filter(M=>M.id!==T))}catch(N){alert(N instanceof Error?N.message:"Failed to delete project")}},A=async T=>{try{const N=await hL(T);n(M=>M.map(F=>F.id===T?N:F))}catch(N){alert(N instanceof Error?N.message:"Failed to archive project")}},O=async T=>{try{const N=await pL(T);n(M=>M.map(F=>F.id===T?N:F))}catch(N){alert(N instanceof Error?N.message:"Failed to restore project")}},P=t.filter(T=>!T.archived),I=t.filter(T=>T.archived),L={onDelete:T=>void k(T),onArchive:T=>void A(T),onUnarchive:T=>void O(T)};return g.jsxs("div",{className:"min-h-screen bg-background",children:[g.jsx("header",{className:"border-b sticky top-0 bg-background z-10",children:g.jsxs("div",{className:"max-w-6xl mx-auto px-4 h-14 flex items-center justify-between",children:[g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(rw,{className:"h-5 w-5"}),g.jsx("span",{className:"font-semibold text-lg",children:"CC Web"})]}),g.jsx(p1,{}),g.jsx(q2,{}),g.jsx(se,{variant:"ghost",size:"sm",onClick:m,title:p?"Exit fullscreen":"Fullscreen",children:p?g.jsx(Wf,{className:"h-4 w-4"}):g.jsx(Gf,{className:"h-4 w-4"})}),g.jsx(g1,{}),g.jsxs(se,{variant:"ghost",size:"sm",onClick:v,children:[g.jsx(BL,{className:"h-4 w-4 mr-2"}),"Logout"]})]})}),g.jsxs("main",{className:"max-w-6xl mx-auto px-4 py-8",children:[g.jsxs("div",{className:"flex items-center justify-between mb-6",children:[g.jsxs("div",{children:[g.jsx("h1",{className:"text-2xl font-bold",children:"Projects"}),g.jsx("p",{className:"text-muted-foreground text-sm mt-1",children:"Each project runs Claude CLI in a dedicated terminal session."})]}),g.jsxs("div",{className:"flex gap-2",children:[g.jsxs(se,{variant:"outline",onClick:()=>d(!0),children:[g.jsx(Gs,{className:"h-4 w-4 mr-2"}),"Open Project"]}),g.jsxs(se,{onClick:()=>l(!0),children:[g.jsx(du,{className:"h-4 w-4 mr-2"}),"New Project"]})]})]}),r&&g.jsx("div",{className:"text-center text-muted-foreground py-12",children:"Loading projects..."}),a&&g.jsx("div",{className:"text-center text-destructive py-12",children:a}),!r&&!a&&t.length===0&&g.jsxs("div",{className:"text-center py-20",children:[g.jsx(rw,{className:"h-12 w-12 text-muted-foreground mx-auto mb-4"}),g.jsx("h2",{className:"text-lg font-semibold mb-2",children:"No projects yet"}),g.jsx("p",{className:"text-muted-foreground text-sm mb-6",children:"Create a new project or open an existing one."}),g.jsxs("div",{className:"flex gap-2 justify-center",children:[g.jsxs(se,{variant:"outline",onClick:()=>d(!0),children:[g.jsx(Gs,{className:"h-4 w-4 mr-2"}),"Open Project"]}),g.jsxs(se,{onClick:()=>l(!0),children:[g.jsx(du,{className:"h-4 w-4 mr-2"}),"New Project"]})]})]}),!r&&!a&&P.length>0&&g.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",children:P.map(T=>g.jsx(iw,{project:T,active:c.has(T.id),...L},T.id))}),!r&&!a&&I.length>0&&g.jsxs("div",{className:"mt-10",children:[g.jsxs("button",{className:"flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors mb-4 group",onClick:()=>y(T=>!T),children:[b?g.jsx(AC,{className:"h-4 w-4"}):g.jsx(Hf,{className:"h-4 w-4"}),g.jsx("span",{className:"font-medium",children:"Archived"}),g.jsx("span",{className:"text-xs bg-muted rounded-full px-2 py-0.5",children:I.length})]}),b&&g.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",children:I.map(T=>g.jsx(iw,{project:T,active:!1,...L},T.id))})]}),g.jsx(Y2,{})]}),g.jsx(H2,{open:o,onOpenChange:l,onCreated:w}),g.jsx(G2,{open:u,onOpenChange:d,onOpened:C})]})}/**
|
|
342
342
|
* Copyright (c) 2014-2024 The xterm.js authors. All rights reserved.
|
|
343
343
|
* @license MIT
|
|
344
344
|
*
|
|
@@ -427,7 +427,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
427
427
|
`,l+1)):l===0?a&&(e.result+=" "):e.result+=At.repeat(`
|
|
428
428
|
`,l):e.result+=At.repeat(`
|
|
429
429
|
`,a?1+l:l),a=!0,s=!0,l=0,n=e.position;!zn(c)&&c!==0;)c=e.input.charCodeAt(++e.position);Br(e,n,e.position,!1)}return!0}function Tk(e,t){var n,r=e.tag,i=e.anchor,a=[],s,o=!1,l;if(e.firstTabInLine!==-1)return!1;for(e.anchor!==null&&(e.anchorMap[e.anchor]=a),l=e.input.charCodeAt(e.position);l!==0&&(e.firstTabInLine!==-1&&(e.position=e.firstTabInLine,Z(e,"tab characters must not be used in indentation")),!(l!==45||(s=e.input.charCodeAt(e.position+1),!Bt(s))));){if(o=!0,e.position++,Ve(e,!0,-1)&&e.lineIndent<=t){a.push(null),l=e.input.charCodeAt(e.position);continue}if(n=e.line,ma(e,t,RA,!1,!0),a.push(e.result),Ve(e,!0,-1),l=e.input.charCodeAt(e.position),(e.line===n||e.lineIndent>t)&&l!==0)Z(e,"bad indentation of a sequence entry");else if(e.lineIndent<t)break}return o?(e.tag=r,e.anchor=i,e.kind="sequence",e.result=a,!0):!1}function RH(e,t,n){var r,i,a,s,o,l,u=e.tag,d=e.anchor,c={},h=Object.create(null),p=null,f=null,b=null,y=!1,m=!1,_;if(e.firstTabInLine!==-1)return!1;for(e.anchor!==null&&(e.anchorMap[e.anchor]=c),_=e.input.charCodeAt(e.position);_!==0;){if(!y&&e.firstTabInLine!==-1&&(e.position=e.firstTabInLine,Z(e,"tab characters must not be used in indentation")),r=e.input.charCodeAt(e.position+1),a=e.line,(_===63||_===58)&&Bt(r))_===63?(y&&(Zi(e,c,h,p,f,null,s,o,l),p=f=b=null),m=!0,y=!0,i=!0):y?(y=!1,i=!0):Z(e,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),e.position+=1,_=r;else{if(s=e.line,o=e.lineStart,l=e.position,!ma(e,n,NA,!1,!0))break;if(e.line===a){for(_=e.input.charCodeAt(e.position);ui(_);)_=e.input.charCodeAt(++e.position);if(_===58)_=e.input.charCodeAt(++e.position),Bt(_)||Z(e,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(Zi(e,c,h,p,f,null,s,o,l),p=f=b=null),m=!0,y=!1,i=!1,p=e.tag,f=e.result;else if(m)Z(e,"can not read an implicit mapping pair; a colon is missed");else return e.tag=u,e.anchor=d,!0}else if(m)Z(e,"can not read a block mapping entry; a multiline key may not be an implicit key");else return e.tag=u,e.anchor=d,!0}if((e.line===a||e.lineIndent>t)&&(y&&(s=e.line,o=e.lineStart,l=e.position),ma(e,t,xu,!0,i)&&(y?f=e.result:b=e.result),y||(Zi(e,c,h,p,f,b,s,o,l),p=f=b=null),Ve(e,!0,-1),_=e.input.charCodeAt(e.position)),(e.line===a||e.lineIndent>t)&&_!==0)Z(e,"bad indentation of a mapping entry");else if(e.lineIndent<t)break}return y&&Zi(e,c,h,p,f,null,s,o,l),m&&(e.tag=u,e.anchor=d,e.kind="mapping",e.result=c),m}function IH(e){var t,n=!1,r=!1,i,a,s;if(s=e.input.charCodeAt(e.position),s!==33)return!1;if(e.tag!==null&&Z(e,"duplication of a tag property"),s=e.input.charCodeAt(++e.position),s===60?(n=!0,s=e.input.charCodeAt(++e.position)):s===33?(r=!0,i="!!",s=e.input.charCodeAt(++e.position)):i="!",t=e.position,n){do s=e.input.charCodeAt(++e.position);while(s!==0&&s!==62);e.position<e.length?(a=e.input.slice(t,e.position),s=e.input.charCodeAt(++e.position)):Z(e,"unexpected end of the stream within a verbatim tag")}else{for(;s!==0&&!Bt(s);)s===33&&(r?Z(e,"tag suffix cannot contain exclamation marks"):(i=e.input.slice(t-1,e.position+1),IA.test(i)||Z(e,"named tag handle cannot contain such characters"),r=!0,t=e.position+1)),s=e.input.charCodeAt(++e.position);a=e.input.slice(t,e.position),yH.test(a)&&Z(e,"tag suffix cannot contain flow indicator characters")}a&&!OA.test(a)&&Z(e,"tag name cannot contain such characters: "+a);try{a=decodeURIComponent(a)}catch{Z(e,"tag name is malformed: "+a)}return n?e.tag=a:$r.call(e.tagMap,i)?e.tag=e.tagMap[i]+a:i==="!"?e.tag="!"+a:i==="!!"?e.tag="tag:yaml.org,2002:"+a:Z(e,'undeclared tag handle "'+i+'"'),!0}function OH(e){var t,n;if(n=e.input.charCodeAt(e.position),n!==38)return!1;for(e.anchor!==null&&Z(e,"duplication of an anchor property"),n=e.input.charCodeAt(++e.position),t=e.position;n!==0&&!Bt(n)&&!Xi(n);)n=e.input.charCodeAt(++e.position);return e.position===t&&Z(e,"name of an anchor node must contain at least one character"),e.anchor=e.input.slice(t,e.position),!0}function LH(e){var t,n,r;if(r=e.input.charCodeAt(e.position),r!==42)return!1;for(r=e.input.charCodeAt(++e.position),t=e.position;r!==0&&!Bt(r)&&!Xi(r);)r=e.input.charCodeAt(++e.position);return e.position===t&&Z(e,"name of an alias node must contain at least one character"),n=e.input.slice(t,e.position),$r.call(e.anchorMap,n)||Z(e,'unidentified alias "'+n+'"'),e.result=e.anchorMap[n],Ve(e,!0,-1),!0}function ma(e,t,n,r,i){var a,s,o,l=1,u=!1,d=!1,c,h,p,f,b,y;if(e.listener!==null&&e.listener("open",e),e.tag=null,e.anchor=null,e.kind=null,e.result=null,a=s=o=xu===n||RA===n,r&&Ve(e,!0,-1)&&(u=!0,e.lineIndent>t?l=1:e.lineIndent===t?l=0:e.lineIndent<t&&(l=-1)),l===1)for(;IH(e)||OH(e);)Ve(e,!0,-1)?(u=!0,o=a,e.lineIndent>t?l=1:e.lineIndent===t?l=0:e.lineIndent<t&&(l=-1)):o=!1;if(o&&(o=u||i),(l===1||xu===n)&&(ku===n||NA===n?b=t:b=t+1,y=e.position-e.lineStart,l===1?o&&(Tk(e,y)||RH(e,y,b))||AH(e,b)?d=!0:(s&&NH(e,b)||CH(e,b)||TH(e,b)?d=!0:LH(e)?(d=!0,(e.tag!==null||e.anchor!==null)&&Z(e,"alias node should not have any properties")):xH(e,b,ku===n)&&(d=!0,e.tag===null&&(e.tag="?")),e.anchor!==null&&(e.anchorMap[e.anchor]=e.result)):l===0&&(d=o&&Tk(e,y))),e.tag===null)e.anchor!==null&&(e.anchorMap[e.anchor]=e.result);else if(e.tag==="?"){for(e.result!==null&&e.kind!=="scalar"&&Z(e,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+e.kind+'"'),c=0,h=e.implicitTypes.length;c<h;c+=1)if(f=e.implicitTypes[c],f.resolve(e.result)){e.result=f.construct(e.result),e.tag=f.tag,e.anchor!==null&&(e.anchorMap[e.anchor]=e.result);break}}else if(e.tag!=="!"){if($r.call(e.typeMap[e.kind||"fallback"],e.tag))f=e.typeMap[e.kind||"fallback"][e.tag];else for(f=null,p=e.typeMap.multi[e.kind||"fallback"],c=0,h=p.length;c<h;c+=1)if(e.tag.slice(0,p[c].tag.length)===p[c].tag){f=p[c];break}f||Z(e,"unknown tag !<"+e.tag+">"),e.result!==null&&f.kind!==e.kind&&Z(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+f.kind+'", not "'+e.kind+'"'),f.resolve(e.result,e.tag)?(e.result=f.construct(e.result,e.tag),e.anchor!==null&&(e.anchorMap[e.anchor]=e.result)):Z(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")}return e.listener!==null&&e.listener("close",e),e.tag!==null||e.anchor!==null||d}function DH(e){var t=e.position,n,r,i,a=!1,s;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap=Object.create(null),e.anchorMap=Object.create(null);(s=e.input.charCodeAt(e.position))!==0&&(Ve(e,!0,-1),s=e.input.charCodeAt(e.position),!(e.lineIndent>0||s!==37));){for(a=!0,s=e.input.charCodeAt(++e.position),n=e.position;s!==0&&!Bt(s);)s=e.input.charCodeAt(++e.position);for(r=e.input.slice(n,e.position),i=[],r.length<1&&Z(e,"directive name must not be less than one character in length");s!==0;){for(;ui(s);)s=e.input.charCodeAt(++e.position);if(s===35){do s=e.input.charCodeAt(++e.position);while(s!==0&&!zn(s));break}if(zn(s))break;for(n=e.position;s!==0&&!Bt(s);)s=e.input.charCodeAt(++e.position);i.push(e.input.slice(n,e.position))}s!==0&&xv(e),$r.call(xk,r)?xk[r](e,r,i):Cu(e,'unknown document directive "'+r+'"')}if(Ve(e,!0,-1),e.lineIndent===0&&e.input.charCodeAt(e.position)===45&&e.input.charCodeAt(e.position+1)===45&&e.input.charCodeAt(e.position+2)===45?(e.position+=3,Ve(e,!0,-1)):a&&Z(e,"directives end mark is expected"),ma(e,e.lineIndent-1,xu,!1,!0),Ve(e,!0,-1),e.checkLineBreaks&&_H.test(e.input.slice(t,e.position))&&Cu(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&bc(e)){e.input.charCodeAt(e.position)===46&&(e.position+=3,Ve(e,!0,-1));return}if(e.position<e.length-1)Z(e,"end of the stream or a document separator is expected");else return}function MH(e,t){e=String(e),t=t||{},e.length!==0&&(e.charCodeAt(e.length-1)!==10&&e.charCodeAt(e.length-1)!==13&&(e+=`
|
|
430
|
-
`),e.charCodeAt(0)===65279&&(e=e.slice(1)));var n=new kH(e,t),r=e.indexOf("\0");for(r!==-1&&(n.position=r,Z(n,"null byte is not allowed in input")),n.input+="\0";n.input.charCodeAt(n.position)===32;)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)DH(n);return n.documents}function FH(e,t){var n=MH(e,t);if(n.length!==0){if(n.length===1)return n[0];throw new Xn("expected a single document in the stream, but found more")}}var PH=FH,BH={load:PH},UH=BH.load;function Ak(e){var y;const t=e.pages||[],n=e.relations||[];if(t.length===0)return{nodes:[],edges:[]};const r=new Map,i=new Map;for(const m of t)r.set(m.id,[]),i.set(m.id,0);for(const m of n)(y=r.get(m.from))==null||y.push(m.to),i.set(m.to,(i.get(m.to)||0)+1);const a=new Map,s=[];for(const m of t)(i.get(m.id)||0)===0&&(s.push(m.id),a.set(m.id,0));let o=0;for(;s.length>0;){const m=s.shift(),_=a.get(m)||0;for(const v of r.get(m)||[]){const w=_+1;w>(a.get(v)||0)&&(a.set(v,w),w>o&&(o=w));const C=(i.get(v)||1)-1;i.set(v,C),C<=0&&s.push(v)}}for(const m of t)a.has(m.id)||a.set(m.id,o+1);const l=new Map;for(const m of t){const _=a.get(m.id)||0;l.has(_)||l.set(_,[]),l.get(_).push(m.id)}const u=160,d=50,c=60,h=80,p=[],f=new Map(t.map(m=>[m.id,m]));for(const[m,_]of l){const w=-(_.length*u+(_.length-1)*c)/2;_.forEach((C,k)=>{const A=f.get(C);p.push({id:C,title:(A==null?void 0:A.title)||C,x:w+k*(u+c)+u/2,y:m*(d+h),layer:m})})}const b=n.map(m=>({from:m.from,to:m.to,label:m.label}));return{nodes:p,edges:b}}const Nk=["#3b82f6","#8b5cf6","#ec4899","#f59e0b","#10b981","#06b6d4","#f97316","#6366f1"];function zH({folderPath:e}){const[t,n]=S.useState(null),[r,i]=S.useState(!0),[a,s]=S.useState(null),[o,l]=S.useState(1),[u,d]=S.useState({x:0,y:0}),[c,h]=S.useState(!1),[p,f]=S.useState({x:0,y:0}),b=S.useRef(null),y=S.useRef(null),m=`${e}/.notebook/graph.yaml`,_=S.useCallback(async()=>{i(!0),s(null);try{const L=await xC(m);if(!L.content){s("graph.yaml is empty"),n(null);return}const T=UH(L.content);n(T),l(1),d({x:0,y:0})}catch{s("Cannot read .notebook/graph.yaml"),n(null)}finally{i(!1)}},[m]);S.useEffect(()=>{_()},[_]);const v=S.useCallback(L=>{L.preventDefault();const T=L.deltaY>0?-.1:.1;l(N=>Math.max(.2,Math.min(3,N+T)))},[]),w=S.useCallback(L=>{L.button===0&&(h(!0),f({x:L.clientX-u.x,y:L.clientY-u.y}))},[u]),C=S.useCallback(L=>{c&&d({x:L.clientX-p.x,y:L.clientY-p.y})},[c,p]),k=S.useCallback(()=>{h(!1)},[]),A=S.useCallback(()=>{if(!t||!y.current)return;const{nodes:L}=Ak(t);if(L.length===0)return;const T=Math.min(...L.map(V=>V.x))-100,N=Math.max(...L.map(V=>V.x))+100,M=Math.min(...L.map(V=>V.y))-40,F=Math.max(...L.map(V=>V.y))+60,z=N-T,j=F-M,D=y.current.clientWidth,$=y.current.clientHeight,x=Math.min(D/z,$/j,1.5)*.9;l(x),d({x:D/2-(T+N)/2*x,y:$/2-(M+F)/2*x})},[t]);if(S.useEffect(()=>{t&&!r&&setTimeout(A,50)},[t,r,A]),r)return g.jsx("div",{className:"flex items-center justify-center h-full text-muted-foreground",children:g.jsx(Oh,{className:"h-5 w-5 animate-spin"})});if(a||!t)return g.jsxs("div",{className:"flex flex-col items-center justify-center h-full gap-2 text-muted-foreground text-sm px-4 text-center",children:[g.jsx("p",{children:a||"No graph data"}),g.jsxs(se,{variant:"ghost",size:"sm",onClick:()=>void _(),children:[g.jsx(Ws,{className:"h-3 w-3 mr-1"})," Retry"]})]});const{nodes:O,edges:P}=S.useMemo(()=>Ak(t),[t]),I=S.useMemo(()=>new Map(O.map(L=>[L.id,L])),[O]);return g.jsxs("div",{className:"flex flex-col h-full",children:[g.jsxs("div",{className:"flex items-center gap-1 px-2 py-1 border-b shrink-0",children:[g.jsxs("span",{className:"text-xs text-muted-foreground mr-auto",children:[O.length," pages, ",P.length," relations"]}),g.jsx(se,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>l(L=>Math.min(3,L+.2)),children:g.jsx(NC,{className:"h-3 w-3"})}),g.jsx(se,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>l(L=>Math.max(.2,L-.2)),children:g.jsx(RC,{className:"h-3 w-3"})}),g.jsx(se,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:A,children:g.jsx(UL,{className:"h-3 w-3"})}),g.jsx(se,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>void _(),children:g.jsx(Ws,{className:"h-3 w-3"})})]}),g.jsx("div",{ref:y,className:"flex-1 overflow-hidden cursor-grab active:cursor-grabbing bg-muted/30",onWheel:v,onMouseDown:w,onMouseMove:C,onMouseUp:k,onMouseLeave:k,children:g.jsxs("svg",{ref:b,width:"100%",height:"100%",style:{userSelect:"none"},children:[g.jsx("defs",{children:g.jsx("marker",{id:"arrowhead",viewBox:"0 0 10 7",refX:"10",refY:"3.5",markerWidth:"8",markerHeight:"6",orient:"auto",children:g.jsx("polygon",{points:"0 0, 10 3.5, 0 7",className:"fill-muted-foreground/60"})})}),g.jsxs("g",{transform:`translate(${u.x}, ${u.y}) scale(${o})`,children:[P.map((L,T)=>{const N=I.get(L.from),M=I.get(L.to);if(!N||!M)return null;const F=N.y+20,z=M.y-20,j=(F+z)/2;return g.jsxs("g",{children:[g.jsx("path",{d:`M ${N.x} ${F} C ${N.x} ${j}, ${M.x} ${j}, ${M.x} ${z}`,fill:"none",className:"stroke-muted-foreground/40",strokeWidth:1.5,markerEnd:"url(#arrowhead)"}),L.label&&g.jsx("text",{x:(N.x+M.x)/2,y:j-4,textAnchor:"middle",className:"fill-muted-foreground/60",fontSize:9,children:L.label})]},`edge-${T}`)}),O.map(L=>{const T=Nk[L.layer%Nk.length],N=140,M=36;return g.jsxs("g",{transform:`translate(${L.x-N/2}, ${L.y-M/2})`,children:[g.jsx("rect",{width:N,height:M,rx:8,fill:T,fillOpacity:.15,stroke:T,strokeWidth:1.5}),g.jsx("text",{x:N/2,y:M/2+1,textAnchor:"middle",dominantBaseline:"middle",className:"fill-foreground",fontSize:11,fontWeight:500,children:L.title.length>14?L.title.slice(0,13)+"…":L.title})]},L.id)})]})]})})]})}const PA={js:"javascript",jsx:"jsx",ts:"typescript",tsx:"tsx",py:"python",rb:"ruby",go:"go",rs:"rust",java:"java",kt:"kotlin",swift:"swift",c:"c",cpp:"cpp",h:"c",cs:"csharp",php:"php",sh:"bash",bash:"bash",zsh:"bash",yaml:"yaml",yml:"yaml",json:"json",toml:"toml",html:"html",htm:"html",xml:"xml",svg:"xml",css:"css",scss:"scss",less:"less",sql:"sql",graphql:"graphql",gql:"graphql",dockerfile:"docker",makefile:"makefile",r:"r",lua:"lua",dart:"dart",zig:"zig"};function $H(e){const t=e.split("/").pop()??"",n=t.toLowerCase();if(n==="dockerfile")return"dockerfile";if(n==="makefile")return"makefile";const r=t.lastIndexOf(".");return r>=0?t.slice(r+1).toLowerCase():""}function jH(e){return e==="md"||e==="html"||e==="htm"||e in PA}function Rk(e){return e==="md"?"Markdown":e==="html"||e==="htm"?"HTML":"高亮"}const Mi=[50,75,100,125,150,200,250,300],ro=100,Fp="cc_file_zoom";function HH(e){try{const n=JSON.parse(localStorage.getItem(Fp)||"{}")[e];return Mi.includes(n)?n:ro}catch{return ro}}function GH(e,t){try{const n=JSON.parse(localStorage.getItem(Fp)||"{}");t===ro?delete n[e]:n[e]=t,localStorage.setItem(Fp,JSON.stringify(n))}catch{}}function WH({filePath:e,onClose:t}){const n=e.endsWith("/.notebook/graph.yaml"),r=n?e.replace(/\/.notebook\/graph\.yaml$/,""):"",[i,a]=S.useState(null),[s,o]=S.useState(null),[l,u]=S.useState(()=>n?"graph":"rendered"),[d,c]=S.useState(!1),[h,p]=S.useState(ro),[f,b]=S.useState(""),[y,m]=S.useState(!1),[_,v]=S.useState(!1),w=S.useRef(null),{resolved:C}=Xf(),k=e.split("/").pop()??e,A=S.useMemo(()=>$H(e),[e]),O=jH(A),P=PA[A]||A;S.useEffect(()=>{a(null),o(null),u(e.endsWith("/.notebook/graph.yaml")?"graph":"rendered"),p(HH(e)),v(!1),xC(e).then(G=>{a(G),b(G.content??"")}).catch(G=>o(G instanceof Error?G.message:"Failed to load file"))},[e]);const I=G=>{if(G.target===G.currentTarget){if(_&&!confirm("有未保存的修改,确定关闭?"))return;t()}};S.useEffect(()=>{const G=R=>{if(R.key==="Escape"){if(_&&!confirm("有未保存的修改,确定关闭?"))return;t()}};return window.addEventListener("keydown",G),()=>window.removeEventListener("keydown",G)},[t,_]);const L=S.useCallback(async()=>{m(!0);try{await SL(e,f),a(G=>G&&{...G,content:f,size:new Blob([f]).size}),v(!1)}catch(G){alert(G instanceof Error?G.message:"保存失败")}finally{m(!1)}},[e,f]);S.useEffect(()=>{const G=R=>{(R.metaKey||R.ctrlKey)&&R.key==="s"&&l==="edit"&&(R.preventDefault(),L())};return window.addEventListener("keydown",G),()=>window.removeEventListener("keydown",G)},[l,L]);const T=()=>{b((i==null?void 0:i.content)??""),v(!1),u("edit"),setTimeout(()=>{var G;return(G=w.current)==null?void 0:G.focus()},0)},N=()=>{_&&!confirm("有未保存的修改,确定退出编辑?")||(u(n?"graph":O?"rendered":"plain"),v(!1))},M=G=>{p(G),GH(e,G)},F=()=>{const G=Mi.find(R=>R>h);G&&M(G)},z=()=>{const G=[...Mi].reverse().find(R=>R<h);G&&M(G)},j=()=>M(ro),D=(i==null?void 0:i.content)??"",$=C==="dark"?X5:Z5,x=12*(h/100),V=i&&!i.binary&&!i.tooLarge;return g.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm",onClick:I,children:g.jsxs("div",{className:J("relative flex flex-col bg-background border border-border shadow-2xl transition-all duration-200",d?"w-screen h-screen rounded-none":"w-[72vw] max-w-4xl h-[80vh] rounded-lg"),children:[g.jsxs("div",{className:"flex items-center gap-2 px-4 h-10 border-b border-border flex-shrink-0",children:[g.jsx(kl,{className:"h-3.5 w-3.5 text-muted-foreground flex-shrink-0"}),g.jsxs("span",{className:"flex-1 text-sm text-foreground font-medium truncate",title:e,children:[k,_&&g.jsx("span",{className:"text-muted-foreground ml-1",children:"*"})]}),V&&g.jsxs("div",{className:"flex items-center rounded-md border border-border bg-muted/50 p-0.5",children:[O&&g.jsxs(g.Fragment,{children:[g.jsxs("button",{onClick:()=>l==="edit"?N():u("plain"),className:J("p-1 rounded-sm transition-colors flex items-center gap-1 text-xs",l==="plain"?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:"纯文本",children:[g.jsx(OL,{className:"h-3 w-3"}),g.jsx("span",{className:"hidden sm:inline",children:"源码"})]}),g.jsxs("button",{onClick:()=>l==="edit"?N():u("rendered"),className:J("p-1 rounded-sm transition-colors flex items-center gap-1 text-xs",l==="rendered"?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:Rk(A),children:[g.jsx(DL,{className:"h-3 w-3"}),g.jsx("span",{className:"hidden sm:inline",children:Rk(A)})]})]}),n&&g.jsxs("button",{onClick:()=>l==="edit"?N():u("graph"),className:J("p-1 rounded-sm transition-colors flex items-center gap-1 text-xs",l==="graph"?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:"图谱",children:[g.jsx(jL,{className:"h-3 w-3"}),g.jsx("span",{className:"hidden sm:inline",children:"图谱"})]}),g.jsxs("button",{onClick:()=>l==="edit"?N():T(),className:J("p-1 rounded-sm transition-colors flex items-center gap-1 text-xs",l==="edit"?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:"编辑",children:[g.jsx(Vf,{className:"h-3 w-3"}),g.jsx("span",{className:"hidden sm:inline",children:"编辑"})]})]}),l==="edit"&&g.jsxs("button",{onClick:()=>void L(),disabled:y||!_,className:J("flex items-center gap-1 text-xs px-2 py-1 rounded transition-colors",_?"bg-blue-600 hover:bg-blue-500 text-white":"bg-muted text-muted-foreground"),title:"保存 (⌘S)",children:[g.jsx(VL,{className:"h-3 w-3"}),y?"保存中...":"保存"]}),V&&l!=="edit"&&l!=="graph"&&g.jsxs("div",{className:"flex items-center rounded-md border border-border bg-muted/50 p-0.5 gap-0.5",children:[g.jsx("button",{onClick:z,disabled:h<=Mi[0],className:"p-1 rounded-sm text-muted-foreground hover:text-foreground transition-colors disabled:opacity-30",title:"缩小",children:g.jsx(RC,{className:"h-3 w-3"})}),g.jsxs("button",{onClick:j,className:"px-1 text-xs text-muted-foreground hover:text-foreground transition-colors min-w-[36px] text-center",title:"重置缩放",children:[h,"%"]}),g.jsx("button",{onClick:F,disabled:h>=Mi[Mi.length-1],className:"p-1 rounded-sm text-muted-foreground hover:text-foreground transition-colors disabled:opacity-30",title:"放大",children:g.jsx(NC,{className:"h-3 w-3"})})]}),g.jsx("button",{className:"p-1 rounded text-muted-foreground hover:text-foreground transition-colors",onClick:()=>c(G=>!G),title:d?"退出全屏":"全屏",children:d?g.jsx(Wf,{className:"h-3.5 w-3.5"}):g.jsx(Gf,{className:"h-3.5 w-3.5"})}),g.jsx("button",{className:"p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors",onClick:()=>{_&&!confirm("有未保存的修改,确定关闭?")||t()},children:g.jsx(wa,{className:"h-4 w-4"})})]}),g.jsxs("div",{className:J("flex-1 min-h-0",l==="graph"?"overflow-hidden":"overflow-auto"),children:[l==="graph"&&g.jsx(zH,{folderPath:r}),l!=="graph"&&!i&&!s&&g.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"Loading…"}),l!=="graph"&&s&&g.jsx("p",{className:"text-sm text-red-400 p-4",children:s}),l!=="graph"&&i&&i.binary&&g.jsxs("div",{className:"flex flex-col items-center gap-2 py-12 text-muted-foreground p-4",children:[g.jsx(kl,{className:"h-8 w-8"}),g.jsx("p",{className:"text-sm",children:"Binary file — cannot preview"}),g.jsxs("p",{className:"text-xs text-muted-foreground",children:[(i.size/1024).toFixed(1)," KB"]})]}),l!=="graph"&&i&&i.tooLarge&&g.jsxs("div",{className:"flex flex-col items-center gap-2 py-12 text-muted-foreground p-4",children:[g.jsx(kl,{className:"h-8 w-8"}),g.jsx("p",{className:"text-sm",children:"File too large to preview"}),g.jsxs("p",{className:"text-xs text-muted-foreground",children:[(i.size/1024/1024).toFixed(2)," MB (limit 1 MB)"]})]}),l!=="graph"&&V&&D!==null&&g.jsxs(g.Fragment,{children:[l==="edit"&&g.jsx("textarea",{ref:w,value:f,onChange:G=>{b(G.target.value),v(!0)},className:"w-full h-full bg-transparent text-foreground font-mono outline-none resize-none p-4 leading-relaxed",style:{fontSize:`${x}px`,minHeight:"100%"},spellCheck:!1}),l!=="edit"&&g.jsxs("div",{className:"p-4",style:{fontSize:`${x}px`},children:[l==="plain"&&g.jsx("pre",{className:"font-mono text-foreground whitespace-pre-wrap break-words leading-relaxed",style:{fontSize:"inherit"},children:D}),l==="rendered"&&A==="md"&&g.jsx("div",{className:"prose dark:prose-invert max-w-none prose-pre:bg-muted prose-pre:border prose-pre:border-border prose-code:text-foreground",style:{fontSize:"inherit"},children:g.jsx(z$,{remarkPlugins:[Jj],components:{code({className:G,children:R,...ue}){const be=/language-(\w+)/.exec(G||"");return!be&&!G?g.jsx("code",{className:G,...ue,children:R}):g.jsx(Dp,{style:$,language:(be==null?void 0:be[1])||"text",PreTag:"div",customStyle:{fontSize:"inherit",borderRadius:"6px",margin:0},children:String(R).replace(/\n$/,"")})}},children:D})}),l==="rendered"&&(A==="html"||A==="htm")&&g.jsx("iframe",{srcDoc:D,className:"w-full h-full border-0 rounded bg-white",sandbox:"",title:k,style:{minHeight:"60vh",transform:`scale(${h/100})`,transformOrigin:"top left",width:`${1e4/h}%`,height:`${1e4/h}%`}}),l==="rendered"&&A!=="md"&&A!=="html"&&A!=="htm"&&P&&g.jsx(Dp,{style:$,language:P,showLineNumbers:!0,lineNumberStyle:{color:C==="dark"?"#555":"#aaa",fontSize:"inherit"},customStyle:{fontSize:"inherit",borderRadius:"6px",margin:0,background:"transparent"},children:D}),l==="rendered"&&!O&&g.jsx("pre",{className:"font-mono text-foreground whitespace-pre-wrap break-words leading-relaxed",style:{fontSize:"inherit"},children:D})]})]})]})]})})}function VH({projectPath:e}){const[t,n]=S.useState(new Map),[r,i]=S.useState(new Set([e])),[a,s]=S.useState(new Set),[o,l]=S.useState(null),u=S.useCallback(async y=>{s(m=>{if(m.has(y))return m;const _=new Set(m);return _.add(y),_});try{const m=await kC(y);n(_=>new Map(_).set(y,m.entries))}catch(m){console.error("[FileTree] Failed to load:",y,m),n(_=>new Map(_).set(y,[]))}finally{s(m=>{const _=new Set(m);return _.delete(y),_})}},[]);S.useEffect(()=>{n(new Map),i(new Set([e])),s(new Set),u(e)},[e,u]);const d=S.useCallback(y=>{i(m=>{const _=new Set(m);return _.has(y)?_.delete(y):(_.add(y),t.has(y)||u(y)),_})},[t,u]),c=S.useCallback(()=>{n(new Map),i(new Set([e])),s(new Set),u(e)},[e,u]),h=(y,m)=>y.map(_=>{const v=r.has(_.path),w=a.has(_.path),C=t.get(_.path),k=_.name.startsWith(".");return g.jsxs("div",{children:[g.jsxs("div",{className:J("flex items-center gap-1 py-[3px] rounded cursor-pointer","hover:bg-muted",k&&"opacity-50"),style:{paddingLeft:`${m*14+6}px`,paddingRight:"6px"},onClick:()=>_.type==="dir"?d(_.path):l(_.path),children:[g.jsx("span",{className:"w-3 flex-shrink-0 text-muted-foreground",children:_.type==="dir"&&(w?g.jsx(Ws,{className:"h-2.5 w-2.5 animate-spin"}):v?g.jsx(AC,{className:"h-2.5 w-2.5"}):g.jsx(Hf,{className:"h-2.5 w-2.5"}))}),_.type==="dir"?v?g.jsx(Gs,{className:"h-3.5 w-3.5 text-blue-400 flex-shrink-0"}):g.jsx(Ih,{className:"h-3.5 w-3.5 text-blue-400 flex-shrink-0"}):g.jsx(kl,{className:"h-3.5 w-3.5 text-muted-foreground flex-shrink-0"}),g.jsx("span",{className:J("text-xs truncate leading-none",_.type==="dir"?"text-foreground":"text-muted-foreground"),title:_.path,children:_.name})]}),_.type==="dir"&&v&&g.jsxs("div",{children:[!C&&!w&&g.jsx("div",{className:"text-xs text-muted-foreground/50 py-0.5",style:{paddingLeft:`${(m+1)*14+6+16}px`},children:"—"}),(C==null?void 0:C.length)===0&&g.jsx("div",{className:"text-xs text-muted-foreground/50 py-0.5",style:{paddingLeft:`${(m+1)*14+6+16}px`},children:"empty"}),C&&C.length>0&&h(C,m+1)]})]},_.path)}),p=t.get(e),f=a.has(e),b=e.split("/").filter(Boolean).pop()??e;return g.jsxs(g.Fragment,{children:[o&&g.jsx(WH,{filePath:o,onClose:()=>l(null)}),g.jsxs("div",{className:"h-full flex flex-col bg-background text-foreground select-none",children:[g.jsxs("div",{className:"flex items-center justify-between px-3 h-9 border-b border-border flex-shrink-0",children:[g.jsx("span",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"Files"}),g.jsx("button",{className:"text-muted-foreground hover:text-foreground p-0.5 rounded transition-colors",onClick:c,title:"Refresh file tree",children:g.jsx(Ws,{className:J("h-3 w-3",f&&"animate-spin")})})]}),g.jsxs("div",{className:"flex items-center gap-1.5 px-3 py-2 border-b border-border flex-shrink-0",children:[g.jsx(Gs,{className:"h-3.5 w-3.5 text-blue-400 flex-shrink-0"}),g.jsx("span",{className:"text-xs text-foreground font-medium truncate",title:e,children:b})]}),g.jsx("div",{className:"flex-1 overflow-y-auto py-1 min-h-0",children:f&&!p?g.jsx("div",{className:"text-xs text-muted-foreground px-4 py-3",children:"Loading…"}):!p||p.length===0?g.jsx("div",{className:"text-xs text-muted-foreground px-4 py-3",children:"Empty folder"}):h(p,0)})]})]})}const Ik=e=>`cc_shortcuts_${e}`;function qH({open:e,onOpenChange:t,initialLabel:n,initialCommand:r,title:i,onSave:a}){const[s,o]=S.useState(n),[l,u]=S.useState(r);S.useEffect(()=>{e&&(o(n),u(r))},[e,n,r]);const d=()=>{const c=l.trim();c&&(a(s.trim()||c,c),t(!1))};return g.jsx(Xu,{open:e,onOpenChange:t,children:g.jsxs(po,{className:"sm:max-w-2xl max-h-[85vh] flex flex-col",children:[g.jsxs(fo,{children:[g.jsx(mo,{children:i}),g.jsx(bo,{children:"Write the command that will be sent to Claude when this shortcut is triggered."})]}),g.jsxs("div",{className:"space-y-4 flex-1 min-h-0 flex flex-col",children:[g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{htmlFor:"shortcut-label",children:"Label"}),g.jsx(Hs,{id:"shortcut-label",placeholder:"Give it a name (optional)",value:s,onChange:c=>o(c.target.value),className:"text-base",autoFocus:!0})]}),g.jsxs("div",{className:"space-y-2 flex-1 flex flex-col min-h-0",children:[g.jsx(Mn,{htmlFor:"shortcut-command",children:"Command"}),g.jsx("textarea",{id:"shortcut-command",placeholder:"Enter the command to send to Claude...",value:l,onChange:c=>u(c.target.value),className:J("flex-1 min-h-[200px] w-full rounded-md border border-input bg-background px-4 py-3","text-base leading-relaxed font-mono","ring-offset-background placeholder:text-muted-foreground","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2","resize-none"),onKeyDown:c=>{c.key==="Enter"&&(c.metaKey||c.ctrlKey)&&(c.preventDefault(),d())}})]})]}),g.jsxs(go,{className:"flex items-center justify-between sm:justify-between",children:[g.jsx("span",{className:"text-xs text-muted-foreground",children:"⌘↩ to save"}),g.jsxs("div",{className:"flex gap-2",children:[g.jsx(se,{variant:"outline",onClick:()=>t(!1),children:"Cancel"}),g.jsx(se,{onClick:d,disabled:!l.trim(),children:"Save"})]})]})]})})}function YH({projectId:e,onSend:t}){const[n,r]=S.useState([]),[i,a]=S.useState([]),[s,o]=S.useState(!1),[l,u]=S.useState(null);S.useEffect(()=>{try{const m=localStorage.getItem(Ik(e));r(m?JSON.parse(m):[])}catch{r([])}},[e]),S.useEffect(()=>{EC().then(a).catch(()=>a([]))},[]);const d=S.useCallback(m=>{const _=[],v=new Set;let w=m;const C=[];for(;w&&!v.has(w.id);)v.add(w.id),C.unshift(w),w=w.parentId?i.find(k=>k.id===w.parentId):void 0;for(const k of C)_.push(k.command);return _},[i]),c=S.useCallback(m=>{d(m).forEach((v,w)=>{setTimeout(()=>t(v+"\r"),w*500)})},[d,t]),h=m=>{r(m),localStorage.setItem(Ik(e),JSON.stringify(m))},p=()=>{u(null),o(!0)},f=(m,_)=>{_.stopPropagation(),u(m),o(!0)},b=(m,_)=>{h(l?n.map(v=>v.id===l.id?{...v,label:m,command:_}:v):[...n,{id:crypto.randomUUID(),label:m,command:_}]),u(null)},y=(m,_)=>{_.stopPropagation(),h(n.filter(v=>v.id!==m))};return g.jsxs("div",{className:"h-full flex flex-col bg-background text-foreground select-none",children:[g.jsxs("div",{className:"flex items-center justify-between px-3 h-9 border-b border-border flex-shrink-0",children:[g.jsx("span",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"Shortcuts"}),g.jsx("button",{className:"p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors",onClick:p,title:"New shortcut",children:g.jsx(du,{className:"h-3.5 w-3.5"})})]}),g.jsxs("div",{className:"flex-1 overflow-y-auto p-2 space-y-1.5 min-h-0",children:[i.length>0&&g.jsxs(g.Fragment,{children:[g.jsxs("div",{className:"flex items-center gap-1.5 px-1 pt-1 pb-0.5",children:[g.jsx(hu,{className:"h-3 w-3 text-muted-foreground"}),g.jsx("span",{className:"text-xs text-muted-foreground uppercase tracking-wider",children:"全局"})]}),i.map(m=>{var v;const _=m.parentId?(v=i.find(w=>w.id===m.parentId))==null?void 0:v.label:void 0;return g.jsxs("div",{className:J("group relative rounded px-3 py-2 cursor-pointer","bg-muted hover:bg-accent","border border-transparent hover:border-muted-foreground/30","transition-colors"),onClick:()=>c(m),title:_?`继承自「${_}」`:"Click to send",children:[g.jsx("div",{className:"text-xs font-medium text-foreground truncate leading-snug",children:m.label}),_&&g.jsxs("div",{className:"flex items-center gap-1 mt-0.5",children:[g.jsx(xl,{className:"h-2.5 w-2.5 text-muted-foreground"}),g.jsxs("span",{className:"text-xs text-muted-foreground truncate",children:["继承: ",_]})]}),!_&&m.label!==m.command&&g.jsx("div",{className:"text-xs text-muted-foreground font-mono truncate mt-0.5 leading-snug",children:m.command})]},m.id)}),n.length>0&&g.jsx("div",{className:"flex items-center gap-1.5 px-1 pt-2 pb-0.5",children:g.jsx("span",{className:"text-xs text-muted-foreground uppercase tracking-wider",children:"项目"})})]}),n.length===0&&i.length===0&&g.jsxs("div",{className:"flex flex-col items-center gap-2 py-8 text-muted-foreground/50",children:[g.jsx(hu,{className:"h-5 w-5"}),g.jsxs("p",{className:"text-xs text-center leading-relaxed",children:["No shortcuts yet.",g.jsx("br",{}),"Click ",g.jsx("strong",{className:"text-muted-foreground",children:"+"})," to add one."]})]}),n.map(m=>g.jsxs("div",{className:J("group relative rounded px-3 py-2 cursor-pointer","bg-muted hover:bg-accent","border border-transparent hover:border-muted-foreground/30","transition-colors"),onClick:()=>t(m.command+"\r"),title:"Click to send",children:[g.jsx("div",{className:"text-xs font-medium text-foreground truncate pr-10 leading-snug",children:m.label}),m.label!==m.command&&g.jsx("div",{className:"text-xs text-muted-foreground font-mono truncate mt-0.5 leading-snug pr-10",children:m.command}),g.jsxs("div",{className:"absolute top-1.5 right-1.5 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity",children:[g.jsx("button",{className:"p-0.5 rounded text-muted-foreground hover:text-blue-400 transition-colors",onClick:_=>f(m,_),title:"Edit shortcut",children:g.jsx(Vf,{className:"h-3 w-3"})}),g.jsx("button",{className:"p-0.5 rounded text-muted-foreground hover:text-red-400 transition-colors",onClick:_=>y(m.id,_),title:"Delete shortcut",children:g.jsx(wa,{className:"h-3 w-3"})})]})]},m.id))]}),g.jsx(qH,{open:s,onOpenChange:o,initialLabel:(l==null?void 0:l.label)??"",initialCommand:(l==null?void 0:l.command)??"",title:l?"Edit Shortcut":"New Shortcut",onSave:b})]})}function BA(e){return new Date(e).toLocaleString("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})}function UA(e){return`这是我们上一次的聊天记录,请你回忆:
|
|
430
|
+
`),e.charCodeAt(0)===65279&&(e=e.slice(1)));var n=new kH(e,t),r=e.indexOf("\0");for(r!==-1&&(n.position=r,Z(n,"null byte is not allowed in input")),n.input+="\0";n.input.charCodeAt(n.position)===32;)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)DH(n);return n.documents}function FH(e,t){var n=MH(e,t);if(n.length!==0){if(n.length===1)return n[0];throw new Xn("expected a single document in the stream, but found more")}}var PH=FH,BH={load:PH},UH=BH.load;function Ak(e){var y;const t=e.pages||[],n=e.relations||[];if(t.length===0)return{nodes:[],edges:[]};const r=new Map,i=new Map;for(const m of t)r.set(m.id,[]),i.set(m.id,0);for(const m of n)(y=r.get(m.from))==null||y.push(m.to),i.set(m.to,(i.get(m.to)||0)+1);const a=new Map,s=[];for(const m of t)(i.get(m.id)||0)===0&&(s.push(m.id),a.set(m.id,0));let o=0;for(;s.length>0;){const m=s.shift(),_=a.get(m)||0;for(const v of r.get(m)||[]){const w=_+1;w>(a.get(v)||0)&&(a.set(v,w),w>o&&(o=w));const C=(i.get(v)||1)-1;i.set(v,C),C<=0&&s.push(v)}}for(const m of t)a.has(m.id)||a.set(m.id,o+1);const l=new Map;for(const m of t){const _=a.get(m.id)||0;l.has(_)||l.set(_,[]),l.get(_).push(m.id)}const u=160,d=50,c=60,h=80,p=[],f=new Map(t.map(m=>[m.id,m]));for(const[m,_]of l){const w=-(_.length*u+(_.length-1)*c)/2;_.forEach((C,k)=>{const A=f.get(C);p.push({id:C,title:(A==null?void 0:A.title)||C,x:w+k*(u+c)+u/2,y:m*(d+h),layer:m})})}const b=n.map(m=>({from:m.from,to:m.to,label:m.label}));return{nodes:p,edges:b}}const Nk=["#3b82f6","#8b5cf6","#ec4899","#f59e0b","#10b981","#06b6d4","#f97316","#6366f1"];function zH({folderPath:e}){const[t,n]=S.useState(null),[r,i]=S.useState(!0),[a,s]=S.useState(null),[o,l]=S.useState(1),[u,d]=S.useState({x:0,y:0}),[c,h]=S.useState(!1),[p,f]=S.useState({x:0,y:0}),b=S.useRef(null),y=S.useRef(null),m=`${e}/.notebook/graph.yaml`,_=S.useCallback(async()=>{i(!0),s(null);try{const L=await xC(m);if(!L.content){s("graph.yaml is empty"),n(null);return}const T=UH(L.content);n(T),l(1),d({x:0,y:0})}catch{s("Cannot read .notebook/graph.yaml"),n(null)}finally{i(!1)}},[m]);S.useEffect(()=>{_()},[_]);const v=S.useCallback(L=>{L.preventDefault();const T=L.deltaY>0?-.1:.1;l(N=>Math.max(.2,Math.min(3,N+T)))},[]),w=S.useCallback(L=>{L.button===0&&(h(!0),f({x:L.clientX-u.x,y:L.clientY-u.y}))},[u]),C=S.useCallback(L=>{c&&d({x:L.clientX-p.x,y:L.clientY-p.y})},[c,p]),k=S.useCallback(()=>{h(!1)},[]),A=S.useCallback(()=>{if(!t||!y.current)return;const{nodes:L}=Ak(t);if(L.length===0)return;const T=Math.min(...L.map(V=>V.x))-100,N=Math.max(...L.map(V=>V.x))+100,M=Math.min(...L.map(V=>V.y))-40,F=Math.max(...L.map(V=>V.y))+60,z=N-T,j=F-M,D=y.current.clientWidth,$=y.current.clientHeight,x=Math.min(D/z,$/j,1.5)*.9;l(x),d({x:D/2-(T+N)/2*x,y:$/2-(M+F)/2*x})},[t]),{nodes:O,edges:P}=S.useMemo(()=>t?Ak(t):{nodes:[],edges:[]},[t]),I=S.useMemo(()=>new Map(O.map(L=>[L.id,L])),[O]);return S.useEffect(()=>{t&&!r&&setTimeout(A,50)},[t,r,A]),r?g.jsx("div",{className:"flex items-center justify-center h-full text-muted-foreground",children:g.jsx(Oh,{className:"h-5 w-5 animate-spin"})}):a||!t?g.jsxs("div",{className:"flex flex-col items-center justify-center h-full gap-2 text-muted-foreground text-sm px-4 text-center",children:[g.jsx("p",{children:a||"No graph data"}),g.jsxs(se,{variant:"ghost",size:"sm",onClick:()=>void _(),children:[g.jsx(Ws,{className:"h-3 w-3 mr-1"})," Retry"]})]}):g.jsxs("div",{className:"flex flex-col h-full",children:[g.jsxs("div",{className:"flex items-center gap-1 px-2 py-1 border-b shrink-0",children:[g.jsxs("span",{className:"text-xs text-muted-foreground mr-auto",children:[O.length," pages, ",P.length," relations"]}),g.jsx(se,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>l(L=>Math.min(3,L+.2)),children:g.jsx(NC,{className:"h-3 w-3"})}),g.jsx(se,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>l(L=>Math.max(.2,L-.2)),children:g.jsx(RC,{className:"h-3 w-3"})}),g.jsx(se,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:A,children:g.jsx(UL,{className:"h-3 w-3"})}),g.jsx(se,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>void _(),children:g.jsx(Ws,{className:"h-3 w-3"})})]}),g.jsx("div",{ref:y,className:"flex-1 overflow-hidden cursor-grab active:cursor-grabbing bg-muted/30",onWheel:v,onMouseDown:w,onMouseMove:C,onMouseUp:k,onMouseLeave:k,children:g.jsxs("svg",{ref:b,width:"100%",height:"100%",style:{userSelect:"none"},children:[g.jsx("defs",{children:g.jsx("marker",{id:"arrowhead",viewBox:"0 0 10 7",refX:"10",refY:"3.5",markerWidth:"8",markerHeight:"6",orient:"auto",children:g.jsx("polygon",{points:"0 0, 10 3.5, 0 7",className:"fill-muted-foreground/60"})})}),g.jsxs("g",{transform:`translate(${u.x}, ${u.y}) scale(${o})`,children:[P.map((L,T)=>{const N=I.get(L.from),M=I.get(L.to);if(!N||!M)return null;const F=N.y+20,z=M.y-20,j=(F+z)/2;return g.jsxs("g",{children:[g.jsx("path",{d:`M ${N.x} ${F} C ${N.x} ${j}, ${M.x} ${j}, ${M.x} ${z}`,fill:"none",className:"stroke-muted-foreground/40",strokeWidth:1.5,markerEnd:"url(#arrowhead)"}),L.label&&g.jsx("text",{x:(N.x+M.x)/2,y:j-4,textAnchor:"middle",className:"fill-muted-foreground/60",fontSize:9,children:L.label})]},`edge-${T}`)}),O.map(L=>{const T=Nk[L.layer%Nk.length],N=140,M=36;return g.jsxs("g",{transform:`translate(${L.x-N/2}, ${L.y-M/2})`,children:[g.jsx("rect",{width:N,height:M,rx:8,fill:T,fillOpacity:.15,stroke:T,strokeWidth:1.5}),g.jsx("text",{x:N/2,y:M/2+1,textAnchor:"middle",dominantBaseline:"middle",className:"fill-foreground",fontSize:11,fontWeight:500,children:L.title.length>14?L.title.slice(0,13)+"…":L.title})]},L.id)})]})]})})]})}const PA={js:"javascript",jsx:"jsx",ts:"typescript",tsx:"tsx",py:"python",rb:"ruby",go:"go",rs:"rust",java:"java",kt:"kotlin",swift:"swift",c:"c",cpp:"cpp",h:"c",cs:"csharp",php:"php",sh:"bash",bash:"bash",zsh:"bash",yaml:"yaml",yml:"yaml",json:"json",toml:"toml",html:"html",htm:"html",xml:"xml",svg:"xml",css:"css",scss:"scss",less:"less",sql:"sql",graphql:"graphql",gql:"graphql",dockerfile:"docker",makefile:"makefile",r:"r",lua:"lua",dart:"dart",zig:"zig"};function $H(e){const t=e.split("/").pop()??"",n=t.toLowerCase();if(n==="dockerfile")return"dockerfile";if(n==="makefile")return"makefile";const r=t.lastIndexOf(".");return r>=0?t.slice(r+1).toLowerCase():""}function jH(e){return e==="md"||e==="html"||e==="htm"||e in PA}function Rk(e){return e==="md"?"Markdown":e==="html"||e==="htm"?"HTML":"高亮"}const Mi=[50,75,100,125,150,200,250,300],ro=100,Fp="cc_file_zoom";function HH(e){try{const n=JSON.parse(localStorage.getItem(Fp)||"{}")[e];return Mi.includes(n)?n:ro}catch{return ro}}function GH(e,t){try{const n=JSON.parse(localStorage.getItem(Fp)||"{}");t===ro?delete n[e]:n[e]=t,localStorage.setItem(Fp,JSON.stringify(n))}catch{}}function WH({filePath:e,onClose:t}){const n=e.endsWith("/.notebook/graph.yaml"),r=n?e.replace(/\/.notebook\/graph\.yaml$/,""):"",[i,a]=S.useState(null),[s,o]=S.useState(null),[l,u]=S.useState(()=>n?"graph":"rendered"),[d,c]=S.useState(!1),[h,p]=S.useState(ro),[f,b]=S.useState(""),[y,m]=S.useState(!1),[_,v]=S.useState(!1),w=S.useRef(null),{resolved:C}=Xf(),k=e.split("/").pop()??e,A=S.useMemo(()=>$H(e),[e]),O=jH(A),P=PA[A]||A;S.useEffect(()=>{a(null),o(null),u(e.endsWith("/.notebook/graph.yaml")?"graph":"rendered"),p(HH(e)),v(!1),xC(e).then(G=>{a(G),b(G.content??"")}).catch(G=>o(G instanceof Error?G.message:"Failed to load file"))},[e]);const I=G=>{if(G.target===G.currentTarget){if(_&&!confirm("有未保存的修改,确定关闭?"))return;t()}};S.useEffect(()=>{const G=R=>{if(R.key==="Escape"){if(_&&!confirm("有未保存的修改,确定关闭?"))return;t()}};return window.addEventListener("keydown",G),()=>window.removeEventListener("keydown",G)},[t,_]);const L=S.useCallback(async()=>{m(!0);try{await SL(e,f),a(G=>G&&{...G,content:f,size:new Blob([f]).size}),v(!1)}catch(G){alert(G instanceof Error?G.message:"保存失败")}finally{m(!1)}},[e,f]);S.useEffect(()=>{const G=R=>{(R.metaKey||R.ctrlKey)&&R.key==="s"&&l==="edit"&&(R.preventDefault(),L())};return window.addEventListener("keydown",G),()=>window.removeEventListener("keydown",G)},[l,L]);const T=()=>{b((i==null?void 0:i.content)??""),v(!1),u("edit"),setTimeout(()=>{var G;return(G=w.current)==null?void 0:G.focus()},0)},N=()=>{_&&!confirm("有未保存的修改,确定退出编辑?")||(u(n?"graph":O?"rendered":"plain"),v(!1))},M=G=>{p(G),GH(e,G)},F=()=>{const G=Mi.find(R=>R>h);G&&M(G)},z=()=>{const G=[...Mi].reverse().find(R=>R<h);G&&M(G)},j=()=>M(ro),D=(i==null?void 0:i.content)??"",$=C==="dark"?X5:Z5,x=12*(h/100),V=i&&!i.binary&&!i.tooLarge;return g.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm",onClick:I,children:g.jsxs("div",{className:J("relative flex flex-col bg-background border border-border shadow-2xl transition-all duration-200",d?"w-screen h-screen rounded-none":"w-[72vw] max-w-4xl h-[80vh] rounded-lg"),children:[g.jsxs("div",{className:"flex items-center gap-2 px-4 h-10 border-b border-border flex-shrink-0",children:[g.jsx(kl,{className:"h-3.5 w-3.5 text-muted-foreground flex-shrink-0"}),g.jsxs("span",{className:"flex-1 text-sm text-foreground font-medium truncate",title:e,children:[k,_&&g.jsx("span",{className:"text-muted-foreground ml-1",children:"*"})]}),V&&g.jsxs("div",{className:"flex items-center rounded-md border border-border bg-muted/50 p-0.5",children:[O&&g.jsxs(g.Fragment,{children:[g.jsxs("button",{onClick:()=>l==="edit"?N():u("plain"),className:J("p-1 rounded-sm transition-colors flex items-center gap-1 text-xs",l==="plain"?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:"纯文本",children:[g.jsx(OL,{className:"h-3 w-3"}),g.jsx("span",{className:"hidden sm:inline",children:"源码"})]}),g.jsxs("button",{onClick:()=>l==="edit"?N():u("rendered"),className:J("p-1 rounded-sm transition-colors flex items-center gap-1 text-xs",l==="rendered"?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:Rk(A),children:[g.jsx(DL,{className:"h-3 w-3"}),g.jsx("span",{className:"hidden sm:inline",children:Rk(A)})]})]}),n&&g.jsxs("button",{onClick:()=>l==="edit"?N():u("graph"),className:J("p-1 rounded-sm transition-colors flex items-center gap-1 text-xs",l==="graph"?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:"图谱",children:[g.jsx(jL,{className:"h-3 w-3"}),g.jsx("span",{className:"hidden sm:inline",children:"图谱"})]}),g.jsxs("button",{onClick:()=>l==="edit"?N():T(),className:J("p-1 rounded-sm transition-colors flex items-center gap-1 text-xs",l==="edit"?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),title:"编辑",children:[g.jsx(Vf,{className:"h-3 w-3"}),g.jsx("span",{className:"hidden sm:inline",children:"编辑"})]})]}),l==="edit"&&g.jsxs("button",{onClick:()=>void L(),disabled:y||!_,className:J("flex items-center gap-1 text-xs px-2 py-1 rounded transition-colors",_?"bg-blue-600 hover:bg-blue-500 text-white":"bg-muted text-muted-foreground"),title:"保存 (⌘S)",children:[g.jsx(VL,{className:"h-3 w-3"}),y?"保存中...":"保存"]}),V&&l!=="edit"&&l!=="graph"&&g.jsxs("div",{className:"flex items-center rounded-md border border-border bg-muted/50 p-0.5 gap-0.5",children:[g.jsx("button",{onClick:z,disabled:h<=Mi[0],className:"p-1 rounded-sm text-muted-foreground hover:text-foreground transition-colors disabled:opacity-30",title:"缩小",children:g.jsx(RC,{className:"h-3 w-3"})}),g.jsxs("button",{onClick:j,className:"px-1 text-xs text-muted-foreground hover:text-foreground transition-colors min-w-[36px] text-center",title:"重置缩放",children:[h,"%"]}),g.jsx("button",{onClick:F,disabled:h>=Mi[Mi.length-1],className:"p-1 rounded-sm text-muted-foreground hover:text-foreground transition-colors disabled:opacity-30",title:"放大",children:g.jsx(NC,{className:"h-3 w-3"})})]}),g.jsx("button",{className:"p-1 rounded text-muted-foreground hover:text-foreground transition-colors",onClick:()=>c(G=>!G),title:d?"退出全屏":"全屏",children:d?g.jsx(Wf,{className:"h-3.5 w-3.5"}):g.jsx(Gf,{className:"h-3.5 w-3.5"})}),g.jsx("button",{className:"p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors",onClick:()=>{_&&!confirm("有未保存的修改,确定关闭?")||t()},children:g.jsx(wa,{className:"h-4 w-4"})})]}),g.jsxs("div",{className:J("flex-1 min-h-0",l==="graph"?"overflow-hidden":"overflow-auto"),children:[l==="graph"&&g.jsx(zH,{folderPath:r}),l!=="graph"&&!i&&!s&&g.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"Loading…"}),l!=="graph"&&s&&g.jsx("p",{className:"text-sm text-red-400 p-4",children:s}),l!=="graph"&&i&&i.binary&&g.jsxs("div",{className:"flex flex-col items-center gap-2 py-12 text-muted-foreground p-4",children:[g.jsx(kl,{className:"h-8 w-8"}),g.jsx("p",{className:"text-sm",children:"Binary file — cannot preview"}),g.jsxs("p",{className:"text-xs text-muted-foreground",children:[(i.size/1024).toFixed(1)," KB"]})]}),l!=="graph"&&i&&i.tooLarge&&g.jsxs("div",{className:"flex flex-col items-center gap-2 py-12 text-muted-foreground p-4",children:[g.jsx(kl,{className:"h-8 w-8"}),g.jsx("p",{className:"text-sm",children:"File too large to preview"}),g.jsxs("p",{className:"text-xs text-muted-foreground",children:[(i.size/1024/1024).toFixed(2)," MB (limit 1 MB)"]})]}),l!=="graph"&&V&&D!==null&&g.jsxs(g.Fragment,{children:[l==="edit"&&g.jsx("textarea",{ref:w,value:f,onChange:G=>{b(G.target.value),v(!0)},className:"w-full h-full bg-transparent text-foreground font-mono outline-none resize-none p-4 leading-relaxed",style:{fontSize:`${x}px`,minHeight:"100%"},spellCheck:!1}),l!=="edit"&&g.jsxs("div",{className:"p-4",style:{fontSize:`${x}px`},children:[l==="plain"&&g.jsx("pre",{className:"font-mono text-foreground whitespace-pre-wrap break-words leading-relaxed",style:{fontSize:"inherit"},children:D}),l==="rendered"&&A==="md"&&g.jsx("div",{className:"prose dark:prose-invert max-w-none prose-pre:bg-muted prose-pre:border prose-pre:border-border prose-code:text-foreground",style:{fontSize:"inherit"},children:g.jsx(z$,{remarkPlugins:[Jj],components:{code({className:G,children:R,...ue}){const be=/language-(\w+)/.exec(G||"");return!be&&!G?g.jsx("code",{className:G,...ue,children:R}):g.jsx(Dp,{style:$,language:(be==null?void 0:be[1])||"text",PreTag:"div",customStyle:{fontSize:"inherit",borderRadius:"6px",margin:0},children:String(R).replace(/\n$/,"")})}},children:D})}),l==="rendered"&&(A==="html"||A==="htm")&&g.jsx("iframe",{srcDoc:D,className:"w-full h-full border-0 rounded bg-white",sandbox:"",title:k,style:{minHeight:"60vh",transform:`scale(${h/100})`,transformOrigin:"top left",width:`${1e4/h}%`,height:`${1e4/h}%`}}),l==="rendered"&&A!=="md"&&A!=="html"&&A!=="htm"&&P&&g.jsx(Dp,{style:$,language:P,showLineNumbers:!0,lineNumberStyle:{color:C==="dark"?"#555":"#aaa",fontSize:"inherit"},customStyle:{fontSize:"inherit",borderRadius:"6px",margin:0,background:"transparent"},children:D}),l==="rendered"&&!O&&g.jsx("pre",{className:"font-mono text-foreground whitespace-pre-wrap break-words leading-relaxed",style:{fontSize:"inherit"},children:D})]})]})]})]})})}function VH({projectPath:e}){const[t,n]=S.useState(new Map),[r,i]=S.useState(new Set([e])),[a,s]=S.useState(new Set),[o,l]=S.useState(null),u=S.useCallback(async y=>{s(m=>{if(m.has(y))return m;const _=new Set(m);return _.add(y),_});try{const m=await kC(y);n(_=>new Map(_).set(y,m.entries))}catch(m){console.error("[FileTree] Failed to load:",y,m),n(_=>new Map(_).set(y,[]))}finally{s(m=>{const _=new Set(m);return _.delete(y),_})}},[]);S.useEffect(()=>{n(new Map),i(new Set([e])),s(new Set),u(e)},[e,u]);const d=S.useCallback(y=>{i(m=>{const _=new Set(m);return _.has(y)?_.delete(y):(_.add(y),t.has(y)||u(y)),_})},[t,u]),c=S.useCallback(()=>{n(new Map),i(new Set([e])),s(new Set),u(e)},[e,u]),h=(y,m)=>y.map(_=>{const v=r.has(_.path),w=a.has(_.path),C=t.get(_.path),k=_.name.startsWith(".");return g.jsxs("div",{children:[g.jsxs("div",{className:J("flex items-center gap-1 py-[3px] rounded cursor-pointer","hover:bg-muted",k&&"opacity-50"),style:{paddingLeft:`${m*14+6}px`,paddingRight:"6px"},onClick:()=>_.type==="dir"?d(_.path):l(_.path),children:[g.jsx("span",{className:"w-3 flex-shrink-0 text-muted-foreground",children:_.type==="dir"&&(w?g.jsx(Ws,{className:"h-2.5 w-2.5 animate-spin"}):v?g.jsx(AC,{className:"h-2.5 w-2.5"}):g.jsx(Hf,{className:"h-2.5 w-2.5"}))}),_.type==="dir"?v?g.jsx(Gs,{className:"h-3.5 w-3.5 text-blue-400 flex-shrink-0"}):g.jsx(Ih,{className:"h-3.5 w-3.5 text-blue-400 flex-shrink-0"}):g.jsx(kl,{className:"h-3.5 w-3.5 text-muted-foreground flex-shrink-0"}),g.jsx("span",{className:J("text-xs truncate leading-none",_.type==="dir"?"text-foreground":"text-muted-foreground"),title:_.path,children:_.name})]}),_.type==="dir"&&v&&g.jsxs("div",{children:[!C&&!w&&g.jsx("div",{className:"text-xs text-muted-foreground/50 py-0.5",style:{paddingLeft:`${(m+1)*14+6+16}px`},children:"—"}),(C==null?void 0:C.length)===0&&g.jsx("div",{className:"text-xs text-muted-foreground/50 py-0.5",style:{paddingLeft:`${(m+1)*14+6+16}px`},children:"empty"}),C&&C.length>0&&h(C,m+1)]})]},_.path)}),p=t.get(e),f=a.has(e),b=e.split("/").filter(Boolean).pop()??e;return g.jsxs(g.Fragment,{children:[o&&g.jsx(WH,{filePath:o,onClose:()=>l(null)}),g.jsxs("div",{className:"h-full flex flex-col bg-background text-foreground select-none",children:[g.jsxs("div",{className:"flex items-center justify-between px-3 h-9 border-b border-border flex-shrink-0",children:[g.jsx("span",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"Files"}),g.jsx("button",{className:"text-muted-foreground hover:text-foreground p-0.5 rounded transition-colors",onClick:c,title:"Refresh file tree",children:g.jsx(Ws,{className:J("h-3 w-3",f&&"animate-spin")})})]}),g.jsxs("div",{className:"flex items-center gap-1.5 px-3 py-2 border-b border-border flex-shrink-0",children:[g.jsx(Gs,{className:"h-3.5 w-3.5 text-blue-400 flex-shrink-0"}),g.jsx("span",{className:"text-xs text-foreground font-medium truncate",title:e,children:b})]}),g.jsx("div",{className:"flex-1 overflow-y-auto py-1 min-h-0",children:f&&!p?g.jsx("div",{className:"text-xs text-muted-foreground px-4 py-3",children:"Loading…"}):!p||p.length===0?g.jsx("div",{className:"text-xs text-muted-foreground px-4 py-3",children:"Empty folder"}):h(p,0)})]})]})}const Ik=e=>`cc_shortcuts_${e}`;function qH({open:e,onOpenChange:t,initialLabel:n,initialCommand:r,title:i,onSave:a}){const[s,o]=S.useState(n),[l,u]=S.useState(r);S.useEffect(()=>{e&&(o(n),u(r))},[e,n,r]);const d=()=>{const c=l.trim();c&&(a(s.trim()||c,c),t(!1))};return g.jsx(Xu,{open:e,onOpenChange:t,children:g.jsxs(po,{className:"sm:max-w-2xl max-h-[85vh] flex flex-col",children:[g.jsxs(fo,{children:[g.jsx(mo,{children:i}),g.jsx(bo,{children:"Write the command that will be sent to Claude when this shortcut is triggered."})]}),g.jsxs("div",{className:"space-y-4 flex-1 min-h-0 flex flex-col",children:[g.jsxs("div",{className:"space-y-2",children:[g.jsx(Mn,{htmlFor:"shortcut-label",children:"Label"}),g.jsx(Hs,{id:"shortcut-label",placeholder:"Give it a name (optional)",value:s,onChange:c=>o(c.target.value),className:"text-base",autoFocus:!0})]}),g.jsxs("div",{className:"space-y-2 flex-1 flex flex-col min-h-0",children:[g.jsx(Mn,{htmlFor:"shortcut-command",children:"Command"}),g.jsx("textarea",{id:"shortcut-command",placeholder:"Enter the command to send to Claude...",value:l,onChange:c=>u(c.target.value),className:J("flex-1 min-h-[200px] w-full rounded-md border border-input bg-background px-4 py-3","text-base leading-relaxed font-mono","ring-offset-background placeholder:text-muted-foreground","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2","resize-none"),onKeyDown:c=>{c.key==="Enter"&&(c.metaKey||c.ctrlKey)&&(c.preventDefault(),d())}})]})]}),g.jsxs(go,{className:"flex items-center justify-between sm:justify-between",children:[g.jsx("span",{className:"text-xs text-muted-foreground",children:"⌘↩ to save"}),g.jsxs("div",{className:"flex gap-2",children:[g.jsx(se,{variant:"outline",onClick:()=>t(!1),children:"Cancel"}),g.jsx(se,{onClick:d,disabled:!l.trim(),children:"Save"})]})]})]})})}function YH({projectId:e,onSend:t}){const[n,r]=S.useState([]),[i,a]=S.useState([]),[s,o]=S.useState(!1),[l,u]=S.useState(null);S.useEffect(()=>{try{const m=localStorage.getItem(Ik(e));r(m?JSON.parse(m):[])}catch{r([])}},[e]),S.useEffect(()=>{EC().then(a).catch(()=>a([]))},[]);const d=S.useCallback(m=>{const _=[],v=new Set;let w=m;const C=[];for(;w&&!v.has(w.id);)v.add(w.id),C.unshift(w),w=w.parentId?i.find(k=>k.id===w.parentId):void 0;for(const k of C)_.push(k.command);return _},[i]),c=S.useCallback(m=>{d(m).forEach((v,w)=>{setTimeout(()=>t(v+"\r"),w*500)})},[d,t]),h=m=>{r(m),localStorage.setItem(Ik(e),JSON.stringify(m))},p=()=>{u(null),o(!0)},f=(m,_)=>{_.stopPropagation(),u(m),o(!0)},b=(m,_)=>{h(l?n.map(v=>v.id===l.id?{...v,label:m,command:_}:v):[...n,{id:crypto.randomUUID(),label:m,command:_}]),u(null)},y=(m,_)=>{_.stopPropagation(),h(n.filter(v=>v.id!==m))};return g.jsxs("div",{className:"h-full flex flex-col bg-background text-foreground select-none",children:[g.jsxs("div",{className:"flex items-center justify-between px-3 h-9 border-b border-border flex-shrink-0",children:[g.jsx("span",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"Shortcuts"}),g.jsx("button",{className:"p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors",onClick:p,title:"New shortcut",children:g.jsx(du,{className:"h-3.5 w-3.5"})})]}),g.jsxs("div",{className:"flex-1 overflow-y-auto p-2 space-y-1.5 min-h-0",children:[i.length>0&&g.jsxs(g.Fragment,{children:[g.jsxs("div",{className:"flex items-center gap-1.5 px-1 pt-1 pb-0.5",children:[g.jsx(hu,{className:"h-3 w-3 text-muted-foreground"}),g.jsx("span",{className:"text-xs text-muted-foreground uppercase tracking-wider",children:"全局"})]}),i.map(m=>{var v;const _=m.parentId?(v=i.find(w=>w.id===m.parentId))==null?void 0:v.label:void 0;return g.jsxs("div",{className:J("group relative rounded px-3 py-2 cursor-pointer","bg-muted hover:bg-accent","border border-transparent hover:border-muted-foreground/30","transition-colors"),onClick:()=>c(m),title:_?`继承自「${_}」`:"Click to send",children:[g.jsx("div",{className:"text-xs font-medium text-foreground truncate leading-snug",children:m.label}),_&&g.jsxs("div",{className:"flex items-center gap-1 mt-0.5",children:[g.jsx(xl,{className:"h-2.5 w-2.5 text-muted-foreground"}),g.jsxs("span",{className:"text-xs text-muted-foreground truncate",children:["继承: ",_]})]}),!_&&m.label!==m.command&&g.jsx("div",{className:"text-xs text-muted-foreground font-mono truncate mt-0.5 leading-snug",children:m.command})]},m.id)}),n.length>0&&g.jsx("div",{className:"flex items-center gap-1.5 px-1 pt-2 pb-0.5",children:g.jsx("span",{className:"text-xs text-muted-foreground uppercase tracking-wider",children:"项目"})})]}),n.length===0&&i.length===0&&g.jsxs("div",{className:"flex flex-col items-center gap-2 py-8 text-muted-foreground/50",children:[g.jsx(hu,{className:"h-5 w-5"}),g.jsxs("p",{className:"text-xs text-center leading-relaxed",children:["No shortcuts yet.",g.jsx("br",{}),"Click ",g.jsx("strong",{className:"text-muted-foreground",children:"+"})," to add one."]})]}),n.map(m=>g.jsxs("div",{className:J("group relative rounded px-3 py-2 cursor-pointer","bg-muted hover:bg-accent","border border-transparent hover:border-muted-foreground/30","transition-colors"),onClick:()=>t(m.command+"\r"),title:"Click to send",children:[g.jsx("div",{className:"text-xs font-medium text-foreground truncate pr-10 leading-snug",children:m.label}),m.label!==m.command&&g.jsx("div",{className:"text-xs text-muted-foreground font-mono truncate mt-0.5 leading-snug pr-10",children:m.command}),g.jsxs("div",{className:"absolute top-1.5 right-1.5 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity",children:[g.jsx("button",{className:"p-0.5 rounded text-muted-foreground hover:text-blue-400 transition-colors",onClick:_=>f(m,_),title:"Edit shortcut",children:g.jsx(Vf,{className:"h-3 w-3"})}),g.jsx("button",{className:"p-0.5 rounded text-muted-foreground hover:text-red-400 transition-colors",onClick:_=>y(m.id,_),title:"Delete shortcut",children:g.jsx(wa,{className:"h-3 w-3"})})]})]},m.id))]}),g.jsx(qH,{open:s,onOpenChange:o,initialLabel:(l==null?void 0:l.label)??"",initialCommand:(l==null?void 0:l.command)??"",title:l?"Edit Shortcut":"New Shortcut",onSave:b})]})}function BA(e){return new Date(e).toLocaleString("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})}function UA(e){return`这是我们上一次的聊天记录,请你回忆:
|
|
431
431
|
|
|
432
432
|
${e.messages.map(n=>`[${n.role==="user"?"User":"Assistant"}]: ${n.content}`).join(`
|
|
433
433
|
|
package/frontend/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/terminal.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>CC Web</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-C_RCd4kd.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-CQjbS4zv.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|