@tom2012/cc-web 2026.6.13-a → 2026.6.13-b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/backend/dist/__tests__/sync-refactor.test.d.ts +2 -0
  2. package/backend/dist/__tests__/sync-refactor.test.d.ts.map +1 -0
  3. package/backend/dist/__tests__/sync-refactor.test.js +212 -0
  4. package/backend/dist/__tests__/sync-refactor.test.js.map +1 -0
  5. package/backend/dist/index.d.ts.map +1 -1
  6. package/backend/dist/index.js +2 -0
  7. package/backend/dist/index.js.map +1 -1
  8. package/backend/dist/routes/sync.d.ts.map +1 -1
  9. package/backend/dist/routes/sync.js +119 -1
  10. package/backend/dist/routes/sync.js.map +1 -1
  11. package/backend/dist/sync-config.d.ts +10 -0
  12. package/backend/dist/sync-config.d.ts.map +1 -1
  13. package/backend/dist/sync-config.js +53 -3
  14. package/backend/dist/sync-config.js.map +1 -1
  15. package/backend/dist/sync-dirty.d.ts +12 -0
  16. package/backend/dist/sync-dirty.d.ts.map +1 -0
  17. package/backend/dist/sync-dirty.js +165 -0
  18. package/backend/dist/sync-dirty.js.map +1 -0
  19. package/backend/dist/sync-migrate.d.ts +15 -0
  20. package/backend/dist/sync-migrate.d.ts.map +1 -0
  21. package/backend/dist/sync-migrate.js +92 -0
  22. package/backend/dist/sync-migrate.js.map +1 -0
  23. package/backend/dist/sync-scheduler.d.ts.map +1 -1
  24. package/backend/dist/sync-scheduler.js +3 -1
  25. package/backend/dist/sync-scheduler.js.map +1 -1
  26. package/backend/dist/sync-service.d.ts.map +1 -1
  27. package/backend/dist/sync-service.js +34 -16
  28. package/backend/dist/sync-service.js.map +1 -1
  29. package/backend/dist/sync-state.d.ts +5 -0
  30. package/backend/dist/sync-state.d.ts.map +1 -0
  31. package/backend/dist/sync-state.js +95 -0
  32. package/backend/dist/sync-state.js.map +1 -0
  33. package/frontend/dist/assets/{ChatOverlay-Co-5g3JZ.js → ChatOverlay-Cg09i5qF.js} +1 -1
  34. package/frontend/dist/assets/{ClaudeMemPage-pUcWBuMw.js → ClaudeMemPage-CT87pX5z.js} +1 -1
  35. package/frontend/dist/assets/{GraphPreview-7YfqasC1.js → GraphPreview-LQt3-skN.js} +2 -2
  36. package/frontend/dist/assets/{MobilePage-pjdKu2mO.js → MobilePage-NHtpiQsi.js} +3 -3
  37. package/frontend/dist/assets/{OfficePreview-CsF2KNUB.js → OfficePreview-CH1bJV2V.js} +2 -2
  38. package/frontend/dist/assets/{PdfPreview-BszKtSXe.js → PdfPreview-BDDzOq58.js} +1 -1
  39. package/frontend/dist/assets/{ProjectPage-BA0XLC3n.js → ProjectPage-BoOR1Zr9.js} +5 -5
  40. package/frontend/dist/assets/ProjectSettingsPage-ClHkL2L4.js +13 -0
  41. package/frontend/dist/assets/{SettingsPage-D_rrejtY.js → SettingsPage-Q7dhf4gJ.js} +2 -2
  42. package/frontend/dist/assets/{SkillHubPage-CCfKppvZ.js → SkillHubPage-CI5o_FsS.js} +1 -1
  43. package/frontend/dist/assets/{check-circle-2-DtSQDsJD.js → check-circle-2-CZgbn9H8.js} +1 -1
  44. package/frontend/dist/assets/{chevron-down-BXO9hQjV.js → chevron-down-efPsOYlh.js} +1 -1
  45. package/frontend/dist/assets/{file-text-DhrmIv6Q.js → file-text-mpbJn406.js} +1 -1
  46. package/frontend/dist/assets/index-BjydjBX7.js +75 -0
  47. package/frontend/dist/assets/index-DS0RkMkF.css +1 -0
  48. package/frontend/dist/assets/{index-1dkP8nIN.js → index-Di-Iyd_L.js} +1 -1
  49. package/frontend/dist/assets/{index-CwYY2lt5.js → index-oPZyCxeH.js} +1 -1
  50. package/frontend/dist/assets/{jszip.min-DRHjMWSQ.js → jszip.min-nePKj7L6.js} +1 -1
  51. package/frontend/dist/assets/save-BYi9FbQu.js +7 -0
  52. package/frontend/dist/assets/{search-BIHCBFC7.js → search-09qCXbdG.js} +1 -1
  53. package/frontend/dist/assets/{select-C_BJUfwv.js → select-De5oupVM.js} +1 -1
  54. package/frontend/dist/assets/tabs-CQZcN-v5.js +7 -0
  55. package/frontend/dist/assets/textarea-Ge2i0ho4.js +1 -0
  56. package/frontend/dist/index.html +2 -2
  57. package/package.json +1 -1
  58. package/frontend/dist/assets/index-CR8bVXG9.css +0 -1
  59. package/frontend/dist/assets/index-D2KpHlv8.js +0 -75
  60. package/frontend/dist/assets/tabs-3fLjxolg.js +0 -13
@@ -0,0 +1,13 @@
1
+ import{c as e,aM as s,b7 as a,aN as r,aP as n,r as t,bD as c,aO as o,j as i,B as l,aI as d,aT as m,I as x,U as j,d as p,X as h,m as u,bE as f,t as y,aU as g,aV as b}from"./index-BjydjBX7.js";import{T as N}from"./textarea-Ge2i0ho4.js";import{S as v}from"./save-BYi9FbQu.js";
2
+ /**
3
+ * @license lucide-react v0.309.0 - ISC
4
+ *
5
+ * This source code is licensed under the ISC license.
6
+ * See the LICENSE file in the root directory of this source tree.
7
+ */const w=e("CloudOff",[["path",{d:"m2 2 20 20",key:"1ooewy"}],["path",{d:"M5.782 5.782A7 7 0 0 0 9 19h8.5a4.5 4.5 0 0 0 1.307-.193",key:"yfwify"}],["path",{d:"M21.532 16.5A4.5 4.5 0 0 0 17.5 10h-1.79A7.008 7.008 0 0 0 10 5.07",key:"jlfiyv"}]]),k=e("Cloud",[["path",{d:"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z",key:"p7xjir"}]]);
8
+ /**
9
+ * @license lucide-react v0.309.0 - ISC
10
+ *
11
+ * This source code is licensed under the ISC license.
12
+ * See the LICENSE file in the root directory of this source tree.
13
+ */function _(e){if(!e)return"";const s=Date.now()-e,a=Math.floor(s/6e4);if(a<1)return"just now";if(a<60)return`${a}m`;const r=Math.floor(a/60);return r<24?`${r}h`:new Date(e).toLocaleString()}function C(){const{t:e}=s(),{id:C}=a(),S=r(),M=n(e=>e.projects.find(e=>e.id===C)),[z,A]=t.useState("loading"),[E,I]=t.useState(null),[D,T]=t.useState(""),[$,B]=t.useState(""),[O,P]=t.useState(!1),[R,U]=t.useState(!1),[H,L]=t.useState(0),V=t.useCallback(async()=>{if(C)try{const e=await c(C);I(e),T(e.path),B(e.excludes.join("\n")),A("ready")}catch(e){A(e instanceof Error&&/forbidden/i.test(e.message)?"forbidden":"error")}},[C]);t.useEffect(()=>{V()},[V]),o({onStart:e=>{e.projectId===C&&(U(!0),L(0))},onProgress:e=>{e.projectId===C&&L(e.filesTransferred)},onDone:e=>{e.projectId===C&&(U(!1),L(0),V())}});const Z=(null==M?void 0:M.name)??C??"",q=i.jsx("header",{className:"border-b sticky top-0 bg-background z-10",children:i.jsxs("div",{className:"w-full px-4 sm:px-6 h-14 flex items-center gap-3",children:[i.jsxs(l,{variant:"ghost",size:"sm",onClick:()=>S("/"),children:[i.jsx(d,{className:"h-4 w-4 mr-1"}),e("projsync.back")]}),i.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[i.jsx(m,{className:"h-5 w-5 shrink-0"}),i.jsx("span",{className:"font-semibold text-lg truncate",children:Z}),i.jsxs("span",{className:"text-muted-foreground text-sm shrink-0",children:["· ",e("projsync.title")]})]})]})});if("loading"===z)return i.jsx("div",{className:"min-h-screen bg-background",children:q});if("forbidden"===z||"error"===z)return i.jsxs("div",{className:"min-h-screen bg-background",children:[q,i.jsxs("div",{className:"max-w-2xl mx-auto px-4 py-20 text-center",children:[i.jsx(w,{className:"h-12 w-12 text-muted-foreground mx-auto mb-4"}),i.jsx("p",{className:"text-muted-foreground text-sm",children:e("forbidden"===z?"projsync.forbidden":"projsync.load_error")})]})]});const F=E,G=!!F.path;return i.jsxs("div",{className:"min-h-screen bg-background",children:[q,i.jsxs("main",{className:"max-w-2xl mx-auto px-4 py-8 space-y-6",children:[!F.connectionReady&&i.jsxs("div",{className:"rounded-lg border border-amber-500/40 bg-amber-500/10 px-4 py-3 text-sm",children:[e("projsync.no_connection")," ",i.jsx("button",{className:"underline hover:text-foreground",onClick:()=>S("/settings"),children:e("projsync.go_global")})]}),i.jsxs("section",{className:"space-y-2",children:[i.jsxs("label",{className:"text-sm font-medium flex items-center gap-2",children:[i.jsx(k,{className:"h-4 w-4 text-muted-foreground"}),e("projsync.remote_path")]}),i.jsx(x,{value:D,onChange:e=>T(e.target.value),placeholder:"/home/user/backups/my-project",spellCheck:!1}),i.jsx("p",{className:"text-xs text-muted-foreground",children:e("projsync.remote_path_hint")})]}),i.jsxs("section",{className:"space-y-2",children:[i.jsx("label",{className:"text-sm font-medium",children:e("projsync.excludes")}),i.jsx(N,{value:$,onChange:e=>B(e.target.value),placeholder:"*.log\ntmp/",rows:4,spellCheck:!1,className:"font-mono text-xs"}),i.jsx("p",{className:"text-xs text-muted-foreground",children:e("projsync.excludes_hint")})]}),i.jsx("div",{className:"flex items-center gap-2",children:i.jsxs(l,{onClick:()=>{(async()=>{if(C){P(!0);try{const s=$.split("\n").map(e=>e.trim()).filter(Boolean),a=await f(C,{path:D.trim(),excludes:s});I(a),T(a.path),B(a.excludes.join("\n")),y.success(e("projsync.saved"))}catch(s){y.error(s instanceof Error?s.message:e("projsync.save_failed"))}finally{P(!1)}}})()},disabled:O,children:[O?i.jsx(j,{className:"h-4 w-4 mr-2 animate-spin"}):i.jsx(v,{className:"h-4 w-4 mr-2"}),e("projsync.save")]})}),i.jsxs("section",{className:"rounded-xl border border-border bg-card p-4 space-y-3",children:[i.jsxs("div",{className:"flex items-center justify-between text-sm",children:[i.jsx("span",{className:"text-muted-foreground",children:e("projsync.status")}),i.jsx("span",{className:p("font-medium",F.dirty?"text-amber-500":G?"text-green-500":"text-muted-foreground"),children:G?F.dirty?e("projsync.dirty"):e("projsync.synced"):e("projsync.not_configured")})]}),i.jsxs("div",{className:"flex items-center justify-between text-sm",children:[i.jsx("span",{className:"text-muted-foreground",children:e("projsync.last_sync")}),i.jsx("span",{children:F.lastSyncAt?_(F.lastSyncAt):e("projsync.never")})]}),i.jsxs("div",{className:"flex items-center justify-between text-sm",children:[i.jsx("span",{className:"text-muted-foreground",children:e("projsync.direction")}),i.jsx("span",{className:"capitalize",children:F.direction})]}),i.jsx("div",{className:"flex items-center gap-2 pt-1",children:R?i.jsxs(l,{variant:"outline",size:"sm",onClick:()=>{(async()=>{if(C)try{await g(C)}catch{}})()},children:[i.jsx(h,{className:"h-4 w-4 mr-1"}),e("projsync.cancel"),H>0?` (${H})`:""]}):i.jsxs(l,{size:"sm",onClick:()=>{(async()=>{if(C){U(!0);try{const s=await b(C);s.ok?y.success(e("projsync.sync_done",{files:s.filesTransferred})):y.error(e("projsync.sync_failed_reason",{reason:s.reason??""}))}catch(s){y.error(s instanceof Error?s.message:e("projsync.sync_failed"))}finally{U(!1),V()}}})()},disabled:!G||!F.connectionReady,title:G?void 0:e("projsync.set_path_first"),children:[i.jsx(u,{className:"h-4 w-4 mr-1"}),e("projsync.sync_now")]})})]})]})]})}export{C as ProjectSettingsPage};
@@ -1,4 +1,4 @@
1
- import{c as e,r as s,ab as t,ba as a,j as n,ad as c,ac as l,bb as i,a7 as r,d as o,aM as d,aO as h,bc as m,t as x,a0 as u,I as p,B as g,U as j,X as b,D as y,bd as f,be as _,bf as v,bg as k,u as N,bh as w,T as C,bi as S,bj as M,bk as T,bl as E,bm as R,aN as I,bn as P,bo as H,i as L,S as z,bp as F,aI as q,L as A,s as U,bq as V}from"./index-D2KpHlv8.js";import{S as O,U as G,T as B,a as D,b as Q,c as W}from"./tabs-3fLjxolg.js";import{u as Z,S as $,a as X,b as J,d as K,e as Y}from"./select-C_BJUfwv.js";import{C as ee}from"./check-circle-2-DtSQDsJD.js";import"./index-1dkP8nIN.js";import"./chevron-down-BXO9hQjV.js";
1
+ import{c as e,r as s,ab as t,ba as a,j as n,ad as c,ac as l,bb as i,a7 as r,d as o,aM as d,aO as h,bc as m,t as x,a0 as u,I as p,B as j,U as g,X as b,D as y,bd as f,be as _,bf as v,bg as k,u as N,bh as w,T as C,bi as S,bj as M,bk as T,bl as E,bm as R,aN as I,bn as P,bo as H,i as L,S as z,bp as F,aI as q,L as A,s as U,bq as V}from"./index-BjydjBX7.js";import{U as O,T as G,a as B,b as D,c as Q}from"./tabs-CQZcN-v5.js";import{u as W,S as Z,a as $,b as X,d as J,e as K}from"./select-De5oupVM.js";import{S as Y}from"./save-BYi9FbQu.js";import{C as ee}from"./check-circle-2-CZgbn9H8.js";import"./index-Di-Iyd_L.js";import"./chevron-down-efPsOYlh.js";
2
2
  /**
3
3
  * @license lucide-react v0.309.0 - ISC
4
4
  *
@@ -10,4 +10,4 @@ import{c as e,r as s,ab as t,ba as a,j as n,ad as c,ac as l,bb as i,a7 as r,d as
10
10
  *
11
11
  * This source code is licensed under the ISC license.
12
12
  * See the LICENSE file in the root directory of this source tree.
13
- */var oe="Switch",[de]=r(oe),[he,me]=de(oe),xe=s.forwardRef((e,i)=>{const{__scopeSwitch:r,name:o,checked:d,defaultChecked:h,required:m,disabled:x,value:u="on",onCheckedChange:p,form:g,...j}=e,[b,y]=s.useState(null),f=t(i,e=>y(e)),_=s.useRef(!1),v=!b||(g||!!b.closest("form")),[k,N]=a({prop:d,defaultProp:h??!1,onChange:p,caller:oe});return n.jsxs(he,{scope:r,checked:k,disabled:x,children:[n.jsx(c.button,{type:"button",role:"switch","aria-checked":k,"aria-required":m,"data-state":je(k),"data-disabled":x?"":void 0,disabled:x,value:u,...j,ref:f,onClick:l(e.onClick,e=>{N(e=>!e),v&&(_.current=e.isPropagationStopped(),_.current||e.stopPropagation())})}),v&&n.jsx(ge,{control:b,bubbles:!_.current,name:o,value:u,checked:k,required:m,disabled:x,form:g,style:{transform:"translateX(-100%)"}})]})});xe.displayName=oe;var ue="SwitchThumb",pe=s.forwardRef((e,s)=>{const{__scopeSwitch:t,...a}=e,l=me(ue,t);return n.jsx(c.span,{"data-state":je(l.checked),"data-disabled":l.disabled?"":void 0,...a,ref:s})});pe.displayName=ue;var ge=s.forwardRef(({__scopeSwitch:e,control:a,checked:c,bubbles:l=!0,...r},o)=>{const d=s.useRef(null),h=t(d,o),m=Z(c),x=i(a);return s.useEffect(()=>{const e=d.current;if(!e)return;const s=window.HTMLInputElement.prototype,t=Object.getOwnPropertyDescriptor(s,"checked").set;if(m!==c&&t){const s=new Event("click",{bubbles:l});t.call(e,c),e.dispatchEvent(s)}},[m,c,l]),n.jsx("input",{type:"checkbox","aria-hidden":!0,defaultChecked:c,...r,tabIndex:-1,ref:h,style:{...r.style,...x,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});function je(e){return e?"checked":"unchecked"}ge.displayName="SwitchBubbleInput";var be=xe,ye=pe;const fe=s.forwardRef(({className:e,...s},t)=>n.jsx(be,{className:o("peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",e),...s,ref:t,children:n.jsx(ye,{className:o("pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0")})}));fe.displayName=be.displayName;function _e(){const{t:e}=d(),[t,a]=s.useState(null),[c,l]=s.useState(!0),[i,r]=s.useState(!1),[o,N]=s.useState(!1),[w,C]=s.useState(!1),[S,M]=s.useState(!1),[T,E]=s.useState(null),[R,I]=s.useState(0),[P,H]=s.useState(""),[L,z]=s.useState("");h({onStart:e=>{E(e.projectId),I(0)},onProgress:e=>{E(e.projectId),I(e.filesTransferred)},onDone:()=>{E(null),I(0)}}),s.useEffect(()=>{let s=!1;return m().then(e=>{s||(a(e),z(e.defaultExcludes.join("\n")))}).catch(s=>x.error(e("sync_section.load_failed",{message:s.message}))).finally(()=>{s||l(!1)}),()=>{s=!0}},[e]);const F=(e,s)=>{a(t=>t?{...t,[e]:s}:t)};return c||!t?n.jsx("div",{className:"text-sm text-muted-foreground",children:e("sync_section.loading")}):n.jsxs("div",{className:"space-y-5",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-3",children:e("sync_section.server_section")}),n.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-host",children:e("sync_section.host")}),n.jsx(p,{id:"sync-host",value:t.host,onChange:e=>F("host",e.target.value),placeholder:"example.com"})]}),n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-port",children:e("sync_section.port")}),n.jsx(p,{id:"sync-port",type:"number",value:t.port,onChange:e=>F("port",Number(e.target.value)||22)})]}),n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-user",children:e("sync_section.user")}),n.jsx(p,{id:"sync-user",value:t.user,onChange:e=>F("user",e.target.value),placeholder:"tom"})]}),n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-remote",children:e("sync_section.remote_root")}),n.jsx(p,{id:"sync-remote",value:t.remoteRoot,onChange:e=>F("remoteRoot",e.target.value),placeholder:"/data/projects"}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",dangerouslySetInnerHTML:{__html:e("sync_section.remote_root_hint")}})]})]})]}),n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-3",children:e("sync_section.auth_section")}),n.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[n.jsxs("div",{children:[n.jsx(u,{children:e("sync_section.auth_method")}),n.jsxs($,{value:t.authMethod,onValueChange:e=>F("authMethod",e),children:[n.jsx(X,{children:n.jsx(J,{})}),n.jsxs(K,{children:[n.jsx(Y,{value:"key",children:"SSH key"}),n.jsx(Y,{value:"password",children:e("sync_section.auth_password")})]})]})]}),"key"===t.authMethod?n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-key",children:e("sync_section.key_path")}),n.jsx(p,{id:"sync-key",value:t.keyPath??"",onChange:e=>F("keyPath",e.target.value),placeholder:"~/.ssh/id_rsa"})]}):n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-pw",children:e("sync_section.password")}),n.jsx(p,{id:"sync-pw",type:"password",value:P,onChange:e=>H(e.target.value),placeholder:t.passwordSet?e("sync_section.password_set_placeholder"):e("sync_section.password_unset_placeholder")}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",dangerouslySetInnerHTML:{__html:e("sync_section.sshpass_hint")}})]})]})]}),n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-3",children:e("sync_section.strategy_section")}),n.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[n.jsxs("div",{children:[n.jsx(u,{children:e("sync_section.direction")}),n.jsxs($,{value:t.direction,onValueChange:e=>F("direction",e),children:[n.jsx(X,{children:n.jsx(J,{})}),n.jsxs(K,{children:[n.jsx(Y,{value:"push",children:e("sync_section.push_label")}),n.jsx(Y,{value:"pull",children:e("sync_section.pull_label")}),n.jsx(Y,{value:"bidirectional",children:e("sync_section.bidirectional_label")})]})]})]}),n.jsxs("div",{className:"flex items-end gap-2",children:[n.jsxs("div",{className:"flex-1",children:[n.jsx(u,{htmlFor:"sync-cron",children:e("sync_section.cron_label")}),n.jsx(p,{id:"sync-cron",value:t.schedule.cron,onChange:e=>F("schedule",{...t.schedule,cron:e.target.value}),placeholder:"0 3 * * *"}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",dangerouslySetInnerHTML:{__html:e("sync_section.cron_hint")}})]}),n.jsxs("div",{className:"flex items-center gap-2 pb-1.5",children:[n.jsx(fe,{checked:t.schedule.enabled,onCheckedChange:e=>F("schedule",{...t.schedule,enabled:e})}),n.jsx("span",{className:"text-xs text-muted-foreground",children:e("sync_section.enable_label")})]})]})]})]}),n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-3",children:e("sync_section.exclude_section")}),n.jsx("textarea",{value:L,onChange:e=>z(e.target.value),rows:6,className:"w-full font-mono text-xs p-2 rounded border border-input bg-background resize-y",placeholder:"node_modules/\n.git/objects/\n*.log"}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",dangerouslySetInnerHTML:{__html:e("sync_section.exclude_hint")}})]}),n.jsxs("div",{className:"flex flex-wrap gap-2 pt-2 border-t",children:[n.jsxs(g,{onClick:()=>{(async()=>{if(t){r(!0);try{const s=L.split("\n").map(e=>e.trim()).filter(Boolean),n={host:t.host,port:t.port,user:t.user,authMethod:t.authMethod,keyPath:t.keyPath,remoteRoot:t.remoteRoot,direction:t.direction,defaultExcludes:s,schedule:t.schedule};P&&"__keep__"!==P&&(n.password=P);const c=await f(n);a(c),z(c.defaultExcludes.join("\n")),H(""),x.success(e("sync_section.saved"))}catch(s){x.error(e("sync_section.save_failed",{message:s.message}))}finally{r(!1)}}})()},disabled:i,children:[i?n.jsx(j,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(O,{className:"h-3.5 w-3.5 mr-1.5"}),e("sync_section.save_button")]}),n.jsxs(g,{variant:"outline",onClick:()=>{(async()=>{N(!0);try{const s=await _();s.ok?x.success(s.message||e("sync_section.test_ok")):x.error(s.message||e("sync_section.test_failed"))}catch(s){x.error(e("sync_section.test_failed_with_reason",{message:s.message}))}finally{N(!1)}})()},disabled:o,children:[o?n.jsx(j,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(ie,{className:"h-3.5 w-3.5 mr-1.5"}),e("sync_section.test_button")]}),n.jsx("div",{className:"flex-1"}),w&&T&&n.jsx("span",{className:"text-xs text-muted-foreground self-center mr-1 tabular-nums",children:R>0?e("sync_section.syncing_with_files",{project:T,files:R}):e("sync_section.syncing_no_files",{project:T})}),n.jsxs(g,{variant:"outline",onClick:()=>{(async()=>{C(!0);try{const s=await v(),t=s.results.filter(e=>e.ok).length,a=s.results.filter(e=>e.skipped).length,n=s.results.filter(e=>"cancelled"===e.reason).length,c=s.total-t-a-n;n>0?x.info(e("sync_section.bulk_cancelled_toast",{ok:t,skipped:a,cancelled:n,failed:c})):x.success(e("sync_section.bulk_done_toast",{ok:t,skipped:a,failed:c}))}catch(s){x.error(e("sync_section.bulk_failed_toast",{message:s.message}))}finally{C(!1),M(!1),E(null),I(0)}})()},disabled:w,title:e("sync_section.sync_all_title"),children:[w?n.jsx(j,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(G,{className:"h-3.5 w-3.5 mr-1.5"}),e("sync_section.sync_all_button")]}),w&&n.jsxs(g,{variant:"outline",onClick:()=>{(async()=>{if(w&&!S){M(!0);try{await k(),x.info(e("sync_section.cancel_requested"))}catch(s){x.error(e("sync_section.cancel_failed",{message:s.message})),M(!1)}}})()},disabled:S,title:e("sync_section.cancel_button_title"),children:[S?n.jsx(j,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(b,{className:"h-3.5 w-3.5 mr-1.5"}),e("sync_section.cancel_button")]})]}),n.jsxs("div",{className:"border-t pt-4 text-xs text-muted-foreground",children:["Per-project push/pull: from inside a project, click the ",n.jsx(G,{className:"inline h-3 w-3"})," / ",n.jsx(y,{className:"inline h-3 w-3"})," buttons in the header. Or call ",n.jsx("code",{children:"POST /api/sync/project/:id"})," with body ",n.jsx("code",{children:'{ "direction": "push" }'}),"."]})]})}function ve(){const e=N(),[t,a]=s.useState(null),[c,l]=s.useState(!0),[i,r]=s.useState(""),[o,d]=s.useState(!1);s.useEffect(()=>{let e=!1;return w().then(s=>{e||a(s)}).catch(()=>{e||a({configured:!1,needsReset:!1})}).finally(()=>{e||l(!1)}),()=>{e=!0}},[]);return n.jsxs("div",{className:"space-y-6",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-1",children:"CCWeb Hub 直接提交"}),n.jsxs("p",{className:"text-xs text-muted-foreground",children:['配置你的 GitHub PAT 后,在 Quick Prompts / Agent Prompts 卡片右键选择"共享"时可一键直接提交 Issue 到 ',n.jsx("code",{children:"zbc0315/ccweb-hub"}),"。 ccweb 本身不自带 token —— 使用你自己的账号身份提交,归属清晰,互不影响。"]})]}),c?n.jsxs("div",{className:"text-sm text-muted-foreground flex items-center gap-2",children:[n.jsx(j,{className:"h-4 w-4 animate-spin"}),"加载中…"]}):n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"rounded-md border px-3 py-2.5 text-xs flex items-center gap-2",children:(null==t?void 0:t.configured)?n.jsxs(n.Fragment,{children:[n.jsx(ee,{className:"h-4 w-4 text-green-500 shrink-0"}),n.jsx("span",{children:"已配置 token,可直接提交"}),n.jsx("div",{className:"flex-1"}),n.jsxs(g,{size:"sm",variant:"outline",onClick:()=>{(async()=>{if(await e({title:"清除 Hub Token",description:"清除后将无法直接提交到 ccweb-hub,需要重新配置 token。确认?",destructive:!0,confirmLabel:"清除"}))try{await S(),a({configured:!1,needsReset:!1}),x.success("已清除")}catch(s){x.error(`清除失败: ${s.message}`)}})()},children:[n.jsx(C,{className:"h-3.5 w-3.5 mr-1"}),"清除"]})]}):(null==t?void 0:t.needsReset)?n.jsxs(n.Fragment,{children:[n.jsx(te,{className:"h-4 w-4 text-amber-500 shrink-0"}),n.jsx("span",{children:"之前的 token 已失效(服务端密钥可能已轮换),请重新设置"})]}):n.jsxs(n.Fragment,{children:[n.jsx(te,{className:"h-4 w-4 text-muted-foreground shrink-0"}),n.jsx("span",{children:"尚未配置 token"})]})}),n.jsxs("div",{className:"rounded-md border bg-muted/30 px-3 py-2.5 text-xs space-y-2",children:[n.jsx("div",{className:"font-medium text-foreground",children:"如何获取 token"}),n.jsxs("ol",{className:"list-decimal list-inside space-y-1 text-muted-foreground",children:[n.jsxs("li",{children:["打开"," ",n.jsxs("a",{href:"https://github.com/settings/personal-access-tokens/new",target:"_blank",rel:"noopener noreferrer",className:"text-blue-500 hover:underline inline-flex items-center gap-0.5",children:["GitHub fine-grained PAT",n.jsx(ne,{className:"h-3 w-3"})]})," ","创建页"]}),n.jsxs("li",{children:[n.jsx("strong",{className:"text-foreground",children:"Repository access"}),':选 "Only select repositories",添加 ',n.jsx("code",{children:"zbc0315/ccweb-hub"})]}),n.jsxs("li",{children:[n.jsx("strong",{className:"text-foreground",children:"Repository permissions → Issues"}),':设置为 "Read and write"']}),n.jsx("li",{children:"其余权限保持默认(全部无访问)"}),n.jsx("li",{children:"生成后复制 token 粘贴到下方"})]})]}),n.jsxs("div",{className:"space-y-2",children:[n.jsxs(u,{htmlFor:"hub-token",className:"text-xs",children:["GitHub Token ",(null==t?void 0:t.configured)&&n.jsx("span",{className:"text-muted-foreground",children:"(填写会覆盖现有 token)"})]}),n.jsx(p,{id:"hub-token",type:"password",placeholder:"github_pat_...",value:i,onChange:e=>r(e.target.value),autoComplete:"off",spellCheck:!1}),n.jsxs("p",{className:"text-xs text-muted-foreground",children:["Token 以 AES-256-GCM 加密存储于 ",n.jsx("code",{children:"~/.ccweb/hub-auth/"}),";per-user 独立,不会被其他用户读到。"]})]}),n.jsx("div",{className:"flex gap-2 pt-2 border-t",children:n.jsxs(g,{onClick:()=>{(async()=>{const e=i.trim();if(e){d(!0);try{const s=await M(e);a(s),r(""),x.success("已保存")}catch(s){x.error(`保存失败: ${s.message}`)}finally{d(!1)}}else x.error("请输入 token")})()},disabled:o||!i.trim(),children:[o?n.jsx(j,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(O,{className:"h-3.5 w-3.5 mr-1.5"}),"保存"]})})]})]})}function ke(){const{t:e,i18n:s}=d();return n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(le,{className:"h-4 w-4 text-muted-foreground"}),n.jsxs($,{value:s.language,onValueChange:async t=>{if(T.includes(t)){try{localStorage.setItem(E,t)}catch{}await s.changeLanguage(t);try{await R(t)}catch{x.error(e("language.switch_failed"))}}},children:[n.jsx(X,{className:"w-40",children:n.jsx(J,{})}),n.jsxs(K,{children:[n.jsx(Y,{value:"zh",children:e("language.zh")}),n.jsx(Y,{value:"en",children:e("language.en")})]})]})]})}function Ne(){const{t:e}=d(),t=I(),[a]=P(),c=a.get("tab")||"sync",[l,i]=s.useState(()=>H()),[r,o]=s.useState(!1),[h,m]=s.useState({webhookEnabled:!1}),[j,b]=s.useState(""),[y,f]=s.useState(!1),[_,v]=s.useState(()=>L(z.usageMonitorTool,"claude"));s.useEffect(()=>{F().then(e=>{m(e),b(e.webhookUrl??"")}).catch(()=>{})},[]);const k=(e,s)=>{const t=parseInt(s,10);isNaN(t)||t<1||(i(s=>({...s,[e]:t})),o(!0))};return n.jsx("div",{className:"min-h-screen bg-background",children:n.jsxs("div",{className:"max-w-3xl mx-auto p-6",children:[n.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[n.jsxs(g,{variant:"ghost",size:"sm",onClick:()=>t("/"),children:[n.jsx(q,{className:"h-4 w-4 mr-1"}),e("common.back")]}),n.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:e("settings.title")})]}),n.jsxs(B,{defaultValue:c,children:[n.jsxs(D,{className:"mb-4",children:[n.jsxs(Q,{value:"sync",children:[n.jsx(re,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_sync")]}),n.jsxs(Q,{value:"hub",children:[n.jsx(ce,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_hub")]}),n.jsxs(Q,{value:"notifications",children:[n.jsx(ae,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_notifications")]}),n.jsxs(Q,{value:"pomodoro",children:[n.jsx(A,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_pomodoro")]}),n.jsxs(Q,{value:"usage",children:[n.jsx(se,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_usage")]}),n.jsxs(Q,{value:"language",children:[n.jsx(le,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_language")]})]}),n.jsx(W,{value:"sync",children:n.jsx(_e,{})}),n.jsx(W,{value:"hub",children:n.jsx(ve,{})}),n.jsx(W,{value:"notifications",children:n.jsxs("div",{className:"space-y-6",children:[n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-2",children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.browser_notify.title")}),n.jsx("p",{className:"text-xs text-muted-foreground",children:e("settings.browser_notify.description")})]}),n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-3",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.webhook.title")}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:e("settings.webhook.description")})]}),n.jsxs("div",{className:"space-y-1.5",children:[n.jsx(u,{className:"text-xs",children:"Webhook URL"}),n.jsxs("div",{className:"flex gap-2",children:[n.jsx(p,{placeholder:"https://hooks.slack.com/...",value:j,onChange:e=>b(e.target.value),className:"font-mono text-xs"}),n.jsx(g,{size:"sm",onClick:()=>{(async()=>{f(!0);try{const s=await V({webhookEnabled:j.trim().length>0,webhookUrl:j.trim()||void 0});m(s),x.success(e("settings.webhook.saved"))}catch{x.error(e("settings.webhook.save_failed"))}finally{f(!1)}})()},disabled:y,children:e(y?"common.saving":"common.save")})]}),h.webhookEnabled&&h.webhookUrl&&n.jsxs("p",{className:"text-xs text-green-500",children:[e("settings.webhook.enabled_prefix")," ",h.webhookUrl]})]})]})]})}),n.jsx(W,{value:"pomodoro",children:n.jsxs("div",{className:"space-y-6",children:[n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-4",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.pomodoro.section_title")}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:e("settings.pomodoro.section_desc")})]}),n.jsxs("div",{className:"grid grid-cols-2 gap-6 max-w-xs",children:[n.jsxs("div",{className:"space-y-1.5",children:[n.jsx(u,{className:"text-xs",children:e("settings.pomodoro.work_minutes")}),n.jsx(p,{type:"number",min:1,max:120,value:l.workMinutes,onChange:e=>k("workMinutes",e.target.value),className:"w-full"})]}),n.jsxs("div",{className:"space-y-1.5",children:[n.jsx(u,{className:"text-xs",children:e("settings.pomodoro.break_minutes")}),n.jsx(p,{type:"number",min:1,max:60,value:l.breakMinutes,onChange:e=>k("breakMinutes",e.target.value),className:"w-full"})]})]}),r&&n.jsxs(g,{size:"sm",onClick:()=>{U(z.pomodoroConfig,l,!0),o(!1),x.success(e("settings.pomodoro.saved"))},children:[n.jsx(O,{className:"h-3.5 w-3.5 mr-1.5"}),e("common.save")]})]}),n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-2",children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.pomodoro.howto_title")}),n.jsxs("ul",{className:"text-xs text-muted-foreground space-y-1 list-disc list-inside",children:[n.jsxs("li",{children:[n.jsx(A,{className:"h-3 w-3 inline-block mx-0.5"})," ",e("settings.pomodoro.howto_item_1")]}),n.jsx("li",{children:e("settings.pomodoro.howto_item_2")}),n.jsx("li",{children:e("settings.pomodoro.howto_item_3")}),n.jsx("li",{children:e("settings.pomodoro.howto_item_4")}),n.jsx("li",{children:e("settings.pomodoro.howto_item_5")})]})]})]})}),n.jsx(W,{value:"usage",children:n.jsxs("div",{className:"space-y-6",children:[n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-4",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.usage.section_title")}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:e("settings.usage.section_desc")})]}),n.jsx("div",{className:"grid gap-3 max-w-md",children:[{key:"claude",label:"Claude Code",desc:e("settings.usage.tool_claude_desc")},{key:"codex",label:"Codex",desc:e("settings.usage.tool_codex_desc")},{key:"opencode",label:"OpenCode",desc:e("settings.usage.tool_opencode_desc")},{key:"qwen",label:"Qwen Code",desc:e("settings.usage.tool_qwen_desc")},{key:"gemini",label:"Gemini CLI",desc:e("settings.usage.tool_gemini_desc")}].map(s=>n.jsxs("label",{className:"flex items-start gap-3 rounded-md border p-3 cursor-pointer transition-colors "+(_===s.key?"border-blue-500/50 bg-blue-500/5":"border-border hover:bg-muted/30"),children:[n.jsx("input",{type:"radio",name:"usageTool",value:s.key,checked:_===s.key,onChange:()=>{v(s.key),U(z.usageMonitorTool,s.key),window.dispatchEvent(new Event("ccweb:usage-tool-change")),x.success(e("settings.usage.switched_toast",{tool:s.label}))},className:"mt-0.5"}),n.jsxs("div",{children:[n.jsx("div",{className:"text-sm font-medium",children:s.label}),n.jsx("div",{className:"text-xs text-muted-foreground",children:s.desc})]})]},s.key))})]}),n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-2",children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.usage.info_title")}),n.jsxs("ul",{className:"text-xs text-muted-foreground space-y-1 list-disc list-inside",children:[n.jsx("li",{children:e("settings.usage.info_item_1")}),n.jsx("li",{children:e("settings.usage.info_item_2")}),n.jsx("li",{children:e("settings.usage.info_item_3")}),n.jsx("li",{children:e("settings.usage.info_item_4")})]})]})]})}),n.jsx(W,{value:"language",children:n.jsx("div",{className:"space-y-6",children:n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-3",children:[n.jsx("div",{children:n.jsx("h3",{className:"text-sm font-medium",children:e("language.label")})}),n.jsx(ke,{})]})})})]})]})})}export{Ne as SettingsPage};
13
+ */var oe="Switch",[de]=r(oe),[he,me]=de(oe),xe=s.forwardRef((e,i)=>{const{__scopeSwitch:r,name:o,checked:d,defaultChecked:h,required:m,disabled:x,value:u="on",onCheckedChange:p,form:j,...g}=e,[b,y]=s.useState(null),f=t(i,e=>y(e)),_=s.useRef(!1),v=!b||(j||!!b.closest("form")),[k,N]=a({prop:d,defaultProp:h??!1,onChange:p,caller:oe});return n.jsxs(he,{scope:r,checked:k,disabled:x,children:[n.jsx(c.button,{type:"button",role:"switch","aria-checked":k,"aria-required":m,"data-state":ge(k),"data-disabled":x?"":void 0,disabled:x,value:u,...g,ref:f,onClick:l(e.onClick,e=>{N(e=>!e),v&&(_.current=e.isPropagationStopped(),_.current||e.stopPropagation())})}),v&&n.jsx(je,{control:b,bubbles:!_.current,name:o,value:u,checked:k,required:m,disabled:x,form:j,style:{transform:"translateX(-100%)"}})]})});xe.displayName=oe;var ue="SwitchThumb",pe=s.forwardRef((e,s)=>{const{__scopeSwitch:t,...a}=e,l=me(ue,t);return n.jsx(c.span,{"data-state":ge(l.checked),"data-disabled":l.disabled?"":void 0,...a,ref:s})});pe.displayName=ue;var je=s.forwardRef(({__scopeSwitch:e,control:a,checked:c,bubbles:l=!0,...r},o)=>{const d=s.useRef(null),h=t(d,o),m=W(c),x=i(a);return s.useEffect(()=>{const e=d.current;if(!e)return;const s=window.HTMLInputElement.prototype,t=Object.getOwnPropertyDescriptor(s,"checked").set;if(m!==c&&t){const s=new Event("click",{bubbles:l});t.call(e,c),e.dispatchEvent(s)}},[m,c,l]),n.jsx("input",{type:"checkbox","aria-hidden":!0,defaultChecked:c,...r,tabIndex:-1,ref:h,style:{...r.style,...x,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});function ge(e){return e?"checked":"unchecked"}je.displayName="SwitchBubbleInput";var be=xe,ye=pe;const fe=s.forwardRef(({className:e,...s},t)=>n.jsx(be,{className:o("peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",e),...s,ref:t,children:n.jsx(ye,{className:o("pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0")})}));fe.displayName=be.displayName;function _e(){const{t:e}=d(),[t,a]=s.useState(null),[c,l]=s.useState(!0),[i,r]=s.useState(!1),[o,N]=s.useState(!1),[w,C]=s.useState(!1),[S,M]=s.useState(!1),[T,E]=s.useState(null),[R,I]=s.useState(0),[P,H]=s.useState(""),[L,z]=s.useState("");h({onStart:e=>{E(e.projectId),I(0)},onProgress:e=>{E(e.projectId),I(e.filesTransferred)},onDone:()=>{E(null),I(0)}}),s.useEffect(()=>{let s=!1;return m().then(e=>{s||(a(e),z(e.defaultExcludes.join("\n")))}).catch(s=>x.error(e("sync_section.load_failed",{message:s.message}))).finally(()=>{s||l(!1)}),()=>{s=!0}},[e]);const F=(e,s)=>{a(t=>t?{...t,[e]:s}:t)};return c||!t?n.jsx("div",{className:"text-sm text-muted-foreground",children:e("sync_section.loading")}):n.jsxs("div",{className:"space-y-5",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-3",children:e("sync_section.server_section")}),n.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-host",children:e("sync_section.host")}),n.jsx(p,{id:"sync-host",value:t.host,onChange:e=>F("host",e.target.value),placeholder:"example.com"})]}),n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-port",children:e("sync_section.port")}),n.jsx(p,{id:"sync-port",type:"number",value:t.port,onChange:e=>F("port",Number(e.target.value)||22)})]}),n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-user",children:e("sync_section.user")}),n.jsx(p,{id:"sync-user",value:t.user,onChange:e=>F("user",e.target.value),placeholder:"tom"})]}),n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-remote",children:e("sync_section.remote_root")}),n.jsx(p,{id:"sync-remote",value:t.remoteRoot,onChange:e=>F("remoteRoot",e.target.value),placeholder:"/data/projects"}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",dangerouslySetInnerHTML:{__html:e("sync_section.remote_root_hint")}})]})]})]}),n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-3",children:e("sync_section.auth_section")}),n.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[n.jsxs("div",{children:[n.jsx(u,{children:e("sync_section.auth_method")}),n.jsxs(Z,{value:t.authMethod,onValueChange:e=>F("authMethod",e),children:[n.jsx($,{children:n.jsx(X,{})}),n.jsxs(J,{children:[n.jsx(K,{value:"key",children:"SSH key"}),n.jsx(K,{value:"password",children:e("sync_section.auth_password")})]})]})]}),"key"===t.authMethod?n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-key",children:e("sync_section.key_path")}),n.jsx(p,{id:"sync-key",value:t.keyPath??"",onChange:e=>F("keyPath",e.target.value),placeholder:"~/.ssh/id_rsa"})]}):n.jsxs("div",{children:[n.jsx(u,{htmlFor:"sync-pw",children:e("sync_section.password")}),n.jsx(p,{id:"sync-pw",type:"password",value:P,onChange:e=>H(e.target.value),placeholder:t.passwordSet?e("sync_section.password_set_placeholder"):e("sync_section.password_unset_placeholder")}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",dangerouslySetInnerHTML:{__html:e("sync_section.sshpass_hint")}})]})]})]}),n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-3",children:e("sync_section.strategy_section")}),n.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[n.jsxs("div",{children:[n.jsx(u,{children:e("sync_section.direction")}),n.jsxs(Z,{value:t.direction,onValueChange:e=>F("direction",e),children:[n.jsx($,{children:n.jsx(X,{})}),n.jsxs(J,{children:[n.jsx(K,{value:"push",children:e("sync_section.push_label")}),n.jsx(K,{value:"pull",children:e("sync_section.pull_label")}),n.jsx(K,{value:"bidirectional",children:e("sync_section.bidirectional_label")})]})]})]}),n.jsxs("div",{className:"flex items-end gap-2",children:[n.jsxs("div",{className:"flex-1",children:[n.jsx(u,{htmlFor:"sync-cron",children:e("sync_section.cron_label")}),n.jsx(p,{id:"sync-cron",value:t.schedule.cron,onChange:e=>F("schedule",{...t.schedule,cron:e.target.value}),placeholder:"0 3 * * *"}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",dangerouslySetInnerHTML:{__html:e("sync_section.cron_hint")}})]}),n.jsxs("div",{className:"flex items-center gap-2 pb-1.5",children:[n.jsx(fe,{checked:t.schedule.enabled,onCheckedChange:e=>F("schedule",{...t.schedule,enabled:e})}),n.jsx("span",{className:"text-xs text-muted-foreground",children:e("sync_section.enable_label")})]})]})]})]}),n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-3",children:e("sync_section.exclude_section")}),n.jsx("textarea",{value:L,onChange:e=>z(e.target.value),rows:6,className:"w-full font-mono text-xs p-2 rounded border border-input bg-background resize-y",placeholder:"node_modules/\n.git/objects/\n*.log"}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",dangerouslySetInnerHTML:{__html:e("sync_section.exclude_hint")}})]}),n.jsxs("div",{className:"flex flex-wrap gap-2 pt-2 border-t",children:[n.jsxs(j,{onClick:()=>{(async()=>{if(t){r(!0);try{const s=L.split("\n").map(e=>e.trim()).filter(Boolean),n={host:t.host,port:t.port,user:t.user,authMethod:t.authMethod,keyPath:t.keyPath,remoteRoot:t.remoteRoot,direction:t.direction,defaultExcludes:s,schedule:t.schedule};P&&"__keep__"!==P&&(n.password=P);const c=await f(n);a(c),z(c.defaultExcludes.join("\n")),H(""),x.success(e("sync_section.saved"))}catch(s){x.error(e("sync_section.save_failed",{message:s.message}))}finally{r(!1)}}})()},disabled:i,children:[i?n.jsx(g,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(Y,{className:"h-3.5 w-3.5 mr-1.5"}),e("sync_section.save_button")]}),n.jsxs(j,{variant:"outline",onClick:()=>{(async()=>{N(!0);try{const s=await _();s.ok?x.success(s.message||e("sync_section.test_ok")):x.error(s.message||e("sync_section.test_failed"))}catch(s){x.error(e("sync_section.test_failed_with_reason",{message:s.message}))}finally{N(!1)}})()},disabled:o,children:[o?n.jsx(g,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(ie,{className:"h-3.5 w-3.5 mr-1.5"}),e("sync_section.test_button")]}),n.jsx("div",{className:"flex-1"}),w&&T&&n.jsx("span",{className:"text-xs text-muted-foreground self-center mr-1 tabular-nums",children:R>0?e("sync_section.syncing_with_files",{project:T,files:R}):e("sync_section.syncing_no_files",{project:T})}),n.jsxs(j,{variant:"outline",onClick:()=>{(async()=>{C(!0);try{const s=await v(),t=s.results.filter(e=>e.ok).length,a=s.results.filter(e=>e.skipped).length,n=s.results.filter(e=>"cancelled"===e.reason).length,c=s.total-t-a-n;n>0?x.info(e("sync_section.bulk_cancelled_toast",{ok:t,skipped:a,cancelled:n,failed:c})):x.success(e("sync_section.bulk_done_toast",{ok:t,skipped:a,failed:c}))}catch(s){x.error(e("sync_section.bulk_failed_toast",{message:s.message}))}finally{C(!1),M(!1),E(null),I(0)}})()},disabled:w,title:e("sync_section.sync_all_title"),children:[w?n.jsx(g,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(O,{className:"h-3.5 w-3.5 mr-1.5"}),e("sync_section.sync_all_button")]}),w&&n.jsxs(j,{variant:"outline",onClick:()=>{(async()=>{if(w&&!S){M(!0);try{await k(),x.info(e("sync_section.cancel_requested"))}catch(s){x.error(e("sync_section.cancel_failed",{message:s.message})),M(!1)}}})()},disabled:S,title:e("sync_section.cancel_button_title"),children:[S?n.jsx(g,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(b,{className:"h-3.5 w-3.5 mr-1.5"}),e("sync_section.cancel_button")]})]}),n.jsxs("div",{className:"border-t pt-4 text-xs text-muted-foreground",children:["Per-project push/pull: from inside a project, click the ",n.jsx(O,{className:"inline h-3 w-3"})," / ",n.jsx(y,{className:"inline h-3 w-3"})," buttons in the header. Or call ",n.jsx("code",{children:"POST /api/sync/project/:id"})," with body ",n.jsx("code",{children:'{ "direction": "push" }'}),"."]})]})}function ve(){const e=N(),[t,a]=s.useState(null),[c,l]=s.useState(!0),[i,r]=s.useState(""),[o,d]=s.useState(!1);s.useEffect(()=>{let e=!1;return w().then(s=>{e||a(s)}).catch(()=>{e||a({configured:!1,needsReset:!1})}).finally(()=>{e||l(!1)}),()=>{e=!0}},[]);return n.jsxs("div",{className:"space-y-6",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-semibold mb-1",children:"CCWeb Hub 直接提交"}),n.jsxs("p",{className:"text-xs text-muted-foreground",children:['配置你的 GitHub PAT 后,在 Quick Prompts / Agent Prompts 卡片右键选择"共享"时可一键直接提交 Issue 到 ',n.jsx("code",{children:"zbc0315/ccweb-hub"}),"。 ccweb 本身不自带 token —— 使用你自己的账号身份提交,归属清晰,互不影响。"]})]}),c?n.jsxs("div",{className:"text-sm text-muted-foreground flex items-center gap-2",children:[n.jsx(g,{className:"h-4 w-4 animate-spin"}),"加载中…"]}):n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"rounded-md border px-3 py-2.5 text-xs flex items-center gap-2",children:(null==t?void 0:t.configured)?n.jsxs(n.Fragment,{children:[n.jsx(ee,{className:"h-4 w-4 text-green-500 shrink-0"}),n.jsx("span",{children:"已配置 token,可直接提交"}),n.jsx("div",{className:"flex-1"}),n.jsxs(j,{size:"sm",variant:"outline",onClick:()=>{(async()=>{if(await e({title:"清除 Hub Token",description:"清除后将无法直接提交到 ccweb-hub,需要重新配置 token。确认?",destructive:!0,confirmLabel:"清除"}))try{await S(),a({configured:!1,needsReset:!1}),x.success("已清除")}catch(s){x.error(`清除失败: ${s.message}`)}})()},children:[n.jsx(C,{className:"h-3.5 w-3.5 mr-1"}),"清除"]})]}):(null==t?void 0:t.needsReset)?n.jsxs(n.Fragment,{children:[n.jsx(te,{className:"h-4 w-4 text-amber-500 shrink-0"}),n.jsx("span",{children:"之前的 token 已失效(服务端密钥可能已轮换),请重新设置"})]}):n.jsxs(n.Fragment,{children:[n.jsx(te,{className:"h-4 w-4 text-muted-foreground shrink-0"}),n.jsx("span",{children:"尚未配置 token"})]})}),n.jsxs("div",{className:"rounded-md border bg-muted/30 px-3 py-2.5 text-xs space-y-2",children:[n.jsx("div",{className:"font-medium text-foreground",children:"如何获取 token"}),n.jsxs("ol",{className:"list-decimal list-inside space-y-1 text-muted-foreground",children:[n.jsxs("li",{children:["打开"," ",n.jsxs("a",{href:"https://github.com/settings/personal-access-tokens/new",target:"_blank",rel:"noopener noreferrer",className:"text-blue-500 hover:underline inline-flex items-center gap-0.5",children:["GitHub fine-grained PAT",n.jsx(ne,{className:"h-3 w-3"})]})," ","创建页"]}),n.jsxs("li",{children:[n.jsx("strong",{className:"text-foreground",children:"Repository access"}),':选 "Only select repositories",添加 ',n.jsx("code",{children:"zbc0315/ccweb-hub"})]}),n.jsxs("li",{children:[n.jsx("strong",{className:"text-foreground",children:"Repository permissions → Issues"}),':设置为 "Read and write"']}),n.jsx("li",{children:"其余权限保持默认(全部无访问)"}),n.jsx("li",{children:"生成后复制 token 粘贴到下方"})]})]}),n.jsxs("div",{className:"space-y-2",children:[n.jsxs(u,{htmlFor:"hub-token",className:"text-xs",children:["GitHub Token ",(null==t?void 0:t.configured)&&n.jsx("span",{className:"text-muted-foreground",children:"(填写会覆盖现有 token)"})]}),n.jsx(p,{id:"hub-token",type:"password",placeholder:"github_pat_...",value:i,onChange:e=>r(e.target.value),autoComplete:"off",spellCheck:!1}),n.jsxs("p",{className:"text-xs text-muted-foreground",children:["Token 以 AES-256-GCM 加密存储于 ",n.jsx("code",{children:"~/.ccweb/hub-auth/"}),";per-user 独立,不会被其他用户读到。"]})]}),n.jsx("div",{className:"flex gap-2 pt-2 border-t",children:n.jsxs(j,{onClick:()=>{(async()=>{const e=i.trim();if(e){d(!0);try{const s=await M(e);a(s),r(""),x.success("已保存")}catch(s){x.error(`保存失败: ${s.message}`)}finally{d(!1)}}else x.error("请输入 token")})()},disabled:o||!i.trim(),children:[o?n.jsx(g,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):n.jsx(Y,{className:"h-3.5 w-3.5 mr-1.5"}),"保存"]})})]})]})}function ke(){const{t:e,i18n:s}=d();return n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(le,{className:"h-4 w-4 text-muted-foreground"}),n.jsxs(Z,{value:s.language,onValueChange:async t=>{if(T.includes(t)){try{localStorage.setItem(E,t)}catch{}await s.changeLanguage(t);try{await R(t)}catch{x.error(e("language.switch_failed"))}}},children:[n.jsx($,{className:"w-40",children:n.jsx(X,{})}),n.jsxs(J,{children:[n.jsx(K,{value:"zh",children:e("language.zh")}),n.jsx(K,{value:"en",children:e("language.en")})]})]})]})}function Ne(){const{t:e}=d(),t=I(),[a]=P(),c=a.get("tab")||"sync",[l,i]=s.useState(()=>H()),[r,o]=s.useState(!1),[h,m]=s.useState({webhookEnabled:!1}),[g,b]=s.useState(""),[y,f]=s.useState(!1),[_,v]=s.useState(()=>L(z.usageMonitorTool,"claude"));s.useEffect(()=>{F().then(e=>{m(e),b(e.webhookUrl??"")}).catch(()=>{})},[]);const k=(e,s)=>{const t=parseInt(s,10);isNaN(t)||t<1||(i(s=>({...s,[e]:t})),o(!0))};return n.jsx("div",{className:"min-h-screen bg-background",children:n.jsxs("div",{className:"max-w-3xl mx-auto p-6",children:[n.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[n.jsxs(j,{variant:"ghost",size:"sm",onClick:()=>t("/"),children:[n.jsx(q,{className:"h-4 w-4 mr-1"}),e("common.back")]}),n.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:e("settings.title")})]}),n.jsxs(G,{defaultValue:c,children:[n.jsxs(B,{className:"mb-4",children:[n.jsxs(D,{value:"sync",children:[n.jsx(re,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_sync")]}),n.jsxs(D,{value:"hub",children:[n.jsx(ce,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_hub")]}),n.jsxs(D,{value:"notifications",children:[n.jsx(ae,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_notifications")]}),n.jsxs(D,{value:"pomodoro",children:[n.jsx(A,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_pomodoro")]}),n.jsxs(D,{value:"usage",children:[n.jsx(se,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_usage")]}),n.jsxs(D,{value:"language",children:[n.jsx(le,{className:"h-3.5 w-3.5 mr-1.5"}),e("settings.tab_language")]})]}),n.jsx(Q,{value:"sync",children:n.jsx(_e,{})}),n.jsx(Q,{value:"hub",children:n.jsx(ve,{})}),n.jsx(Q,{value:"notifications",children:n.jsxs("div",{className:"space-y-6",children:[n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-2",children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.browser_notify.title")}),n.jsx("p",{className:"text-xs text-muted-foreground",children:e("settings.browser_notify.description")})]}),n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-3",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.webhook.title")}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:e("settings.webhook.description")})]}),n.jsxs("div",{className:"space-y-1.5",children:[n.jsx(u,{className:"text-xs",children:"Webhook URL"}),n.jsxs("div",{className:"flex gap-2",children:[n.jsx(p,{placeholder:"https://hooks.slack.com/...",value:g,onChange:e=>b(e.target.value),className:"font-mono text-xs"}),n.jsx(j,{size:"sm",onClick:()=>{(async()=>{f(!0);try{const s=await V({webhookEnabled:g.trim().length>0,webhookUrl:g.trim()||void 0});m(s),x.success(e("settings.webhook.saved"))}catch{x.error(e("settings.webhook.save_failed"))}finally{f(!1)}})()},disabled:y,children:e(y?"common.saving":"common.save")})]}),h.webhookEnabled&&h.webhookUrl&&n.jsxs("p",{className:"text-xs text-green-500",children:[e("settings.webhook.enabled_prefix")," ",h.webhookUrl]})]})]})]})}),n.jsx(Q,{value:"pomodoro",children:n.jsxs("div",{className:"space-y-6",children:[n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-4",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.pomodoro.section_title")}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:e("settings.pomodoro.section_desc")})]}),n.jsxs("div",{className:"grid grid-cols-2 gap-6 max-w-xs",children:[n.jsxs("div",{className:"space-y-1.5",children:[n.jsx(u,{className:"text-xs",children:e("settings.pomodoro.work_minutes")}),n.jsx(p,{type:"number",min:1,max:120,value:l.workMinutes,onChange:e=>k("workMinutes",e.target.value),className:"w-full"})]}),n.jsxs("div",{className:"space-y-1.5",children:[n.jsx(u,{className:"text-xs",children:e("settings.pomodoro.break_minutes")}),n.jsx(p,{type:"number",min:1,max:60,value:l.breakMinutes,onChange:e=>k("breakMinutes",e.target.value),className:"w-full"})]})]}),r&&n.jsxs(j,{size:"sm",onClick:()=>{U(z.pomodoroConfig,l,!0),o(!1),x.success(e("settings.pomodoro.saved"))},children:[n.jsx(Y,{className:"h-3.5 w-3.5 mr-1.5"}),e("common.save")]})]}),n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-2",children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.pomodoro.howto_title")}),n.jsxs("ul",{className:"text-xs text-muted-foreground space-y-1 list-disc list-inside",children:[n.jsxs("li",{children:[n.jsx(A,{className:"h-3 w-3 inline-block mx-0.5"})," ",e("settings.pomodoro.howto_item_1")]}),n.jsx("li",{children:e("settings.pomodoro.howto_item_2")}),n.jsx("li",{children:e("settings.pomodoro.howto_item_3")}),n.jsx("li",{children:e("settings.pomodoro.howto_item_4")}),n.jsx("li",{children:e("settings.pomodoro.howto_item_5")})]})]})]})}),n.jsx(Q,{value:"usage",children:n.jsxs("div",{className:"space-y-6",children:[n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-4",children:[n.jsxs("div",{children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.usage.section_title")}),n.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:e("settings.usage.section_desc")})]}),n.jsx("div",{className:"grid gap-3 max-w-md",children:[{key:"claude",label:"Claude Code",desc:e("settings.usage.tool_claude_desc")},{key:"codex",label:"Codex",desc:e("settings.usage.tool_codex_desc")},{key:"opencode",label:"OpenCode",desc:e("settings.usage.tool_opencode_desc")},{key:"qwen",label:"Qwen Code",desc:e("settings.usage.tool_qwen_desc")},{key:"gemini",label:"Gemini CLI",desc:e("settings.usage.tool_gemini_desc")}].map(s=>n.jsxs("label",{className:"flex items-start gap-3 rounded-md border p-3 cursor-pointer transition-colors "+(_===s.key?"border-blue-500/50 bg-blue-500/5":"border-border hover:bg-muted/30"),children:[n.jsx("input",{type:"radio",name:"usageTool",value:s.key,checked:_===s.key,onChange:()=>{v(s.key),U(z.usageMonitorTool,s.key),window.dispatchEvent(new Event("ccweb:usage-tool-change")),x.success(e("settings.usage.switched_toast",{tool:s.label}))},className:"mt-0.5"}),n.jsxs("div",{children:[n.jsx("div",{className:"text-sm font-medium",children:s.label}),n.jsx("div",{className:"text-xs text-muted-foreground",children:s.desc})]})]},s.key))})]}),n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-2",children:[n.jsx("h3",{className:"text-sm font-medium",children:e("settings.usage.info_title")}),n.jsxs("ul",{className:"text-xs text-muted-foreground space-y-1 list-disc list-inside",children:[n.jsx("li",{children:e("settings.usage.info_item_1")}),n.jsx("li",{children:e("settings.usage.info_item_2")}),n.jsx("li",{children:e("settings.usage.info_item_3")}),n.jsx("li",{children:e("settings.usage.info_item_4")})]})]})]})}),n.jsx(Q,{value:"language",children:n.jsx("div",{className:"space-y-6",children:n.jsxs("div",{className:"rounded-xl border border-border p-4 space-y-3",children:[n.jsx("div",{children:n.jsx("h3",{className:"text-sm font-medium",children:e("language.label")})}),n.jsx(ke,{})]})})})]})]})})}export{Ne as SettingsPage};
@@ -1,4 +1,4 @@
1
- import{c as e,aN as s,r as t,bs as a,bt as r,t as n,bu as l,bv as i,bw as c,ap as d,bx as o,j as m,B as x,aI as u,d as p,I as h,T as g,q as f,D as j,aJ as b,aK as N,A as y,au as v,aA as k}from"./index-D2KpHlv8.js";import{S as w}from"./search-BIHCBFC7.js";import{C}from"./chevron-down-BXO9hQjV.js";
1
+ import{c as e,aN as s,r as t,bs as a,bt as r,t as n,bu as l,bv as i,bw as c,ap as d,bx as o,j as m,B as x,aI as u,d as p,I as h,T as g,q as f,D as j,aJ as b,aK as N,A as y,au as v,aA as k}from"./index-BjydjBX7.js";import{S as w}from"./search-09qCXbdG.js";import{C}from"./chevron-down-efPsOYlh.js";
2
2
  /**
3
3
  * @license lucide-react v0.309.0 - ISC
4
4
  *
@@ -1,4 +1,4 @@
1
- import{c}from"./index-D2KpHlv8.js";
1
+ import{c}from"./index-BjydjBX7.js";
2
2
  /**
3
3
  * @license lucide-react v0.309.0 - ISC
4
4
  *
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-D2KpHlv8.js";
1
+ import{c as o}from"./index-BjydjBX7.js";
2
2
  /**
3
3
  * @license lucide-react v0.309.0 - ISC
4
4
  *
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-D2KpHlv8.js";
1
+ import{c as e}from"./index-BjydjBX7.js";
2
2
  /**
3
3
  * @license lucide-react v0.309.0 - ISC
4
4
  *