@lovelybunch/api 1.0.71-alpha.3 → 1.0.71-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/routes/api/v1/context/images/index.d.ts +2 -0
- package/dist/routes/api/v1/context/images/index.js +2 -0
- package/dist/routes/api/v1/context/images/route.d.ts +3 -0
- package/dist/routes/api/v1/context/images/route.js +253 -0
- package/dist/routes/api/v1/context/index.js +2 -0
- package/dist/routes/api/v1/resources/generate-audio/index.d.ts +3 -0
- package/dist/routes/api/v1/resources/generate-audio/index.js +5 -0
- package/dist/routes/api/v1/resources/generate-audio/route.d.ts +19 -0
- package/dist/routes/api/v1/resources/generate-audio/route.js +129 -0
- package/dist/routes/api/v1/resources/index.js +2 -0
- package/package.json +4 -4
- package/static/assets/{AgentDetailPage-DVDnvYcy.js → AgentDetailPage-B3CFO9Vg.js} +1 -1
- package/static/assets/{AgentEditPage-DRLTkdIZ.js → AgentEditPage-Cc8k9uYb.js} +1 -1
- package/static/assets/{AgentsPage-CVoYisFq.js → AgentsPage-CcRVHD2p.js} +2 -2
- package/static/assets/{AgentsSettingsPage-D9FDJHpC.js → AgentsSettingsPage-BMphtJ6C.js} +1 -1
- package/static/assets/{ApiKeysSettingsPage-DGcz0E10.js → ApiKeysSettingsPage-BLlmALn1.js} +3 -3
- package/static/assets/{ArchitectureEditPage-PXH0HtcY.js → ArchitectureEditPage-B8YrHerA.js} +1 -1
- package/static/assets/{ArchitecturePage-BiybPTif.js → ArchitecturePage-fIoEV_ow.js} +1 -1
- package/static/assets/{AuthSettingsPage-6TaOiZV7.js → AuthSettingsPage-CICO_5eb.js} +2 -2
- package/static/assets/{CallbackPage-BdZglBBj.js → CallbackPage-6lJyGru9.js} +1 -1
- package/static/assets/{CodePage-B239DtM2.js → CodePage-gGhNXTQn.js} +1 -1
- package/static/assets/{CollapsibleSection-DaqBpCe-.js → CollapsibleSection-CkCVMSBD.js} +1 -1
- package/static/assets/{DashboardPage-B2FJcHVR.js → DashboardPage-qkyq1COW.js} +1 -1
- package/static/assets/{GitPage-DaWE2Q-b.js → GitPage-Dj9uMiQV.js} +1 -1
- package/static/assets/{GitSettingsPage-bTqUr0fn.js → GitSettingsPage--hjPt4zu.js} +2 -2
- package/static/assets/{IdentityPage-eXzMXYy2.js → IdentityPage-DzqrsAU2.js} +2 -2
- package/static/assets/{ImplementationStepsEditor-CuDeossU.js → ImplementationStepsEditor-GxhD-g8y.js} +1 -1
- package/static/assets/{IntegrationsSettingsPage-wAf_7nar.js → IntegrationsSettingsPage-DR_v_Fbo.js} +1 -1
- package/static/assets/{KnowledgeDetailPage-B5ieYIze.js → KnowledgeDetailPage-BEHrLcNg.js} +1 -1
- package/static/assets/{KnowledgeEditPage-OMUREl1n.js → KnowledgeEditPage-CETMgdZf.js} +1 -1
- package/static/assets/{KnowledgePage-CKtcok1N.js → KnowledgePage-Dz2YIqdH.js} +2 -2
- package/static/assets/{LoginPage-B70_aCBv.js → LoginPage-DSxl4xGK.js} +1 -1
- package/static/assets/McpSettingsPage-CLDzqlt3.js +1 -0
- package/static/assets/{NewAgentPage-DITLLDez.js → NewAgentPage-DlEnBUUY.js} +1 -1
- package/static/assets/{NewKnowledgePage-C7vEg4PR.js → NewKnowledgePage-CI8D1NRB.js} +1 -1
- package/static/assets/{NewProposalPage-z8wqyXIj.js → NewProposalPage-B1hVwad9.js} +1 -1
- package/static/assets/{ProjectEditPage-BDj8GlD_.js → ProjectEditPage-t_oD7x6f.js} +1 -1
- package/static/assets/{ProjectPage-CtoKV0l9.js → ProjectPage-CMez4KRO.js} +1 -1
- package/static/assets/{PromptsSettingsPage-CI-pWQVw.js → PromptsSettingsPage-DXvS4JX8.js} +1 -1
- package/static/assets/{ProposalDetailPage-D6rhO9vm.js → ProposalDetailPage-Cbld0UYO.js} +1 -1
- package/static/assets/{ProposalEditPage-DCy3_sbg.js → ProposalEditPage-Dujm4G1-.js} +1 -1
- package/static/assets/{ProposalsPage-DQLqm83b.js → ProposalsPage-0L4kWC5Y.js} +1 -1
- package/static/assets/ResourcesPage-5sZL01s_.js +66 -0
- package/static/assets/{RulesSettingsPage-MgsP5qaA.js → RulesSettingsPage-D6qjkKbl.js} +1 -1
- package/static/assets/{SchedulePage-C1vDSjyh.js → SchedulePage-CgnTsib0.js} +1 -1
- package/static/assets/{TagInput-Cdfvhozb.js → TagInput-DJMwLVTn.js} +1 -1
- package/static/assets/{TerminalPage-NQzi2rzj.js → TerminalPage-EYVbapc9.js} +1 -1
- package/static/assets/{TerminalSessionPage-DQgbm-LP.js → TerminalSessionPage-CQCLFjOR.js} +1 -1
- package/static/assets/{UserPreferencesPage-CCYsj_XY.js → UserPreferencesPage-KAsCdvFQ.js} +1 -1
- package/static/assets/{UserSettingsPage-DdCnaoY_.js → UserSettingsPage-DclI2Mhd.js} +1 -1
- package/static/assets/{UtilitiesPage-DGcmJSz6.js → UtilitiesPage-BKdyva6y.js} +1 -1
- package/static/assets/{alert-BAeRxZ1d.js → alert-p2sQnjrU.js} +1 -1
- package/static/assets/{arrow-down-5CQhXptz.js → arrow-down-DGeJDsho.js} +1 -1
- package/static/assets/{arrow-left-DSqUNUH-.js → arrow-left-BRSAC1N6.js} +1 -1
- package/static/assets/{arrow-up-CYoJSbWn.js → arrow-up-C5ecpR5U.js} +1 -1
- package/static/assets/{badge-NJasrAx_.js → badge-DaM4gF82.js} +1 -1
- package/static/assets/browser-modal-CyeEbzDK.js +6 -0
- package/static/assets/{calendar-wiZSxCBM.js → calendar-CV2haPQ9.js} +1 -1
- package/static/assets/{card-CvaBJsG6.js → card-B9ym6neB.js} +1 -1
- package/static/assets/{chevron-left-CaZHWPr-.js → chevron-left-D8aMFTU2.js} +1 -1
- package/static/assets/{circle-alert-61156jM6.js → circle-alert-C-piOZLm.js} +1 -1
- package/static/assets/{circle-check-z0By2KN8.js → circle-check-4zzXsmHH.js} +1 -1
- package/static/assets/{circle-check-big-K_QMED_K.js → circle-check-big-AlE11jqb.js} +1 -1
- package/static/assets/{circle-play-88lMuMRZ.js → circle-play-cWY3nlZW.js} +1 -1
- package/static/assets/{circle-x-DdTsJYO7.js → circle-x-D58MbKgZ.js} +1 -1
- package/static/assets/{clipboard-BNXOfcye.js → clipboard-BFF6-pdC.js} +1 -1
- package/static/assets/{clock-BTCBJF7v.js → clock-B-uSJOTR.js} +1 -1
- package/static/assets/{download-BaYIFjpj.js → download-DrQn0jny.js} +1 -1
- package/static/assets/{eye-CuSCp49Y.js → eye-BcjteMts.js} +1 -1
- package/static/assets/{folder-git-2-CiVM8o0Y.js → folder-git-2-B_ezHf_E.js} +1 -1
- package/static/assets/index-B0JO3x3V.js +458 -0
- package/static/assets/index-C8p-lTq9.css +2 -0
- package/static/assets/label-BHOOQ99D.js +1 -0
- package/static/assets/{markdown-editor-DvlGlqU9.js → markdown-editor-B0i_LOAR.js} +1 -1
- package/static/assets/{pause-COIsHZIp.js → pause-DqQ7Twc6.js} +1 -1
- package/static/assets/{play-a8BsF4gF.js → play-Y2N8OVBu.js} +1 -1
- package/static/assets/{plus-Bon5P_OK.js → plus-D737EJ5S.js} +1 -1
- package/static/assets/radio-group-nRRUTZ_w.js +1 -0
- package/static/assets/{refresh-cw-CnHMzcH3.js → refresh-cw-uBnPtZwp.js} +1 -1
- package/static/assets/registry-ANRa5WBi.js +1 -0
- package/static/assets/{search-BR37JgJ3.js → search-cntvIhnF.js} +1 -1
- package/static/assets/{switch-D86f4WeD.js → switch-BYf9VEgx.js} +1 -1
- package/static/assets/{tabs-BYrDWPwx.js → tabs-BnsC3AY5.js} +1 -1
- package/static/assets/{tag--U3Nuedb.js → tag-C_HL28Xd.js} +1 -1
- package/static/assets/{terminal-preview-Be68j_3t.js → terminal-preview-Qv4UvCJz.js} +1 -1
- package/static/assets/{use-terminal-2DGl8X5T.js → use-terminal-5sW1t6SD.js} +1 -1
- package/static/assets/{zap-C0eIGEl_.js → zap-CrLPiVyl.js} +1 -1
- package/static/index.html +2 -2
- package/static/assets/McpSettingsPage-DcJIlHEi.js +0 -1
- package/static/assets/ResourcesPage-Bq9t872V.js +0 -66
- package/static/assets/browser-modal-x3ise3M1.js +0 -6
- package/static/assets/index-B8vejVRZ.js +0 -458
- package/static/assets/index-CKwmN6yL.css +0 -2
- package/static/assets/label-DtNTh--4.js +0 -1
- package/static/assets/radio-group-DpJuX02X.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{c as
|
|
1
|
+
import{c as R,m as X,r as t,b5 as y,j as e,B as a,b6 as Y,T as _,D as j,a as g,b as v,d as f,e as A,I as F,$ as N,ai as J,t as i}from"./index-B0JO3x3V.js";import{C as W,b as G,c as Q,d as V,a as Z}from"./card-B9ym6neB.js";import{L as w}from"./label-BHOOQ99D.js";import{B as ee}from"./badge-DaM4gF82.js";import{A as I,a as C}from"./alert-p2sQnjrU.js";import{P as se}from"./plus-D737EJ5S.js";import{C as te}from"./circle-alert-C-piOZLm.js";/**
|
|
2
2
|
* @license lucide-react v0.542.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const ae=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],L=
|
|
7
|
-
+ ${
|
|
6
|
+
*/const ae=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],L=R("info",ae);function he(){const{authEnabled:n}=X(),[k,P]=t.useState([]),[b,K]=t.useState(!0),[M,o]=t.useState(!1),[O,d]=t.useState(!1),[h,D]=t.useState(""),[x,E]=t.useState("never"),[c,S]=t.useState(null),[m,l]=t.useState(null);t.useEffect(()=>{p()},[]);const p=async()=>{K(!0);try{const s=await y("/api/v1/api-keys");s.success&&P(s.data?.apiKeys||[])}catch(s){console.error("Failed to load API keys:",s),P([])}finally{K(!1)}},U=async()=>{if(!h.trim()){i({title:"Error",description:"Please provide a name for the API key",variant:"destructive"});return}try{const s={name:h,scopes:["*"]};x!=="never"&&(s.expiresIn=x);const r=await y("/api/v1/api-keys",{method:"POST",body:JSON.stringify(s)});r.success&&(S(r.data),o(!1),d(!0),D(""),E("never"),await p(),i({title:"API Key Created",description:"Make sure to copy your API key now. You won't be able to see it again!"}))}catch(s){console.error("Failed to create API key:",s),i({title:"Error",description:"Failed to create API key",variant:"destructive"})}},B=async s=>{try{(await y(`/api/v1/api-keys/${s}`,{method:"DELETE"})).success&&(await p(),l(null),i({title:"API Key Deleted",description:"The API key has been permanently deleted"}))}catch(r){console.error("Failed to delete API key:",r),i({title:"Error",description:"Failed to delete API key",variant:"destructive"})}},$=async s=>{try{await navigator.clipboard.writeText(s),i({title:"Copied",description:"API key copied to clipboard"})}catch{i({title:"Error",description:"Failed to copy to clipboard",variant:"destructive"})}},u=s=>new Date(s).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),H=s=>s?new Date(s)<new Date:!1,q=typeof window<"u"?window.location.origin:"http://localhost:3000",z=c?`curl -H "X-API-Key: ${c.key}" \\
|
|
7
|
+
+ ${q}/api/v1/proposals`:"",T=n?null:e.jsxs(I,{children:[e.jsx(L,{className:"h-4 w-4"}),e.jsxs(C,{children:["Authentication is currently disabled. API keys will only be required once you enable authentication in the ",e.jsx("a",{href:"/settings/authentication",className:"underline",children:"Authentication settings"}),"."]})]});return!n&&b?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for programmatic access"})]}),T]}):b?e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading..."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for programmatic access to your Coconut instance"})]}),T,n&&e.jsxs(I,{children:[e.jsx(L,{className:"h-4 w-4"}),e.jsxs(C,{children:["API keys provide programmatic access to your Coconut instance. Use them in CI/CD pipelines or automation scripts by including the key in the ",e.jsx("code",{className:"bg-muted px-1 py-0.5 rounded",children:"X-API-Key"})," header."]})]}),e.jsxs(W,{children:[e.jsx(G,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(Q,{children:"Active API Keys"}),e.jsx(V,{children:"API keys you've created for programmatic access"})]}),e.jsxs(a,{onClick:()=>o(!0),disabled:!n,children:[e.jsx(se,{className:"mr-2 h-4 w-4"}),"Create API Key"]})]})}),e.jsx(Z,{children:k.length===0?e.jsxs("div",{className:"text-center py-8 text-muted-foreground",children:[e.jsx(Y,{className:"h-12 w-12 mx-auto mb-4 opacity-20"}),e.jsx("p",{children:"No API keys yet"}),e.jsx("p",{className:"text-sm",children:"Create an API key to get started with programmatic access"})]}):e.jsx("div",{className:"space-y-4",children:k.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("p",{className:"font-medium",children:s.name}),H(s.expiresAt)&&e.jsx(ee,{variant:"destructive",children:"Expired"})]}),e.jsx("p",{className:"text-sm text-muted-foreground font-mono",children:s.keyPreview}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Created: ",u(s.createdAt)]}),s.expiresAt&&e.jsxs("span",{children:["Expires: ",u(s.expiresAt)]}),s.lastUsedAt&&e.jsxs("span",{children:["Last used: ",u(s.lastUsedAt)]})]})]}),e.jsx(a,{variant:"ghost",size:"icon",onClick:()=>l(s.id),children:e.jsx(_,{className:"h-4 w-4 text-destructive"})})]},s.id))})})]}),e.jsx(j,{open:M,onOpenChange:o,children:e.jsxs(g,{children:[e.jsxs(v,{children:[e.jsx(f,{children:"Create API Key"}),e.jsx(A,{children:"Create a new API key for programmatic access. The key will only be shown once."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{htmlFor:"keyName",children:"Name"}),e.jsx(F,{id:"keyName",placeholder:"CI/CD Pipeline",value:h,onChange:s=>D(s.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"A descriptive name to identify this API key"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{htmlFor:"keyExpiry",children:"Expiration"}),e.jsxs("select",{id:"keyExpiry",className:"w-full rounded-md border border-input bg-background px-3 py-2 text-sm",value:x,onChange:s=>E(s.target.value),children:[e.jsx("option",{value:"never",children:"Never"}),e.jsx("option",{value:"30d",children:"30 days"}),e.jsx("option",{value:"90d",children:"90 days"}),e.jsx("option",{value:"1y",children:"1 year"})]})]})]}),e.jsxs(N,{children:[e.jsx(a,{variant:"outline",onClick:()=>o(!1),children:"Cancel"}),e.jsx(a,{onClick:U,disabled:!n,children:"Create API Key"})]})]})}),e.jsx(j,{open:O,onOpenChange:d,children:e.jsxs(g,{className:"sm:max-w-[600px]",children:[e.jsxs(v,{children:[e.jsx(f,{children:"API Key Created"}),e.jsx(A,{children:"Make sure to copy your API key now. You won't be able to see it again!"})]}),e.jsxs(I,{variant:"destructive",className:"my-4",children:[e.jsx(te,{className:"h-4 w-4"}),e.jsx(C,{children:"This is the only time you will see this key. Store it securely."})]}),c&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{children:"API Key"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(F,{readOnly:!0,value:c.key,className:"font-mono text-sm"}),e.jsx(a,{variant:"outline",size:"icon",onClick:()=>$(c.key),children:e.jsx(J,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:[e.jsx("p",{className:"mb-2",children:"Usage example:"}),e.jsx("pre",{className:"bg-muted p-3 rounded-md whitespace-pre-wrap break-words",children:e.jsx("code",{className:"font-mono text-xs",children:z})})]})]}),e.jsx(N,{children:e.jsx(a,{onClick:()=>{d(!1),S(null)},children:"I've Saved My Key"})})]})}),e.jsx(j,{open:!!m,onOpenChange:s=>!s&&l(null),children:e.jsxs(g,{children:[e.jsxs(v,{children:[e.jsx(f,{children:"Delete API Key"}),e.jsx(A,{children:"Are you sure you want to delete this API key? This action cannot be undone and any scripts using this key will stop working."})]}),e.jsxs(N,{children:[e.jsx(a,{variant:"outline",onClick:()=>l(null),children:"Cancel"}),e.jsx(a,{variant:"destructive",onClick:()=>m&&B(m),children:"Delete API Key"})]})]})})]})}export{he as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{u as D,H as M,r as l,A as b,j as e,B as S,L as I,a2 as _,I as d,a0 as B}from"./index-
|
|
1
|
+
import{u as D,H as M,r as l,A as b,j as e,B as S,L as I,a2 as _,I as d,a0 as B}from"./index-B0JO3x3V.js";import{C as u,a as p,b as j,c as v}from"./card-B9ym6neB.js";import{L as o}from"./label-BHOOQ99D.js";import{M as P}from"./markdown-editor-B0i_LOAR.js";import{A as R}from"./arrow-left-BRSAC1N6.js";import{C as $}from"./circle-check-big-AlE11jqb.js";function Q(){const F=D(),{toast:h}=M(),[n,x]=l.useState({stack:{runtime:"",framework:"",language:"",database:"",deployment:"",repository:""},commands:{}}),[y,f]=l.useState(""),[E,k]=l.useState(""),[L,N]=l.useState(!0),[C,w]=l.useState(!1);l.useEffect(()=>{fetch(`${b}/api/v1/context/architecture`).then(t=>t.json()).then(t=>{if(t.success){const a=t.document,m={stack:{runtime:a.metadata.stack?.runtime||"",framework:a.metadata.stack?.framework||"",language:a.metadata.stack?.language||"",database:a.metadata.stack?.database||"",deployment:a.metadata.stack?.deployment||"",repository:a.metadata.stack?.repository||""},commands:a.metadata.commands||{}};x(m);const s=Object.entries(m.commands).map(([r,c])=>`${r}: ${c}`).join(`
|
|
2
2
|
`);k(s),f(a.content.trim())}N(!1)}).catch(t=>{console.error("Failed to load context:",t),h({title:"Error",description:"Failed to load architecture documentation",variant:"destructive"}),N(!1)})},[h]);const A=async()=>{w(!0);try{const a=await(await fetch(`${b}/api/v1/context/architecture`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:y,metadata:{stack:n.stack,commands:n.commands}})})).json();if(a.success)h({title:"Success",description:"Architecture documentation saved successfully",action:e.jsx($,{className:"h-4 w-4"})}),F("/context/architecture");else throw new Error(a.error||"Failed to save context")}catch(t){console.error("Save error:",t),h({title:"Error",description:"Failed to save architecture documentation",variant:"destructive"})}finally{w(!1)}},i=(t,a)=>{x(m=>{const s={...m},r=t.split(".");let c=s;for(let g=0;g<r.length-1;g++)c=c[r[g]];return c[r[r.length-1]]=a,s})},T=t=>{k(t);const a={};t.split(`
|
|
3
3
|
`).filter(s=>s.trim()).forEach(s=>{const[r,...c]=s.split(":");r&&c.length>0&&(a[r.trim()]=c.join(":").trim())}),x(s=>({...s,commands:a}))};return L?e.jsx("div",{className:"space-y-6",children:e.jsx(u,{children:e.jsx(p,{className:"pt-6",children:e.jsx("div",{className:"text-center",children:e.jsx("p",{children:"Loading..."})})})})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold tracking-tight",children:"Edit Architecture"}),e.jsx("p",{className:"text-muted-foreground text-sm hidden sm:block",children:"Edit technical architecture and supporting metadata"})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[e.jsx(S,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(I,{to:"/context/architecture",className:"text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(R,{className:"w-4 h-4"})})}),e.jsxs(S,{onClick:A,disabled:C,size:"sm",children:[e.jsx(_,{className:"w-4 h-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:C?"Saving...":"Save"})]})]})]}),e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(v,{children:"Technology Stack"})}),e.jsxs(p,{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"runtime",children:"Runtime"}),e.jsx(d,{id:"runtime",value:n.stack.runtime,onChange:t=>i("stack.runtime",t.target.value),placeholder:"node|python|go|etc"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"framework",children:"Framework"}),e.jsx(d,{id:"framework",value:n.stack.framework,onChange:t=>i("stack.framework",t.target.value),placeholder:"express|fastify|django|gin|etc"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"language",children:"Language"}),e.jsx(d,{id:"language",value:n.stack.language,onChange:t=>i("stack.language",t.target.value),placeholder:"typescript|javascript|python|go|etc"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"database",children:"Database"}),e.jsx(d,{id:"database",value:n.stack.database,onChange:t=>i("stack.database",t.target.value),placeholder:"postgresql|mysql|mongodb|sqlite|etc"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"deployment",children:"Deployment"}),e.jsx(d,{id:"deployment",value:n.stack.deployment,onChange:t=>i("stack.deployment",t.target.value),placeholder:"docker|kubernetes|vercel|aws|etc"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"repository",children:"Repository"}),e.jsx(d,{id:"repository",value:n.stack.repository,onChange:t=>i("stack.repository",t.target.value),placeholder:"https://github.com/yourorg/yourproject"})]})]})]})]}),e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(v,{children:"Quick Commands"})}),e.jsx(p,{className:"space-y-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"commands",children:"Commands (format: command_name: command_to_run)"}),e.jsx(B,{id:"commands",value:E,onChange:t=>T(t.target.value),placeholder:`install: npm install
|
|
4
4
|
dev: npm run dev
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{H as g,r as n,A as v,j as e,n as y,g as k,B as l,
|
|
1
|
+
import{H as g,r as n,A as v,j as e,n as y,g as k,B as l,az as b,ay as w,L as C,J as E,av as A}from"./index-B0JO3x3V.js";import{C as a,a as c,b as o,c as m}from"./card-B9ym6neB.js";import{c as D}from"./clipboard-B9ndUJKl.js";function F(){const{toast:h}=g(),[r,x]=n.useState(null),[u,p]=n.useState(!0),[j,i]=n.useState(!1);n.useEffect(()=>{fetch(`${v}/api/v1/context/architecture`).then(t=>{if(t.ok)return t.json();throw new Error("Not found")}).then(t=>{t.success?(x(t.document),i(!0)):i(!1)}).catch(()=>{i(!1)}).finally(()=>{p(!1)})},[]);const N=async()=>{const t=".nut/context/architecture.md";try{await D(t),h({title:"Copied!",description:`Path ${t} copied to clipboard`})}catch(d){console.error("Failed to copy path:",d),h({title:"Error",description:"Failed to copy path to clipboard",variant:"destructive"})}},f=()=>{const t=new CustomEvent("discuss-in-chat",{detail:{type:"context",id:"architecture-md",filename:"architecture.md",name:"architecture.md",path:".nut/context/architecture.md"}});window.dispatchEvent(t)};if(u)return e.jsx("div",{className:"space-y-6",children:e.jsx(a,{children:e.jsx(c,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center",children:[e.jsx(y,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Loading architecture documentation..."})]})})})});if(!j||!r)return e.jsx("div",{className:"space-y-6",children:e.jsx(a,{children:e.jsx(c,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(k,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Architecture Documentation Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Architecture documentation will appear here once created."})]})})})});const s=r.metadata;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Technical Architecture"}),e.jsx("p",{className:"text-muted-foreground",children:"System design, components, and technical patterns"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(l,{variant:"outline",size:"sm",onClick:f,children:[e.jsx(b,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Discuss"})]}),e.jsxs(l,{variant:"outline",size:"sm",onClick:N,children:[e.jsx(w,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Copy Path"})]}),e.jsx(l,{size:"sm",asChild:!0,children:e.jsxs(C,{to:"/context/architecture/edit",children:[e.jsx(E,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Edit"})]})})]})]}),s&&e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs(a,{children:[e.jsx(o,{className:"pb-3",children:e.jsx(m,{className:"text-lg font-semibold",children:"Technology Stack"})}),e.jsx(c,{className:"space-y-3",children:s.stack&&e.jsxs("div",{className:"space-y-1 text-sm",children:[s.stack.runtime&&e.jsxs("div",{children:["Runtime: ",s.stack.runtime]}),s.stack.framework&&e.jsxs("div",{children:["Framework: ",s.stack.framework]}),s.stack.language&&e.jsxs("div",{children:["Language: ",s.stack.language]}),s.stack.database&&e.jsxs("div",{children:["Database: ",s.stack.database]}),s.stack.deployment&&e.jsxs("div",{children:["Deployment: ",s.stack.deployment]}),s.stack.repository&&e.jsxs("div",{children:["Repository:"," ",e.jsx("a",{href:s.stack.repository,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:s.stack.repository})]})]})})]}),e.jsxs(a,{children:[e.jsx(o,{className:"pb-3",children:e.jsx(m,{className:"text-lg font-semibold",children:"Quick Commands"})}),e.jsx(c,{className:"space-y-3",children:s.commands&&e.jsxs("div",{className:"space-y-1",children:[Object.entries(s.commands).slice(0,5).map(([t,d])=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("span",{className:"font-medium capitalize",children:[t,": "]}),e.jsx("code",{className:"bg-muted px-2 py-1 rounded text-xs",children:d})]},t)),Object.entries(s.commands).length>5&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["+ ",Object.entries(s.commands).length-5," more commands"]})]})})]})]}),e.jsxs(a,{children:[e.jsx(o,{children:e.jsx(m,{className:"text-lg font-semibold",children:"Architecture Documentation"})}),e.jsx(c,{children:e.jsx("div",{className:"prose prose-sm max-w-none dark:prose-invert",children:e.jsx(A,{children:r.content||"No content available"})})})]})]})}export{F as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as Y,m as le,r as n,
|
|
1
|
+
import{c as Y,m as le,r as n,b5 as c,j as e,a1 as O,b4 as ce,D as I,_ as M,B as l,a as $,b as V,d as _,e as z,I as j,v as H,w as J,x as W,y as q,z as a,$ as B,M as oe,N as de,T as he,O as ue,P as xe,Q as me,R as ge,U as je,V as pe,W as ve,t as r}from"./index-B0JO3x3V.js";import{C as p,b as v,c as w,d as f,a as y}from"./card-B9ym6neB.js";import{L as o}from"./label-BHOOQ99D.js";import{S as U}from"./switch-BYf9VEgx.js";import{B as k}from"./badge-DaM4gF82.js";import{C as we}from"./circle-alert-C-piOZLm.js";/**
|
|
2
2
|
* @license lucide-react v0.542.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -8,4 +8,4 @@ import{c as Y,m as le,r as n,aX as c,j as e,a1 as O,aW as ce,D as I,_ as M,B as
|
|
|
8
8
|
*
|
|
9
9
|
* This source code is licensed under the ISC license.
|
|
10
10
|
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/const Ne=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]],Se=Y("user-plus",Ne);function Fe(){const{user:N,authEnabled:K,checkAuthStatus:Q}=le(),[i,d]=n.useState(null),[X,F]=n.useState(!0),[S,P]=n.useState(!1),[G,C]=n.useState(!1),[b,D]=n.useState(""),[A,R]=n.useState(""),[T,L]=n.useState("viewer"),[E,u]=n.useState(null),[x,m]=n.useState(""),Z=!K||N?.role==="admin";n.useEffect(()=>{h()},[]);const h=async()=>{try{F(!0);const s=await c("/api/v1/auth-settings");s.success?d(s.data):d(null)}catch(s){console.error("Failed to load auth settings:",s),d(null)}finally{F(!1)}},ee=async()=>{if(!i)return;const s=!i.enabled;try{const t=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({enabled:s})});if(t.success)d({...i,enabled:s}),await Q(),r({title:"Success",description:`Authentication ${s?"enabled":"disabled"}`});else throw new Error(t.error||"Failed to toggle auth")}catch(t){r({title:"Error",description:t.message||"Failed to toggle authentication",variant:"destructive"})}},se=async()=>{if(!i)return;const s=!i.allowRegistration;try{const t=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({allowRegistration:s})});if(t.success)d({...i,allowRegistration:s}),r({title:"Success",description:`Self-registration ${s?"enabled":"disabled"}`});else throw new Error(t.error||"Failed to update setting")}catch(t){r({title:"Error",description:t.message||"Failed to update setting",variant:"destructive"})}},te=async()=>{if(!b||!A){r({title:"Error",description:"Please provide email and name",variant:"destructive"});return}try{const s=await c("/api/v1/auth-settings/users",{method:"POST",body:JSON.stringify({email:b,name:A,role:T})});if(s.success)await h(),C(!1),D(""),R(""),L("viewer"),r({title:"Success",description:"User added to whitelist"});else throw new Error(s.error||"Failed to add user")}catch(s){r({title:"Error",description:s.message||"Failed to add user",variant:"destructive"})}},ie=async s=>{try{const t=await c(`/api/v1/auth-settings/users/${s}`,{method:"DELETE"});if(t.success)await h(),r({title:"Success",description:"User removed from whitelist"});else throw new Error(t.error||"Failed to remove user")}catch(t){r({title:"Error",description:t.message||"Failed to remove user",variant:"destructive"})}},re=async(s,t)=>{try{const g=await c(`/api/v1/auth-settings/users/${s}`,{method:"PUT",body:JSON.stringify({role:t})});if(g.success)await h(),r({title:"Success",description:"User role updated"});else throw new Error(g.error||"Failed to update role")}catch(g){r({title:"Error",description:g.message||"Failed to update role",variant:"destructive"})}},ae=async()=>{if(!(!E||!x)){if(x.length<8){r({title:"Error",description:"Password must be at least 8 characters",variant:"destructive"});return}try{const s=await c(`/api/v1/auth-settings/users/${E}/reset-password`,{method:"POST",body:JSON.stringify({newPassword:x})});if(s.success)u(null),m(""),r({title:"Success",description:"Password reset successfully"});else throw new Error(s.error||"Failed to reset password")}catch(s){r({title:"Error",description:s.message||"Failed to reset password",variant:"destructive"})}}},ne=async()=>{if(i)try{P(!0);const s=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({session:i.session})});if(s.success)r({title:"Success",description:"Session settings updated"});else throw new Error(s.error||"Failed to update settings")}catch(s){r({title:"Error",description:s.message||"Failed to update settings",variant:"destructive"})}finally{P(!1)}};return X?e.jsx("div",{children:"Loading..."}):i?Z?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage authentication settings and user access."})]}),e.jsx(O,{}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ce,{className:"h-5 w-5"}),e.jsx(w,{children:"Authentication Status"})]}),e.jsx(f,{children:"Control whether authentication is required to access Coconut."})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"auth-enabled",children:"Require Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When enabled, users must log in to access Coconut"})]}),e.jsx(U,{id:"auth-enabled",checked:i.enabled,onCheckedChange:ee})]}),i.enabled&&e.jsxs("div",{className:"flex items-center justify-between pt-2 border-t",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"allow-registration",children:"Allow Self-Registration"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Whitelisted users can create their own accounts"})]}),e.jsx(U,{id:"allow-registration",checked:i.allowRegistration,onCheckedChange:se})]})]})]}),e.jsxs(p,{children:[e.jsx(v,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(w,{children:"Whitelisted Users"}),e.jsx(f,{children:"Manage users who can access this Coconut instance."})]}),e.jsxs(I,{open:G,onOpenChange:C,children:[e.jsx(M,{asChild:!0,children:e.jsxs(l,{size:"sm",children:[e.jsx(Se,{className:"h-4 w-4 mr-2"}),"Add User"]})}),e.jsxs($,{children:[e.jsxs(V,{children:[e.jsx(_,{children:"Add User to Whitelist"}),e.jsx(z,{children:"Add a user's email to allow them to register and access Coconut."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-email",children:"Email"}),e.jsx(j,{id:"new-email",type:"email",value:b,onChange:s=>D(s.target.value),placeholder:"user@example.com"})]}),e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-name",children:"Name"}),e.jsx(j,{id:"new-name",value:A,onChange:s=>R(s.target.value),placeholder:"User Name"})]}),e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-role",children:"Role"}),e.jsxs(H,{value:T,onValueChange:s=>L(s),children:[e.jsx(J,{children:e.jsx(W,{})}),e.jsxs(q,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]})]})]}),e.jsxs(B,{children:[e.jsx(l,{variant:"outline",onClick:()=>C(!1),children:"Cancel"}),e.jsx(l,{onClick:te,children:"Add User"})]})]})]})]})}),e.jsx(y,{children:e.jsx("div",{className:"space-y-4",children:i.providers.local.users.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"font-medium",children:s.name}),s.registered?e.jsx(k,{variant:"default",className:"text-xs",children:"Registered"}):e.jsx(k,{variant:"secondary",className:"text-xs",children:"Pending"}),s.id===N?.id&&e.jsx(k,{variant:"outline",className:"text-xs",children:"You"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s.email}),s.lastLoginAt&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Last login: ",new Date(s.lastLoginAt).toLocaleString()]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(H,{value:s.role,onValueChange:t=>re(s.id,t),children:[e.jsx(J,{className:"w-40",children:e.jsx(W,{})}),e.jsxs(q,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]}),e.jsxs(I,{open:E===s.id,onOpenChange:t=>{t||(u(null),m(""))},children:[e.jsx(M,{asChild:!0,children:e.jsx(l,{size:"sm",variant:"outline",onClick:()=>u(s.id),children:e.jsx(ye,{className:"h-4 w-4"})})}),e.jsxs($,{children:[e.jsxs(V,{children:[e.jsx(_,{children:"Reset Password"}),e.jsxs(z,{children:["Set a new password for ",s.name]})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{children:[e.jsx(o,{htmlFor:"reset-password",children:"New Password"}),e.jsx(j,{id:"reset-password",type:"password",value:x,onChange:t=>m(t.target.value),placeholder:"At least 8 characters",minLength:8})]})}),e.jsxs(B,{children:[e.jsx(l,{variant:"outline",onClick:()=>{u(null),m("")},children:"Cancel"}),e.jsx(l,{onClick:ae,children:"Reset Password"})]})]})]}),s.id!==N?.id&&e.jsxs(oe,{children:[e.jsx(de,{asChild:!0,children:e.jsx(l,{size:"sm",variant:"destructive",children:e.jsx(he,{className:"h-4 w-4"})})}),e.jsxs(ue,{children:[e.jsxs(xe,{children:[e.jsx(me,{children:"Remove User"}),e.jsxs(ge,{children:["Are you sure you want to remove ",s.name," from the whitelist? They will no longer be able to access Coconut."]})]}),e.jsxs(je,{children:[e.jsx(pe,{children:"Cancel"}),e.jsx(ve,{onClick:()=>ie(s.id),children:"Remove"})]})]})]})]})]},s.id))})})]}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsx(w,{children:"Session Settings"}),e.jsx(f,{children:"Configure session behavior and security."})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"session-expiry",children:"Session Expiry"}),e.jsx(j,{id:"session-expiry",value:i.session.expiresIn,onChange:s=>d({...i,session:{...i.session,expiresIn:s.target.value}}),placeholder:"7d"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Format: 30s, 15m, 24h, 7d"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"secure-cookies",children:"Secure Cookies (HTTPS only)"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Enable in production with HTTPS"})]}),e.jsx(U,{id:"secure-cookies",checked:i.session.secure||!1,onCheckedChange:s=>d({...i,session:{...i.session,secure:s}})})]})]})]}),e.jsxs("div",{className:"flex justify-end space-x-2",children:[e.jsx(l,{variant:"outline",onClick:h,disabled:S,children:"Cancel"}),e.jsx(l,{onClick:ne,disabled:S,children:S?"Saving...":"Save Session Settings"})]})]}):e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"You don't have permission to manage authentication settings."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Secure your Coconut instance with authentication."})]}),e.jsx(O,{}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(w,{children:"Authentication Not Configured"})]}),e.jsx(f,{children:"Authentication has not been initialized. Use the CLI to set up authentication."})]}),e.jsxs(y,{children:[e.jsx("div",{className:"bg-muted p-4 rounded-md",children:e.jsxs("code",{className:"text-sm",children:["$ nut auth init",e.jsx("br",{}),"$ nut auth toggle"]})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-4",children:"This will create an admin user and enable authentication for your Coconut instance."})]})]})]})}export{Fe as default};
|
|
11
|
+
*/const Ne=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]],Se=Y("user-plus",Ne);function Fe(){const{user:N,authEnabled:K,checkAuthStatus:Q}=le(),[i,d]=n.useState(null),[G,F]=n.useState(!0),[S,P]=n.useState(!1),[X,C]=n.useState(!1),[b,D]=n.useState(""),[A,R]=n.useState(""),[T,L]=n.useState("viewer"),[E,u]=n.useState(null),[x,m]=n.useState(""),Z=!K||N?.role==="admin";n.useEffect(()=>{h()},[]);const h=async()=>{try{F(!0);const s=await c("/api/v1/auth-settings");s.success?d(s.data):d(null)}catch(s){console.error("Failed to load auth settings:",s),d(null)}finally{F(!1)}},ee=async()=>{if(!i)return;const s=!i.enabled;try{const t=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({enabled:s})});if(t.success)d({...i,enabled:s}),await Q(),r({title:"Success",description:`Authentication ${s?"enabled":"disabled"}`});else throw new Error(t.error||"Failed to toggle auth")}catch(t){r({title:"Error",description:t.message||"Failed to toggle authentication",variant:"destructive"})}},se=async()=>{if(!i)return;const s=!i.allowRegistration;try{const t=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({allowRegistration:s})});if(t.success)d({...i,allowRegistration:s}),r({title:"Success",description:`Self-registration ${s?"enabled":"disabled"}`});else throw new Error(t.error||"Failed to update setting")}catch(t){r({title:"Error",description:t.message||"Failed to update setting",variant:"destructive"})}},te=async()=>{if(!b||!A){r({title:"Error",description:"Please provide email and name",variant:"destructive"});return}try{const s=await c("/api/v1/auth-settings/users",{method:"POST",body:JSON.stringify({email:b,name:A,role:T})});if(s.success)await h(),C(!1),D(""),R(""),L("viewer"),r({title:"Success",description:"User added to whitelist"});else throw new Error(s.error||"Failed to add user")}catch(s){r({title:"Error",description:s.message||"Failed to add user",variant:"destructive"})}},ie=async s=>{try{const t=await c(`/api/v1/auth-settings/users/${s}`,{method:"DELETE"});if(t.success)await h(),r({title:"Success",description:"User removed from whitelist"});else throw new Error(t.error||"Failed to remove user")}catch(t){r({title:"Error",description:t.message||"Failed to remove user",variant:"destructive"})}},re=async(s,t)=>{try{const g=await c(`/api/v1/auth-settings/users/${s}`,{method:"PUT",body:JSON.stringify({role:t})});if(g.success)await h(),r({title:"Success",description:"User role updated"});else throw new Error(g.error||"Failed to update role")}catch(g){r({title:"Error",description:g.message||"Failed to update role",variant:"destructive"})}},ae=async()=>{if(!(!E||!x)){if(x.length<8){r({title:"Error",description:"Password must be at least 8 characters",variant:"destructive"});return}try{const s=await c(`/api/v1/auth-settings/users/${E}/reset-password`,{method:"POST",body:JSON.stringify({newPassword:x})});if(s.success)u(null),m(""),r({title:"Success",description:"Password reset successfully"});else throw new Error(s.error||"Failed to reset password")}catch(s){r({title:"Error",description:s.message||"Failed to reset password",variant:"destructive"})}}},ne=async()=>{if(i)try{P(!0);const s=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({session:i.session})});if(s.success)r({title:"Success",description:"Session settings updated"});else throw new Error(s.error||"Failed to update settings")}catch(s){r({title:"Error",description:s.message||"Failed to update settings",variant:"destructive"})}finally{P(!1)}};return G?e.jsx("div",{children:"Loading..."}):i?Z?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage authentication settings and user access."})]}),e.jsx(O,{}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ce,{className:"h-5 w-5"}),e.jsx(w,{children:"Authentication Status"})]}),e.jsx(f,{children:"Control whether authentication is required to access Coconut."})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"auth-enabled",children:"Require Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When enabled, users must log in to access Coconut"})]}),e.jsx(U,{id:"auth-enabled",checked:i.enabled,onCheckedChange:ee})]}),i.enabled&&e.jsxs("div",{className:"flex items-center justify-between pt-2 border-t",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"allow-registration",children:"Allow Self-Registration"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Whitelisted users can create their own accounts"})]}),e.jsx(U,{id:"allow-registration",checked:i.allowRegistration,onCheckedChange:se})]})]})]}),e.jsxs(p,{children:[e.jsx(v,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(w,{children:"Whitelisted Users"}),e.jsx(f,{children:"Manage users who can access this Coconut instance."})]}),e.jsxs(I,{open:X,onOpenChange:C,children:[e.jsx(M,{asChild:!0,children:e.jsxs(l,{size:"sm",children:[e.jsx(Se,{className:"h-4 w-4 mr-2"}),"Add User"]})}),e.jsxs($,{children:[e.jsxs(V,{children:[e.jsx(_,{children:"Add User to Whitelist"}),e.jsx(z,{children:"Add a user's email to allow them to register and access Coconut."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-email",children:"Email"}),e.jsx(j,{id:"new-email",type:"email",value:b,onChange:s=>D(s.target.value),placeholder:"user@example.com"})]}),e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-name",children:"Name"}),e.jsx(j,{id:"new-name",value:A,onChange:s=>R(s.target.value),placeholder:"User Name"})]}),e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-role",children:"Role"}),e.jsxs(H,{value:T,onValueChange:s=>L(s),children:[e.jsx(J,{children:e.jsx(W,{})}),e.jsxs(q,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]})]})]}),e.jsxs(B,{children:[e.jsx(l,{variant:"outline",onClick:()=>C(!1),children:"Cancel"}),e.jsx(l,{onClick:te,children:"Add User"})]})]})]})]})}),e.jsx(y,{children:e.jsx("div",{className:"space-y-4",children:i.providers.local.users.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"font-medium",children:s.name}),s.registered?e.jsx(k,{variant:"default",className:"text-xs",children:"Registered"}):e.jsx(k,{variant:"secondary",className:"text-xs",children:"Pending"}),s.id===N?.id&&e.jsx(k,{variant:"outline",className:"text-xs",children:"You"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s.email}),s.lastLoginAt&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Last login: ",new Date(s.lastLoginAt).toLocaleString()]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(H,{value:s.role,onValueChange:t=>re(s.id,t),children:[e.jsx(J,{className:"w-40",children:e.jsx(W,{})}),e.jsxs(q,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]}),e.jsxs(I,{open:E===s.id,onOpenChange:t=>{t||(u(null),m(""))},children:[e.jsx(M,{asChild:!0,children:e.jsx(l,{size:"sm",variant:"outline",onClick:()=>u(s.id),children:e.jsx(ye,{className:"h-4 w-4"})})}),e.jsxs($,{children:[e.jsxs(V,{children:[e.jsx(_,{children:"Reset Password"}),e.jsxs(z,{children:["Set a new password for ",s.name]})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{children:[e.jsx(o,{htmlFor:"reset-password",children:"New Password"}),e.jsx(j,{id:"reset-password",type:"password",value:x,onChange:t=>m(t.target.value),placeholder:"At least 8 characters",minLength:8})]})}),e.jsxs(B,{children:[e.jsx(l,{variant:"outline",onClick:()=>{u(null),m("")},children:"Cancel"}),e.jsx(l,{onClick:ae,children:"Reset Password"})]})]})]}),s.id!==N?.id&&e.jsxs(oe,{children:[e.jsx(de,{asChild:!0,children:e.jsx(l,{size:"sm",variant:"destructive",children:e.jsx(he,{className:"h-4 w-4"})})}),e.jsxs(ue,{children:[e.jsxs(xe,{children:[e.jsx(me,{children:"Remove User"}),e.jsxs(ge,{children:["Are you sure you want to remove ",s.name," from the whitelist? They will no longer be able to access Coconut."]})]}),e.jsxs(je,{children:[e.jsx(pe,{children:"Cancel"}),e.jsx(ve,{onClick:()=>ie(s.id),children:"Remove"})]})]})]})]})]},s.id))})})]}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsx(w,{children:"Session Settings"}),e.jsx(f,{children:"Configure session behavior and security."})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"session-expiry",children:"Session Expiry"}),e.jsx(j,{id:"session-expiry",value:i.session.expiresIn,onChange:s=>d({...i,session:{...i.session,expiresIn:s.target.value}}),placeholder:"7d"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Format: 30s, 15m, 24h, 7d"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"secure-cookies",children:"Secure Cookies (HTTPS only)"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Enable in production with HTTPS"})]}),e.jsx(U,{id:"secure-cookies",checked:i.session.secure||!1,onCheckedChange:s=>d({...i,session:{...i.session,secure:s}})})]})]})]}),e.jsxs("div",{className:"flex justify-end space-x-2",children:[e.jsx(l,{variant:"outline",onClick:h,disabled:S,children:"Cancel"}),e.jsx(l,{onClick:ne,disabled:S,children:S?"Saving...":"Save Session Settings"})]})]}):e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"You don't have permission to manage authentication settings."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Secure your Coconut instance with authentication."})]}),e.jsx(O,{}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(w,{children:"Authentication Not Configured"})]}),e.jsx(f,{children:"Authentication has not been initialized. Use the CLI to set up authentication."})]}),e.jsxs(y,{children:[e.jsx("div",{className:"bg-muted p-4 rounded-md",children:e.jsxs("code",{className:"text-sm",children:["$ nut auth init",e.jsx("br",{}),"$ nut auth toggle"]})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-4",children:"This will create an admin user and enable authentication for your Coconut instance."})]})]})]})}export{Fe as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as m,j as e,n as x,A as f}from"./index-
|
|
1
|
+
import{r as m,j as e,n as x,A as f}from"./index-B0JO3x3V.js";import{C as w}from"./circle-check-4zzXsmHH.js";import{C as b}from"./circle-x-D58MbKgZ.js";const r="coconut/github-auth-state";function j(s){try{window.opener&&window.opener.postMessage({type:"github-auth",...s},window.location.origin)}catch{}}const v=()=>{const[s,d]=m.useState("pending"),[h,p]=m.useState("Authorizing GitHub…");return m.useEffect(()=>{const a=new URLSearchParams(window.location.search),u=a.get("error"),l=a.get("token"),n=a.get("expires_at")||a.get("expiresAt"),c=a.get("state"),o=t=>{j(t),d(t.success?"success":"error"),p(t.message),setTimeout(()=>{try{window.close()}catch{}},1200)};if(u){localStorage.removeItem(r),o({success:!1,message:decodeURIComponent(u)});return}if(!l||!n||!c){localStorage.removeItem(r),o({success:!1,message:"Missing authorization parameters. Please try again."});return}const g=localStorage.getItem(r);if(!g||g!==c){localStorage.removeItem(r),o({success:!1,message:"Authorization state mismatch. Please start again."});return}(async()=>{try{const t=await fetch(`${f}/api/v1/git/providers/github/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:l,expiresAt:n,state:c})}),i=await t.json();if(!t.ok||!i.success)throw new Error(i?.error?.message||"Failed to store GitHub token");localStorage.removeItem(r),o({success:!0,message:"GitHub connected successfully!",expiresAt:i.data?.expiresAt||n})}catch(t){localStorage.removeItem(r),o({success:!1,message:t?.message||"Failed to store GitHub token. Please try again."})}})()},[]),e.jsx("div",{className:"flex h-screen items-center justify-center bg-background px-6",children:e.jsxs("div",{className:"max-w-sm rounded-lg border bg-card p-6 text-center shadow-sm",children:[e.jsxs("div",{className:"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted",children:[s==="pending"&&e.jsx(x,{className:"h-6 w-6 animate-spin text-muted-foreground"}),s==="success"&&e.jsx(w,{className:"h-6 w-6 text-green-600"}),s==="error"&&e.jsx(b,{className:"h-6 w-6 text-red-600"})]}),e.jsx("h1",{className:"text-lg font-semibold",children:"GitHub Authorization"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:h}),s!=="pending"&&e.jsx("p",{className:"mt-4 text-xs text-muted-foreground",children:"You can close this window and return to Coconut."})]})})};export{v as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as ce,H as de,r as i,j as e,B as r,k as oe,a3 as me,q as xe,s as M,X as he,g as ue,J as fe,D as ge,a as je,b as pe,d as ve,v as Ne,w as ye,x as we,y as Ce,z as S,i as Se,a5 as R,a6 as B,a7 as H,a8 as L,a9 as O,ae as G,h as be,a0 as Ae,A as I}from"./index-B8vejVRZ.js";import{C as p,b as ke,a as _,c as De}from"./card-CvaBJsG6.js";import{B as U}from"./badge-NJasrAx_.js";import{u as Me}from"./use-terminal-2DGl8X5T.js";import{C as Ie,a as $e,T as Pe}from"./terminal-preview-Be68j_3t.js";import{b as Te,d as Ee,c as ze,a as Fe}from"./droid-CmYuCN_q.js";import{R as Re}from"./refresh-cw-CnHMzcH3.js";import{P as Be}from"./play-a8BsF4gF.js";import"./xterm-DTxiCjtJ.js";const He=c=>c?Array.isArray(c)?c.filter(x=>typeof x=="string").map(x=>x.trim()).filter(Boolean):typeof c=="string"?c.split(",").map(x=>x.trim()).filter(Boolean):[]:[];function Xe(){const c=ce(),{sessions:x,loading:b,error:$,refreshSessions:w,createSession:V,destroySession:q}=Me(),{toast:v}=de(),[P,W]=i.useState([]),[J,X]=i.useState(!0),[g,A]=i.useState(()=>({})),[k,N]=i.useState(!1),[j,K]=i.useState("claude"),[T,Q]=i.useState(""),[D,E]=i.useState(!1),[h,Y]=i.useState([]),[f,y]=i.useState([]),[Z,ee]=i.useState({}),[u,se]=i.useState([]),[o,C]=i.useState([]),te=s=>{const t=Date.now(),a=new Date(s).getTime(),n=Math.max(0,Math.floor((t-a)/1e3));if(n<60)return`${n}s ago`;const d=Math.floor(n/60);if(d<60)return`${d}m ago`;const l=Math.floor(d/60);return l<24?`${l}h ago`:`${Math.floor(l/24)}d ago`};i.useEffect(()=>{(async()=>{try{const t=await fetch(`${I}/api/v1/proposals`);if(t.ok){const a=await t.json(),n=a.data||a;W(Array.isArray(n)?n:[])}}catch(t){console.error("Error loading proposals:",t)}finally{X(!1)}})()},[]),i.useEffect(()=>{w()},[w]),i.useEffect(()=>{if(!k)return;(async()=>{try{const t=await fetch(`${I}/api/v1/mcp`);if(t.ok){const a=await t.json();a?.success&&Array.isArray(a.servers)&&(Y(a.servers),y(n=>n.filter(d=>a.servers.includes(d))),a.mcpServers&&typeof a.mcpServers=="object"&&ee(a.mcpServers))}}catch(t){console.error("Failed to load MCP servers",t)}try{const t=await fetch(`${I}/api/v1/agents`);if(t.ok){const a=await t.json(),d=(Array.isArray(a?.documents)?a.documents:[]).map(l=>({id:l.filename,name:l?.metadata?.name||l.title||l.filename,tools:He(l?.metadata?.tools)}));se(d),C(l=>l.filter(F=>d.some(re=>re.id===F)))}}catch(t){console.error("Failed to load agents",t)}})()},[k]),i.useEffect(()=>{o.length!==0&&y(s=>{const t=new Set(s),a=h.length>0?new Set(h):void 0;return o.forEach(n=>{const d=u.find(l=>l.id===n);d&&d.tools.forEach(l=>{(!a||a.has(l))&&t.add(l)})}),Array.from(t)})},[o,u,h]);const m=i.useMemo(()=>x.filter(s=>s.proposalId?.startsWith("cp-")||s.proposalId?.startsWith("ag-")).sort((s,t)=>new Date(t.lastActivity).getTime()-new Date(s.lastActivity).getTime()),[x]);i.useEffect(()=>{A(s=>{const t={...s};return m.forEach(a=>{a.id in t||(t[a.id]=!0)}),t})},[m]);const z=i.useMemo(()=>P.filter(s=>s.status==="draft"||s.status==="approved").sort((s,t)=>new Date(t.metadata.createdAt).getTime()-new Date(s.metadata.createdAt).getTime()).slice(0,3),[P]),ae=()=>{const s=m.every(a=>g[a.id]),t={};m.forEach(a=>{t[a.id]=!s}),A(t)},ie=m.length>0&&m.every(s=>g[s.id]),ne=async s=>{await q(s)?(v({title:"Session closed",description:s}),setTimeout(()=>w(),100)):v({title:"Failed to close session",description:s,variant:"destructive"})},le=async()=>{E(!0);try{const s=`cp-${Date.now()}`,t={proposalId:s,contextType:"change-proposal",cliAgent:j,mcpServersMap:Z,selectedMcpServers:f,agents:u,selectedAgentIds:o,automationEnabled:!1,customInstruction:T.trim(),includeDefaultInstructions:!1};let a="";j==="claude"?a=Te(t):j==="gemini"?a=Ee(t):j==="codex"?a=ze(t):j==="droid"&&(a=Fe(t)),await V(s,!1,a)?(v({title:"Coding session started",description:`Session ${s} created`}),N(!1),c(`/terminal/${s}`)):v({title:"Failed to start session",description:"Could not create terminal session",variant:"destructive"})}catch(s){console.error("Error starting coding session:",s),v({title:"Error",description:"Failed to start coding session",variant:"destructive"})}finally{E(!1)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Code"}),e.jsx("p",{className:"text-muted-foreground hidden sm:block",children:"Terminal sessions and coding agents"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(r,{variant:"outline",size:"sm",onClick:()=>w(),disabled:b,children:[e.jsx(Re,{className:`h-4 w-4 sm:mr-2 ${b?"animate-spin":""}`}),e.jsx("span",{className:"hidden sm:inline",children:"Refresh"})]}),m.length>0&&e.jsx(r,{variant:"outline",size:"sm",onClick:ae,children:ie?e.jsxs(e.Fragment,{children:[e.jsx(Ie,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Hide All"})]}):e.jsxs(e.Fragment,{children:[e.jsx($e,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Show All"})]})}),e.jsxs(r,{size:"sm",onClick:()=>N(!0),children:[e.jsx(Be,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Interactive Session"})]})]})]}),$&&e.jsx("div",{className:"p-4 bg-red-50 border border-red-200 rounded-lg",children:e.jsx("div",{className:"text-red-600",children:$})}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Sessions"}),b?e.jsx("div",{className:"space-y-2",children:[...Array(2)].map((s,t)=>e.jsx(p,{className:"p-3",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"h-4 w-4 rounded bg-muted animate-pulse"}),e.jsxs("div",{children:[e.jsx("div",{className:"h-4 w-40 bg-muted rounded animate-pulse mb-2"}),e.jsx("div",{className:"h-3 w-24 bg-muted rounded animate-pulse"})]})]}),e.jsx("div",{className:"h-6 w-20 bg-muted rounded animate-pulse"})]})},t))}):m.length===0?e.jsx(p,{className:"p-8",children:e.jsxs("div",{className:"flex flex-col items-center justify-center text-center space-y-3",children:[e.jsx(oe,{className:"h-12 w-12 text-muted-foreground"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-lg mb-2",children:"No active sessions"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Get started by launching an"," ",e.jsx("button",{onClick:()=>N(!0),className:"text-primary hover:underline font-medium",children:"Interactive Session"})," ","or working on a"," ",e.jsx("button",{onClick:()=>c("/proposals"),className:"text-primary hover:underline font-medium",children:"Change Proposal"})]})]})]})}):e.jsx("div",{className:"space-y-2",children:m.slice(0,10).map(s=>e.jsxs(p,{className:"p-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(me,{className:"h-4 w-4 shrink-0"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium text-sm",children:s.proposalId}),e.jsxs("div",{className:"text-xs text-gray-500",children:["Session ",s.id.split("-").slice(-1)[0].substring(0,8)," • Last activity ",te(s.lastActivity)]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("div",{className:`flex items-center gap-1 ${s.connected?"text-green-600":"text-gray-400"}`,title:s.connected?"Connected":"Disconnected",children:e.jsx("div",{className:`w-2 h-2 rounded-full ${s.connected?"bg-green-500":"bg-gray-400"}`})}),e.jsx(r,{size:"sm",variant:"outline",onClick:()=>{A(t=>({...t,[s.id]:!t[s.id]}))},"aria-label":g[s.id]?"Hide preview":"Show preview",title:g[s.id]?"Hide preview":"Show preview",children:g[s.id]?e.jsx(xe,{className:"h-4 w-4"}):e.jsx(M,{className:"h-4 w-4"})}),e.jsx(r,{size:"sm",variant:"outline",onClick:()=>c(`/terminal/${s.proposalId}`),children:"Open"}),e.jsx(r,{size:"icon",variant:"destructive",onClick:()=>ne(s.id),title:"Close session","aria-label":"Close session",children:e.jsx(he,{className:"h-4 w-4"})})]})]}),g[s.id]&&e.jsx("div",{className:"mt-2 w-full p-2 cursor-pointer hover:opacity-80 transition-opacity",onClick:()=>c(`/terminal/${s.proposalId}`),title:"Click to open full terminal session",children:e.jsx(Pe,{sessionId:s.id,heightPx:160,maxScrollback:200})})]},s.id))})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Recent Proposals"}),J?e.jsx("div",{className:"space-y-3",children:[...Array(3)].map((s,t)=>e.jsx(p,{children:e.jsx(ke,{className:"py-3",children:e.jsxs("div",{className:"flex justify-between items-start",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"h-4 bg-muted rounded w-2/3 animate-pulse"}),e.jsx("div",{className:"h-3 bg-muted rounded w-1/3 animate-pulse"})]}),e.jsx("div",{className:"h-5 bg-muted rounded w-16 animate-pulse"})]})})},t))}):z.length===0?e.jsx(p,{children:e.jsx(_,{className:"flex items-center justify-center py-6",children:e.jsx("div",{className:"text-center text-sm text-gray-500",children:"No draft or approved proposals found"})})}):e.jsx("div",{className:"space-y-2",children:z.map(s=>e.jsx(p,{className:"hover:shadow-md transition-all cursor-pointer hover:border-primary/50",onClick:()=>c(`/terminal/${s.id}`),children:e.jsx(_,{className:"py-4",children:e.jsx("div",{className:"flex justify-between items-start gap-4",children:e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx(De,{className:"text-base leading-tight",children:s.intent}),e.jsxs("div",{className:"flex gap-1 ml-3 flex-shrink-0",children:[s.priority&&e.jsx(U,{variant:s.priority==="high"||s.priority==="critical"?"destructive":s.priority==="medium"?"secondary":"outline",className:"text-xs",children:s.priority}),e.jsx(U,{variant:"default",className:"text-xs",children:s.status})]})]}),s.content&&e.jsxs("div",{className:"text-sm text-muted-foreground leading-relaxed",children:[s.content.split(`
|
|
1
|
+
import{u as ce,H as de,r as i,j as e,B as r,k as oe,a3 as me,q as xe,s as M,X as he,g as ue,J as fe,D as ge,a as je,b as pe,d as ve,v as Ne,w as ye,x as we,y as Ce,z as S,i as Se,a5 as R,a6 as B,a7 as H,a8 as L,a9 as O,ae as G,h as be,a0 as Ae,A as I}from"./index-B0JO3x3V.js";import{C as p,b as ke,a as _,c as De}from"./card-B9ym6neB.js";import{B as U}from"./badge-DaM4gF82.js";import{u as Me}from"./use-terminal-5sW1t6SD.js";import{C as Ie,a as $e,T as Pe}from"./terminal-preview-Qv4UvCJz.js";import{b as Te,d as Ee,c as ze,a as Fe}from"./droid-CmYuCN_q.js";import{R as Re}from"./refresh-cw-uBnPtZwp.js";import{P as Be}from"./play-Y2N8OVBu.js";import"./xterm-DTxiCjtJ.js";const He=c=>c?Array.isArray(c)?c.filter(x=>typeof x=="string").map(x=>x.trim()).filter(Boolean):typeof c=="string"?c.split(",").map(x=>x.trim()).filter(Boolean):[]:[];function Xe(){const c=ce(),{sessions:x,loading:b,error:$,refreshSessions:w,createSession:V,destroySession:q}=Me(),{toast:v}=de(),[P,W]=i.useState([]),[J,X]=i.useState(!0),[g,A]=i.useState(()=>({})),[k,N]=i.useState(!1),[j,K]=i.useState("claude"),[T,Q]=i.useState(""),[D,E]=i.useState(!1),[h,Y]=i.useState([]),[f,y]=i.useState([]),[Z,ee]=i.useState({}),[u,se]=i.useState([]),[o,C]=i.useState([]),te=s=>{const t=Date.now(),a=new Date(s).getTime(),n=Math.max(0,Math.floor((t-a)/1e3));if(n<60)return`${n}s ago`;const d=Math.floor(n/60);if(d<60)return`${d}m ago`;const l=Math.floor(d/60);return l<24?`${l}h ago`:`${Math.floor(l/24)}d ago`};i.useEffect(()=>{(async()=>{try{const t=await fetch(`${I}/api/v1/proposals`);if(t.ok){const a=await t.json(),n=a.data||a;W(Array.isArray(n)?n:[])}}catch(t){console.error("Error loading proposals:",t)}finally{X(!1)}})()},[]),i.useEffect(()=>{w()},[w]),i.useEffect(()=>{if(!k)return;(async()=>{try{const t=await fetch(`${I}/api/v1/mcp`);if(t.ok){const a=await t.json();a?.success&&Array.isArray(a.servers)&&(Y(a.servers),y(n=>n.filter(d=>a.servers.includes(d))),a.mcpServers&&typeof a.mcpServers=="object"&&ee(a.mcpServers))}}catch(t){console.error("Failed to load MCP servers",t)}try{const t=await fetch(`${I}/api/v1/agents`);if(t.ok){const a=await t.json(),d=(Array.isArray(a?.documents)?a.documents:[]).map(l=>({id:l.filename,name:l?.metadata?.name||l.title||l.filename,tools:He(l?.metadata?.tools)}));se(d),C(l=>l.filter(F=>d.some(re=>re.id===F)))}}catch(t){console.error("Failed to load agents",t)}})()},[k]),i.useEffect(()=>{o.length!==0&&y(s=>{const t=new Set(s),a=h.length>0?new Set(h):void 0;return o.forEach(n=>{const d=u.find(l=>l.id===n);d&&d.tools.forEach(l=>{(!a||a.has(l))&&t.add(l)})}),Array.from(t)})},[o,u,h]);const m=i.useMemo(()=>x.filter(s=>s.proposalId?.startsWith("cp-")||s.proposalId?.startsWith("ag-")).sort((s,t)=>new Date(t.lastActivity).getTime()-new Date(s.lastActivity).getTime()),[x]);i.useEffect(()=>{A(s=>{const t={...s};return m.forEach(a=>{a.id in t||(t[a.id]=!0)}),t})},[m]);const z=i.useMemo(()=>P.filter(s=>s.status==="draft"||s.status==="approved").sort((s,t)=>new Date(t.metadata.createdAt).getTime()-new Date(s.metadata.createdAt).getTime()).slice(0,3),[P]),ae=()=>{const s=m.every(a=>g[a.id]),t={};m.forEach(a=>{t[a.id]=!s}),A(t)},ie=m.length>0&&m.every(s=>g[s.id]),ne=async s=>{await q(s)?(v({title:"Session closed",description:s}),setTimeout(()=>w(),100)):v({title:"Failed to close session",description:s,variant:"destructive"})},le=async()=>{E(!0);try{const s=`cp-${Date.now()}`,t={proposalId:s,contextType:"change-proposal",cliAgent:j,mcpServersMap:Z,selectedMcpServers:f,agents:u,selectedAgentIds:o,automationEnabled:!1,customInstruction:T.trim(),includeDefaultInstructions:!1};let a="";j==="claude"?a=Te(t):j==="gemini"?a=Ee(t):j==="codex"?a=ze(t):j==="droid"&&(a=Fe(t)),await V(s,!1,a)?(v({title:"Coding session started",description:`Session ${s} created`}),N(!1),c(`/terminal/${s}`)):v({title:"Failed to start session",description:"Could not create terminal session",variant:"destructive"})}catch(s){console.error("Error starting coding session:",s),v({title:"Error",description:"Failed to start coding session",variant:"destructive"})}finally{E(!1)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Code"}),e.jsx("p",{className:"text-muted-foreground hidden sm:block",children:"Terminal sessions and coding agents"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(r,{variant:"outline",size:"sm",onClick:()=>w(),disabled:b,children:[e.jsx(Re,{className:`h-4 w-4 sm:mr-2 ${b?"animate-spin":""}`}),e.jsx("span",{className:"hidden sm:inline",children:"Refresh"})]}),m.length>0&&e.jsx(r,{variant:"outline",size:"sm",onClick:ae,children:ie?e.jsxs(e.Fragment,{children:[e.jsx(Ie,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Hide All"})]}):e.jsxs(e.Fragment,{children:[e.jsx($e,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Show All"})]})}),e.jsxs(r,{size:"sm",onClick:()=>N(!0),children:[e.jsx(Be,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Interactive Session"})]})]})]}),$&&e.jsx("div",{className:"p-4 bg-red-50 border border-red-200 rounded-lg",children:e.jsx("div",{className:"text-red-600",children:$})}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Sessions"}),b?e.jsx("div",{className:"space-y-2",children:[...Array(2)].map((s,t)=>e.jsx(p,{className:"p-3",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"h-4 w-4 rounded bg-muted animate-pulse"}),e.jsxs("div",{children:[e.jsx("div",{className:"h-4 w-40 bg-muted rounded animate-pulse mb-2"}),e.jsx("div",{className:"h-3 w-24 bg-muted rounded animate-pulse"})]})]}),e.jsx("div",{className:"h-6 w-20 bg-muted rounded animate-pulse"})]})},t))}):m.length===0?e.jsx(p,{className:"p-8",children:e.jsxs("div",{className:"flex flex-col items-center justify-center text-center space-y-3",children:[e.jsx(oe,{className:"h-12 w-12 text-muted-foreground"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-lg mb-2",children:"No active sessions"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Get started by launching an"," ",e.jsx("button",{onClick:()=>N(!0),className:"text-primary hover:underline font-medium",children:"Interactive Session"})," ","or working on a"," ",e.jsx("button",{onClick:()=>c("/proposals"),className:"text-primary hover:underline font-medium",children:"Change Proposal"})]})]})]})}):e.jsx("div",{className:"space-y-2",children:m.slice(0,10).map(s=>e.jsxs(p,{className:"p-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(me,{className:"h-4 w-4 shrink-0"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium text-sm",children:s.proposalId}),e.jsxs("div",{className:"text-xs text-gray-500",children:["Session ",s.id.split("-").slice(-1)[0].substring(0,8)," • Last activity ",te(s.lastActivity)]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("div",{className:`flex items-center gap-1 ${s.connected?"text-green-600":"text-gray-400"}`,title:s.connected?"Connected":"Disconnected",children:e.jsx("div",{className:`w-2 h-2 rounded-full ${s.connected?"bg-green-500":"bg-gray-400"}`})}),e.jsx(r,{size:"sm",variant:"outline",onClick:()=>{A(t=>({...t,[s.id]:!t[s.id]}))},"aria-label":g[s.id]?"Hide preview":"Show preview",title:g[s.id]?"Hide preview":"Show preview",children:g[s.id]?e.jsx(xe,{className:"h-4 w-4"}):e.jsx(M,{className:"h-4 w-4"})}),e.jsx(r,{size:"sm",variant:"outline",onClick:()=>c(`/terminal/${s.proposalId}`),children:"Open"}),e.jsx(r,{size:"icon",variant:"destructive",onClick:()=>ne(s.id),title:"Close session","aria-label":"Close session",children:e.jsx(he,{className:"h-4 w-4"})})]})]}),g[s.id]&&e.jsx("div",{className:"mt-2 w-full p-2 cursor-pointer hover:opacity-80 transition-opacity",onClick:()=>c(`/terminal/${s.proposalId}`),title:"Click to open full terminal session",children:e.jsx(Pe,{sessionId:s.id,heightPx:160,maxScrollback:200})})]},s.id))})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Recent Proposals"}),J?e.jsx("div",{className:"space-y-3",children:[...Array(3)].map((s,t)=>e.jsx(p,{children:e.jsx(ke,{className:"py-3",children:e.jsxs("div",{className:"flex justify-between items-start",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"h-4 bg-muted rounded w-2/3 animate-pulse"}),e.jsx("div",{className:"h-3 bg-muted rounded w-1/3 animate-pulse"})]}),e.jsx("div",{className:"h-5 bg-muted rounded w-16 animate-pulse"})]})})},t))}):z.length===0?e.jsx(p,{children:e.jsx(_,{className:"flex items-center justify-center py-6",children:e.jsx("div",{className:"text-center text-sm text-gray-500",children:"No draft or approved proposals found"})})}):e.jsx("div",{className:"space-y-2",children:z.map(s=>e.jsx(p,{className:"hover:shadow-md transition-all cursor-pointer hover:border-primary/50",onClick:()=>c(`/terminal/${s.id}`),children:e.jsx(_,{className:"py-4",children:e.jsx("div",{className:"flex justify-between items-start gap-4",children:e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx(De,{className:"text-base leading-tight",children:s.intent}),e.jsxs("div",{className:"flex gap-1 ml-3 flex-shrink-0",children:[s.priority&&e.jsx(U,{variant:s.priority==="high"||s.priority==="critical"?"destructive":s.priority==="medium"?"secondary":"outline",className:"text-xs",children:s.priority}),e.jsx(U,{variant:"default",className:"text-xs",children:s.status})]})]}),s.content&&e.jsxs("div",{className:"text-sm text-muted-foreground leading-relaxed",children:[s.content.split(`
|
|
2
2
|
`).slice(0,2).join(" ").substring(0,150),s.content.length>150?"...":""]}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("div",{className:"text-xs text-muted-foreground",children:[s.id," • by ",s.author.name," • ",new Date(s.metadata.createdAt).toLocaleDateString()]}),e.jsxs("div",{className:"flex gap-2",onClick:t=>t.stopPropagation(),children:[e.jsxs(r,{variant:"ghost",size:"sm",onClick:()=>c(`/proposals/${s.id}`),className:"h-7 px-2 text-xs",children:[e.jsx(ue,{className:"h-3 w-3 mr-1"})," View"]}),e.jsxs(r,{variant:"ghost",size:"sm",onClick:()=>c(`/proposals/${s.id}/edit`),className:"h-7 px-2 text-xs",children:[e.jsx(fe,{className:"h-3 w-3 mr-1"})," Edit"]})]})]})]})})})},s.id))})]}),e.jsx(ge,{open:k,onOpenChange:N,children:e.jsxs(je,{className:"max-w-lg",children:[e.jsxs(pe,{children:[e.jsx(ve,{children:"Start Coding Agent"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:"Start an interactive coding session"})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-2 block",children:"Coding Agent"}),e.jsxs(Ne,{value:j,onValueChange:s=>K(s),children:[e.jsx(ye,{className:"w-full",children:e.jsx(we,{placeholder:"Select coding agent"})}),e.jsxs(Ce,{children:[e.jsx(S,{value:"claude",children:"Claude Code"}),e.jsx(S,{value:"gemini",children:"Google Gemini"}),e.jsx(S,{value:"codex",children:"OpenAI Codex"}),e.jsx(S,{value:"droid",children:"Factory Droid"})]})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("div",{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(Se,{className:"h-4 w-4"}),"Custom Agents"]}),e.jsxs("div",{className:"text-xs text-gray-500",children:[o.length," of ",u.length," selected"]})]}),e.jsxs(R,{children:[e.jsx(B,{asChild:!0,children:e.jsxs(r,{variant:"outline",className:"w-full justify-between",children:[o.length===0?"Select agents...":o.length===u.length?"All agents selected":`${o.length} agent${o.length!==1?"s":""} selected`,e.jsx(M,{className:"h-4 w-4 opacity-50"})]})}),e.jsxs(H,{className:"w-full min-w-[--radix-dropdown-menu-trigger-width]",children:[e.jsxs(L,{className:"flex items-center justify-between",children:[e.jsx("span",{children:"Available Agents"}),e.jsxs("div",{className:"flex gap-1",children:[e.jsx(r,{size:"sm",variant:"ghost",className:"h-5 px-1 text-xs",onClick:s=>{s.preventDefault(),C(u.map(t=>t.id))},children:"All"}),e.jsx(r,{size:"sm",variant:"ghost",className:"h-5 px-1 text-xs",onClick:s=>{s.preventDefault(),C([])},children:"None"})]})]}),e.jsx(O,{}),u.length===0?e.jsx("div",{className:"px-2 py-1.5 text-sm text-gray-500",children:"No agents found"}):u.map(s=>e.jsx(G,{checked:o.includes(s.id),onCheckedChange:t=>{C(a=>t?a.includes(s.id)?a:[...a,s.id]:a.filter(n=>n!==s.id))},children:e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{children:s.name}),s.tools.length>0&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:["MCP servers: ",s.tools.join(", ")]}),s.tools.length===0&&e.jsx("span",{className:"text-xs text-muted-foreground",children:"Inherits available MCP servers"})]})},s.id))]})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("div",{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(be,{className:"h-4 w-4"}),"MCP Servers"]}),e.jsxs("div",{className:"text-xs text-gray-500",children:[f.length," of ",h.length," selected"]})]}),e.jsxs(R,{children:[e.jsx(B,{asChild:!0,children:e.jsxs(r,{variant:"outline",className:"w-full justify-between",children:[f.length===0?"Select MCP servers...":f.length===h.length?"All servers selected":`${f.length} server${f.length!==1?"s":""} selected`,e.jsx(M,{className:"h-4 w-4 opacity-50"})]})}),e.jsxs(H,{className:"w-full min-w-[--radix-dropdown-menu-trigger-width]",children:[e.jsxs(L,{className:"flex items-center justify-between",children:[e.jsx("span",{children:"Available Servers"}),e.jsxs("div",{className:"flex gap-1",children:[e.jsx(r,{size:"sm",variant:"ghost",className:"h-5 px-1 text-xs",onClick:s=>{s.preventDefault(),y(h)},children:"All"}),e.jsx(r,{size:"sm",variant:"ghost",className:"h-5 px-1 text-xs",onClick:s=>{s.preventDefault(),y([])},children:"None"})]})]}),e.jsx(O,{}),h.length===0?e.jsx("div",{className:"px-2 py-1.5 text-sm text-gray-500",children:"No MCP servers found"}):h.map(s=>e.jsx(G,{checked:f.includes(s),onCheckedChange:t=>{y(a=>t?a.includes(s)?a:[...a,s]:a.filter(n=>n!==s))},children:s},s))]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-2 block",children:"Additional Instructions (optional)"}),e.jsx(Ae,{value:T,onChange:s=>Q(s.target.value),placeholder:"Add any custom instructions for the coding agent...",rows:4,className:"resize-none"})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-2",children:[e.jsx(r,{variant:"outline",onClick:()=>N(!1),disabled:D,children:"Cancel"}),e.jsx(r,{onClick:le,disabled:D,children:D?"Starting...":"Start Session"})]})]})]})})]})}export{Xe as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as x,j as e,f as a,s as m}from"./index-
|
|
1
|
+
import{r as x,j as e,f as a,s as m}from"./index-B0JO3x3V.js";function u({title:r,description:t,icon:n,defaultOpen:o=!1,children:i,className:l}){const[s,d]=x.useState(o);return e.jsxs("div",{className:a("rounded-lg border bg-card text-card-foreground",l),children:[e.jsxs("button",{type:"button",onClick:()=>d(c=>!c),className:"flex w-full items-center justify-between gap-4 px-4 py-3 text-left","aria-expanded":s,children:[e.jsxs("div",{className:"flex items-center gap-3",children:[n,e.jsxs("div",{children:[e.jsx("p",{className:"font-medium leading-tight",children:r}),t&&e.jsx("p",{className:"text-sm text-muted-foreground leading-snug",children:t})]})]}),e.jsx(m,{className:a("h-4 w-4 shrink-0 transition-transform duration-200",s?"rotate-180":"rotate-0")})]}),s&&e.jsx("div",{className:"border-t px-4 py-4",children:i})]})}export{u as C};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as W,j as e,r as m,D as q,a as B,F as N,b as S,d as A,e as P,f as I,S as z,B as r,C as D,L as n,g as L,h as F,i as M,k as T,A as E}from"./index-
|
|
1
|
+
import{c as W,j as e,r as m,D as q,a as B,F as N,b as S,d as A,e as P,f as I,S as z,B as r,C as D,L as n,g as L,h as F,i as M,k as T,A as E}from"./index-B0JO3x3V.js";import{C as c,a as l,b as f,c as j,d as R}from"./card-B9ym6neB.js";import{B as Y}from"./badge-DaM4gF82.js";import{F as _}from"./folder-git-2-B_ezHf_E.js";import{C as H}from"./calendar-CV2haPQ9.js";import{C as G}from"./circle-check-4zzXsmHH.js";import{C as $}from"./chevron-left-D8aMFTU2.js";import{C as O}from"./clock-B-uSJOTR.js";import{C as V}from"./circle-check-big-AlE11jqb.js";import{P as U}from"./plus-D737EJ5S.js";/**
|
|
2
2
|
* @license lucide-react v0.542.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as le,A as l,
|
|
1
|
+
import{c as le,A as l,bf as ws,r as n,H as vs,ag as ys,j as e,L as ee,ad as Fe,B as o,G as D,ac as Ns,X as Cs,I as k,q as Me,s as Be,T as Oe,D as se,a as te,b as ae,d as re,e as ne,b6 as ks,$ as Re}from"./index-B0JO3x3V.js";import{C as ie}from"./card-B9ym6neB.js";import{L as Ge}from"./label-BHOOQ99D.js";import{T as Ss,a as Ts,b as We,c as ze}from"./tabs-BnsC3AY5.js";import{C as Ps}from"./circle-check-4zzXsmHH.js";import{C as As}from"./circle-x-D58MbKgZ.js";import{A as Ds}from"./arrow-down-DGeJDsho.js";import{A as $s}from"./arrow-up-C5ecpR5U.js";import{R as Ue}from"./refresh-cw-uBnPtZwp.js";import{C as ce}from"./circle-alert-C-piOZLm.js";import{F as oe}from"./folder-git-2-B_ezHf_E.js";/**
|
|
2
2
|
* @license lucide-react v0.542.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{c as
|
|
1
|
+
import{c as Te,r,H as He,A as u,j as e,a1 as he,aA as xe,B as o,T as Fe,n as De,b6 as ze,I as U,D as W,a as B,b as q,d as J,e as K,$ as Y}from"./index-B0JO3x3V.js";import{C as pe,b as ge,c as fe,d as be,a as je}from"./card-B9ym6neB.js";import{L as f}from"./label-BHOOQ99D.js";import{R as Me,a as ve}from"./radio-group-nRRUTZ_w.js";import{R as A}from"./refresh-cw-uBnPtZwp.js";import{C as Oe}from"./circle-check-4zzXsmHH.js";import{C as Ie}from"./circle-x-D58MbKgZ.js";/**
|
|
2
2
|
* @license lucide-react v0.542.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const $e=[["path",{d:"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4",key:"tonef"}],["path",{d:"M9 18c-4.51 2-5-2-7-2",key:"9comsn"}]],we=Ae("github",$e),V="../worktrees",y="../worktrees",b="coconut/github-auth-state";function _e(h){const j=h.trim();return j?/^([A-Za-z]:\\|\\\\|\/|~)/.test(j):!1}function Xe(){const[h,j]=r.useState(null),[X,v]=r.useState(y),[c,A]=r.useState("github"),[Z,Q]=r.useState(!0),[H,ee]=r.useState(!1),[a,te]=r.useState(null),[w,se]=r.useState(!1),[x,ye]=r.useState(null),[Ne,N]=r.useState(!1),[C,F]=r.useState(""),[k,D]=r.useState(""),[re,ae]=r.useState(!1),[p,S]=r.useState(!1),[ie,oe]=r.useState(!1),[Ce,R]=r.useState(!1),[E,G]=r.useState(""),[ne,ce]=r.useState(!1),[z,le]=r.useState(!1),[ke,P]=r.useState(!1),m=r.useRef(null),{toast:i}=He(),M=r.useCallback(async()=>{Q(!0);try{const s=await(await fetch(`${u}/api/v1/git/settings`)).json();if(s.success){const n=s.data||{},d={defaultWorktreePath:n.defaultWorktreePath||y,authMode:n.authMode||"github"};j(d),v(d.defaultWorktreePath),A(d.authMode)}else throw new Error(s.error?.message||"Failed to load settings")}catch(t){console.error("Failed to load git settings",t),i({title:"Error",description:"Failed to load git settings",variant:"destructive"})}finally{Q(!1)}},[i]),l=r.useCallback(async()=>{se(!0);try{const[t,s]=await Promise.all([fetch(`${u}/api/v1/git/auth-status`).then(n=>n.json()),fetch(`${u}/api/v1/git/credential-config`).then(n=>n.json())]);if(t.success)te(t.data);else throw new Error(t.error?.message||"Failed to check auth status");s.success&&ye(s.data)}catch(t){console.error("Failed to check git auth status",t),te({authenticated:!1,error:"Failed to check status"})}finally{se(!1)}},[i]),O=c==="github",Se=O&&a?.provider==="github",L=!!(O&&a?.authenticated&&a?.provider==="github"),I=!!(O&&a?.provider==="github"&&!a?.authenticated),de=r.useMemo(()=>{if(!a?.expiresAt)return null;const t=new Date(a.expiresAt);return Number.isNaN(t.getTime())?null:t.toLocaleString()},[a?.expiresAt]);r.useEffect(()=>{if(typeof window>"u")return;const t=s=>{s.origin===window.location.origin&&s.data?.type==="github-auth"&&(m.current&&!m.current.closed&&m.current.close(),m.current=null,localStorage.removeItem(b),S(!1),s.data?.success?(i({title:"GitHub connected",description:"GitHub authorization completed successfully."}),l()):i({title:"GitHub authorization failed",description:s.data?.message||"Authorization was cancelled or failed.",variant:"destructive"}))};return window.addEventListener("message",t),()=>window.removeEventListener("message",t)},[l,i]),r.useEffect(()=>{if(typeof window>"u"||!p)return;const t=window.setInterval(()=>{m.current&&m.current.closed&&(window.clearInterval(t),m.current=null,S(!1),localStorage.removeItem(b))},500);return()=>window.clearInterval(t)},[p]);const Re=r.useCallback(async()=>{if(!p&&!(typeof window>"u")){S(!0);try{const t=`${window.location.origin}/auth/github/callback`,s=await fetch(`${u}/api/v1/git/providers/github/authorize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({callbackUrl:t})}),n=await s.json();if(!s.ok||!n.success)throw new Error(n?.error?.message||"Failed to start GitHub authorization");const d=n?.data?.authorizeUrl,me=n?.data?.state;if(!d||!me)throw new Error("Invalid response from authorization endpoint");localStorage.removeItem(b),localStorage.setItem(b,me);const _=window.open(d,"github-authorization","width=600,height=700");if(!_)throw localStorage.removeItem(b),new Error("Popup blocked. Please allow popups and try again.");m.current=_,_.focus()}catch(t){S(!1),localStorage.removeItem(b),i({title:"GitHub authorization failed",description:t?.message||"Unable to open GitHub authorization flow.",variant:"destructive"})}}},[p,i]),Ee=r.useCallback(async()=>{oe(!0);try{const t=await fetch(`${u}/api/v1/git/providers/github/token`,{method:"DELETE"}),s=await t.json();if(!t.ok||!s.success)throw new Error(s?.error?.message||"Failed to disconnect GitHub");i({title:"GitHub disconnected",description:"Stored GitHub credentials were removed."}),await l()}catch(t){i({title:"Failed to disconnect GitHub",description:t?.message||"Please try again.",variant:"destructive"})}finally{oe(!1)}},[l,i]);r.useEffect(()=>{M(),l()},[M,l]);const Ge=async()=>{if(!E.trim()){i({title:"Error",description:"Remote URL is required",variant:"destructive"});return}ce(!0);try{const s=await(await fetch(`${u}/api/v1/git/remote`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({remoteUrl:E.trim()})})).json();if(!s.success)throw new Error(s.error?.message||"Failed to set remote URL");i({title:"Success",description:"Remote URL set successfully"}),R(!1),G(""),await l()}catch(t){console.error("Failed to set remote URL",t),i({title:"Error",description:t?.message||"Failed to set remote URL",variant:"destructive"})}finally{ce(!1)}},Pe=async()=>{le(!0);try{const s=await(await fetch(`${u}/api/v1/git/remote`,{method:"DELETE"})).json();if(!s.success)throw new Error(s.error?.message||"Failed to delete remote");i({title:"Success",description:"Remote URL removed"}),await l()}catch(t){console.error("Failed to delete remote",t),i({title:"Error",description:t?.message||"Failed to delete remote",variant:"destructive"})}finally{le(!1)}},Le=async()=>{if(!C||!k){i({title:"Error",description:"Username and password are required",variant:"destructive"});return}if(!a?.remote){i({title:"Error",description:"Set a remote URL first before saving credentials",variant:"destructive"});return}ae(!0);try{const s=await(await fetch(`${u}/api/v1/git/credentials`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:C,password:k})})).json();if(!s.success)throw new Error(s.error?.message||"Failed to save credentials");i({title:"Success",description:"Credentials saved successfully"}),N(!1),F(""),D(""),await l()}catch(t){console.error("Failed to save credentials",t),i({title:"Error",description:t?.message||"Failed to save credentials",variant:"destructive"})}finally{ae(!1)}},g=X.trim(),$=r.useMemo(()=>g?_e(g)?"Path must be relative to the project root":null:"Path is required",[g]),Ue=r.useMemo(()=>h?g!==h.defaultWorktreePath||(h.authMode||"github")!==c:!1,[h,g,c]),ue=!Z&&!H&&Ue&&!$,Te=async()=>{if(ue){ee(!0);try{const s=await(await fetch(`${u}/api/v1/git/settings`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({defaultWorktreePath:g,authMode:c})})).json();if(!s.success)throw new Error(s.error?.message||"Failed to update settings");const n=s.data||{},d={defaultWorktreePath:n.defaultWorktreePath||y,authMode:n.authMode||"github"};j(d),v(d.defaultWorktreePath),A(d.authMode),i({title:"Updated",description:"Git settings saved"})}catch(t){console.error("Failed to update git settings",t),i({title:"Error",description:t?.message||"Failed to update git settings",variant:"destructive"})}finally{ee(!1)}}};return Z&&!h?e.jsx("div",{children:"Loading..."}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Git Settings"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Control how Coconut creates worktrees for change proposals and manual Git operations."})]}),e.jsx(he,{}),e.jsxs(pe,{children:[e.jsxs(ge,{children:[e.jsx(fe,{children:"Remote Authentication"}),e.jsx(be,{children:"Configure authentication for remote git operations."})]}),e.jsxs(je,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{className:"text-sm font-medium",children:"Remote URL"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"The git remote URL for your repository (origin)."}),e.jsxs("div",{className:"flex items-center justify-between gap-3 rounded border bg-muted/30 px-3 py-2",children:[w&&!a?e.jsxs("span",{className:"text-sm text-muted-foreground italic flex items-center gap-2",children:[e.jsx(T,{className:"h-3.5 w-3.5 animate-spin"}),"Loading..."]}):a?.remote?e.jsxs("a",{href:a.remote.replace(/\.git$/,"").replace(/^git@([^:]+):/,"https://$1/"),target:"_blank",rel:"noopener noreferrer",className:"text-sm text-primary hover:underline truncate inline-flex items-center gap-1.5",children:[a.remote,e.jsx(xe,{className:"h-3.5 w-3.5 shrink-0"})]}):e.jsx("span",{className:"text-sm text-muted-foreground italic",children:"Not configured"}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[a?.remote&&e.jsx(o,{variant:"ghost",size:"icon",className:"h-8 w-8 text-muted-foreground hover:text-destructive",onClick:()=>P(!0),disabled:z,title:"Remove remote",children:e.jsx(Fe,{className:"h-4 w-4"})}),e.jsx(o,{variant:"outline",size:"sm",onClick:()=>{G(a?.remote||""),R(!0)},children:a?.remote?"Edit":"Set Remote"})]})]})]}),e.jsx(he,{}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{className:"text-sm font-medium",children:"Authentication Mode"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Choose how Coconut authenticates with your remote repository when pushing or pulling."}),e.jsxs(Me,{value:c,onValueChange:t=>A(t||"github"),className:"grid gap-2 md:grid-cols-2",children:[e.jsx("label",{htmlFor:"mode-github",className:`cursor-pointer rounded-md border p-3 transition-colors ${c==="github"?"border-primary ring-1 ring-primary/40 bg-primary/5":"border-border bg-background hover:border-primary/60"}`,children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(ve,{value:"github",id:"mode-github",className:"mt-1 h-5 w-5 shrink-0 border-[1.5px]"}),e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsx("span",{className:"text-sm font-medium",children:"GitHub"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Use the Coconut control plane to fetch short-lived GitHub tokens automatically."})]})]})}),e.jsx("label",{htmlFor:"mode-local",className:`cursor-pointer rounded-md border p-3 transition-colors ${c==="local"?"border-primary ring-1 ring-primary/40 bg-primary/5":"border-border bg-background hover:border-primary/60"}`,children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(ve,{value:"local",id:"mode-local",className:"mt-1 h-5 w-5 shrink-0 border-[1.5px]"}),e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsx("span",{className:"text-sm font-medium",children:"Local configuration"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Manage credentials yourself using SSH keys, stored PATs, or OS credential helpers on this Coconut."})]})]})})]})]}),c==="github"&&!a&&e.jsxs("div",{className:"flex items-center justify-center gap-2 py-4 text-sm text-muted-foreground",children:[e.jsx(T,{className:"h-4 w-4 animate-spin"}),"Loading authentication status..."]}),c==="github"&&a&&!a.remote&&e.jsxs("div",{className:"rounded border border-amber-200 bg-amber-50 p-3 text-sm text-amber-700 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-200",children:[e.jsx("span",{className:"font-medium",children:"Remote URL required:"})," Set a remote URL above to enable GitHub authentication."]}),c==="github"&&a?.remote&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-3 rounded border p-3",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[w?e.jsx(T,{className:"h-5 w-5 mt-1 animate-spin text-muted-foreground"}):a?.authenticated?e.jsx(Oe,{className:"h-5 w-5 mt-1 text-green-600"}):e.jsx(Ie,{className:"h-5 w-5 mt-1 text-red-600"}),e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsx("div",{className:"font-medium",children:w?"Checking...":L?"Connected to GitHub":I?"GitHub authorization required":a?.authenticated?"Authenticated":"Not authenticated"}),Se&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(we,{className:"h-3.5 w-3.5"}),e.jsx("span",{children:L?"GitHub App credentials active":"Authorize with GitHub to continue"})]}),L&&de&&e.jsxs("span",{className:"rounded bg-muted px-2 py-0.5 text-[11px] text-muted-foreground",children:["Expires ",de]})]}),a?.error&&e.jsx("div",{className:"text-xs text-red-600",children:a.error})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 justify-end",children:[e.jsxs(o,{variant:"outline",size:"sm",onClick:l,disabled:w,children:[e.jsx(T,{className:"h-4 w-4 mr-2"+(w?" animate-spin":"")}),"Check Status"]}),L?e.jsx(o,{variant:"ghost",size:"sm",onClick:Ee,disabled:ie,children:ie?"Disconnecting…":"Disconnect GitHub"}):e.jsxs(o,{size:"sm",onClick:Re,disabled:p,children:[p?e.jsx(De,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(we,{className:"h-4 w-4 mr-2"}),p?"Authorizing…":I?"Reconnect GitHub":"Connect GitHub"]})]}),e.jsx("div",{className:"text-right",children:e.jsxs("a",{href:"https://app.coconut.dev/git",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-xs text-primary hover:underline",children:["Manage Github authentication",e.jsx(xe,{className:"h-3 w-3"})]})})]}),I&&e.jsx("div",{className:"rounded border border-amber-200 bg-amber-50 p-3 text-xs text-amber-700 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-200",children:"GitHub authorization has expired. Click “Reconnect GitHub” to refresh access."}),x&&(x.helper||x.origin)&&e.jsxs("div",{className:"rounded border bg-muted/50 p-3",children:[e.jsx("div",{className:"text-xs font-medium mb-1",children:"Current Configuration"}),e.jsxs("div",{className:"text-xs text-muted-foreground space-y-1",children:[x.helper&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx("span",{className:"font-mono",children:"credential.helper:"}),e.jsx("span",{className:"font-mono text-foreground",children:x.helper})]}),x.origin&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx("span",{className:"font-mono",children:"Configured in:"}),e.jsx("span",{className:"font-mono text-foreground",children:x.origin})]})]})]})]}),c==="local"&&e.jsxs("div",{className:"rounded bg-muted p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-sm font-medium",children:"Setup Git Credentials"}),e.jsxs(o,{variant:"outline",size:"sm",onClick:()=>N(!0),children:[e.jsx(ze,{className:"h-4 w-4 mr-2"}),"Enter Credentials"]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground space-y-2",children:[e.jsx("p",{children:"Configure credentials directly on this Coconut. Coconut will use your existing SSH keys or credential helpers without contacting the control plane."}),e.jsxs("div",{className:"space-y-2 ml-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Option 1: SSH Keys (Recommended)"}),e.jsxs("code",{className:"text-[11px] block mt-1 bg-background rounded px-2 py-1",children:['ssh-keygen -t ed25519 -C "your_email@example.com"',e.jsx("br",{}),"# Add ~/.ssh/id_ed25519.pub to your Git provider account"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Option 2: Git Credential Manager"}),e.jsxs("code",{className:"text-[11px] block mt-1 bg-background rounded px-2 py-1",children:["# macOS (already configured with osxkeychain)",e.jsx("br",{}),"git credential-osxkeychain",e.jsx("br",{}),e.jsx("br",{}),"# Or install Git Credential Manager",e.jsx("br",{}),"brew install git-credential-manager"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Option 3: Personal Access Token"}),e.jsxs("code",{className:"text-[11px] block mt-1 bg-background rounded px-2 py-1",children:["# Store credentials after first push/pull",e.jsx("br",{}),"git config credential.helper store"]})]})]}),e.jsx("p",{className:"mt-3",children:'After configuring, click "Check Status" to verify authentication.'})]})]})]})]}),e.jsxs(pe,{children:[e.jsxs(ge,{children:[e.jsx(fe,{children:"Worktree Location"}),e.jsx(be,{children:"Choose where new worktrees should be created relative to your project root."})]}),e.jsxs(je,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"default-worktree-path",children:"Default worktree path"}),e.jsx(U,{id:"default-worktree-path",value:X,onChange:t=>v(t.target.value),placeholder:"../worktrees",spellCheck:!1}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Paths are resolved from your project root. We recommend keeping worktrees outside the repository, for example ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-[11px] font-mono",children:V}),"."]}),$&&e.jsx("p",{className:"text-xs text-red-600",children:$})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(o,{type:"button",variant:"outline",size:"sm",onClick:()=>v(V),children:["Use ",V]}),e.jsxs(o,{type:"button",variant:"ghost",size:"sm",onClick:()=>v(y),children:["Reset to ",y]})]})]})]}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(o,{type:"button",variant:"outline",disabled:H,onClick:M,children:"Reload"}),e.jsx(o,{type:"button",disabled:!ue,onClick:Te,children:H?"Saving...":"Save changes"})]}),e.jsx(W,{open:Ne,onOpenChange:N,children:e.jsxs(q,{children:[e.jsxs(B,{children:[e.jsx(J,{children:"Enter Git Credentials"}),e.jsx(K,{children:"Enter your username and personal access token for HTTPS authentication. Your credentials will be securely stored using your system's credential manager."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[!a?.remote&&e.jsx("div",{className:"rounded border border-amber-200 bg-amber-50 p-3 text-xs text-amber-700 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-200",children:"No remote URL configured. Set a remote URL first before entering credentials."}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"git-username",children:"Username"}),e.jsx(U,{id:"git-username",placeholder:"your-username",value:C,onChange:t=>F(t.target.value),autoComplete:"username"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"git-password",children:"Password / Personal Access Token"}),e.jsx(U,{id:"git-password",type:"password",placeholder:"ghp_xxxxxxxxxxxx or your password",value:k,onChange:t=>D(t.target.value),autoComplete:"current-password"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["We recommend using a Personal Access Token instead of your password.",e.jsx("br",{}),"GitHub: Settings → Developer settings → Personal access tokens",e.jsx("br",{}),"GitLab: Preferences → Access Tokens"]})]})]}),e.jsxs(Y,{children:[e.jsx(o,{variant:"outline",onClick:()=>{N(!1),F(""),D("")},children:"Cancel"}),e.jsx(o,{onClick:Le,disabled:re||!C||!k||!a?.remote,children:re?"Saving...":"Save Credentials"})]})]})}),e.jsx(W,{open:ke,onOpenChange:P,children:e.jsxs(q,{children:[e.jsxs(B,{children:[e.jsx(J,{children:"Remove Remote?"}),e.jsx(K,{children:"This will remove the origin remote from your local git configuration. The remote repository itself won't be affected."})]}),e.jsxs(Y,{children:[e.jsx(o,{variant:"outline",onClick:()=>P(!1),children:"Cancel"}),e.jsx(o,{variant:"destructive",onClick:async()=>{P(!1),await Pe()},disabled:z,children:z?"Removing...":"Remove Remote"})]})]})}),e.jsx(W,{open:Ce,onOpenChange:R,children:e.jsxs(q,{children:[e.jsxs(B,{children:[e.jsx(J,{children:a?.remote?"Edit Remote URL":"Set Remote URL"}),e.jsx(K,{children:"Configure the git remote URL for your repository. This is the origin remote used for push and pull operations."})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"remote-url",children:"Remote URL"}),e.jsx(U,{id:"remote-url",placeholder:"https://github.com/username/repo.git",value:E,onChange:t=>G(t.target.value),autoComplete:"off"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter your repository URL (HTTPS or SSH format)."})]})}),e.jsxs(Y,{children:[e.jsx(o,{variant:"outline",onClick:()=>{R(!1),G("")},children:"Cancel"}),e.jsx(o,{onClick:Ge,disabled:ne||!E.trim(),children:ne?"Saving...":"Save"})]})]})})]})}export{Xe as default};
|
|
6
|
+
*/const $e=[["path",{d:"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4",key:"tonef"}],["path",{d:"M9 18c-4.51 2-5-2-7-2",key:"9comsn"}]],we=Te("github",$e),V="../worktrees",y="../worktrees",b="coconut/github-auth-state";function _e(h){const j=h.trim();return j?/^([A-Za-z]:\\|\\\\|\/|~)/.test(j):!1}function Xe(){const[h,j]=r.useState(null),[X,v]=r.useState(y),[c,T]=r.useState("github"),[Z,Q]=r.useState(!0),[H,ee]=r.useState(!1),[a,te]=r.useState(null),[w,se]=r.useState(!1),[x,ye]=r.useState(null),[Ne,N]=r.useState(!1),[C,F]=r.useState(""),[k,D]=r.useState(""),[re,ae]=r.useState(!1),[p,S]=r.useState(!1),[ie,oe]=r.useState(!1),[Ce,R]=r.useState(!1),[E,G]=r.useState(""),[ne,ce]=r.useState(!1),[z,le]=r.useState(!1),[ke,P]=r.useState(!1),m=r.useRef(null),{toast:i}=He(),M=r.useCallback(async()=>{Q(!0);try{const s=await(await fetch(`${u}/api/v1/git/settings`)).json();if(s.success){const n=s.data||{},d={defaultWorktreePath:n.defaultWorktreePath||y,authMode:n.authMode||"github"};j(d),v(d.defaultWorktreePath),T(d.authMode)}else throw new Error(s.error?.message||"Failed to load settings")}catch(t){console.error("Failed to load git settings",t),i({title:"Error",description:"Failed to load git settings",variant:"destructive"})}finally{Q(!1)}},[i]),l=r.useCallback(async()=>{se(!0);try{const[t,s]=await Promise.all([fetch(`${u}/api/v1/git/auth-status`).then(n=>n.json()),fetch(`${u}/api/v1/git/credential-config`).then(n=>n.json())]);if(t.success)te(t.data);else throw new Error(t.error?.message||"Failed to check auth status");s.success&&ye(s.data)}catch(t){console.error("Failed to check git auth status",t),te({authenticated:!1,error:"Failed to check status"})}finally{se(!1)}},[i]),O=c==="github",Se=O&&a?.provider==="github",L=!!(O&&a?.authenticated&&a?.provider==="github"),I=!!(O&&a?.provider==="github"&&!a?.authenticated),de=r.useMemo(()=>{if(!a?.expiresAt)return null;const t=new Date(a.expiresAt);return Number.isNaN(t.getTime())?null:t.toLocaleString()},[a?.expiresAt]);r.useEffect(()=>{if(typeof window>"u")return;const t=s=>{s.origin===window.location.origin&&s.data?.type==="github-auth"&&(m.current&&!m.current.closed&&m.current.close(),m.current=null,localStorage.removeItem(b),S(!1),s.data?.success?(i({title:"GitHub connected",description:"GitHub authorization completed successfully."}),l()):i({title:"GitHub authorization failed",description:s.data?.message||"Authorization was cancelled or failed.",variant:"destructive"}))};return window.addEventListener("message",t),()=>window.removeEventListener("message",t)},[l,i]),r.useEffect(()=>{if(typeof window>"u"||!p)return;const t=window.setInterval(()=>{m.current&&m.current.closed&&(window.clearInterval(t),m.current=null,S(!1),localStorage.removeItem(b))},500);return()=>window.clearInterval(t)},[p]);const Re=r.useCallback(async()=>{if(!p&&!(typeof window>"u")){S(!0);try{const t=`${window.location.origin}/auth/github/callback`,s=await fetch(`${u}/api/v1/git/providers/github/authorize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({callbackUrl:t})}),n=await s.json();if(!s.ok||!n.success)throw new Error(n?.error?.message||"Failed to start GitHub authorization");const d=n?.data?.authorizeUrl,me=n?.data?.state;if(!d||!me)throw new Error("Invalid response from authorization endpoint");localStorage.removeItem(b),localStorage.setItem(b,me);const _=window.open(d,"github-authorization","width=600,height=700");if(!_)throw localStorage.removeItem(b),new Error("Popup blocked. Please allow popups and try again.");m.current=_,_.focus()}catch(t){S(!1),localStorage.removeItem(b),i({title:"GitHub authorization failed",description:t?.message||"Unable to open GitHub authorization flow.",variant:"destructive"})}}},[p,i]),Ee=r.useCallback(async()=>{oe(!0);try{const t=await fetch(`${u}/api/v1/git/providers/github/token`,{method:"DELETE"}),s=await t.json();if(!t.ok||!s.success)throw new Error(s?.error?.message||"Failed to disconnect GitHub");i({title:"GitHub disconnected",description:"Stored GitHub credentials were removed."}),await l()}catch(t){i({title:"Failed to disconnect GitHub",description:t?.message||"Please try again.",variant:"destructive"})}finally{oe(!1)}},[l,i]);r.useEffect(()=>{M(),l()},[M,l]);const Ge=async()=>{if(!E.trim()){i({title:"Error",description:"Remote URL is required",variant:"destructive"});return}ce(!0);try{const s=await(await fetch(`${u}/api/v1/git/remote`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({remoteUrl:E.trim()})})).json();if(!s.success)throw new Error(s.error?.message||"Failed to set remote URL");i({title:"Success",description:"Remote URL set successfully"}),R(!1),G(""),await l()}catch(t){console.error("Failed to set remote URL",t),i({title:"Error",description:t?.message||"Failed to set remote URL",variant:"destructive"})}finally{ce(!1)}},Pe=async()=>{le(!0);try{const s=await(await fetch(`${u}/api/v1/git/remote`,{method:"DELETE"})).json();if(!s.success)throw new Error(s.error?.message||"Failed to delete remote");i({title:"Success",description:"Remote URL removed"}),await l()}catch(t){console.error("Failed to delete remote",t),i({title:"Error",description:t?.message||"Failed to delete remote",variant:"destructive"})}finally{le(!1)}},Le=async()=>{if(!C||!k){i({title:"Error",description:"Username and password are required",variant:"destructive"});return}if(!a?.remote){i({title:"Error",description:"Set a remote URL first before saving credentials",variant:"destructive"});return}ae(!0);try{const s=await(await fetch(`${u}/api/v1/git/credentials`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:C,password:k})})).json();if(!s.success)throw new Error(s.error?.message||"Failed to save credentials");i({title:"Success",description:"Credentials saved successfully"}),N(!1),F(""),D(""),await l()}catch(t){console.error("Failed to save credentials",t),i({title:"Error",description:t?.message||"Failed to save credentials",variant:"destructive"})}finally{ae(!1)}},g=X.trim(),$=r.useMemo(()=>g?_e(g)?"Path must be relative to the project root":null:"Path is required",[g]),Ue=r.useMemo(()=>h?g!==h.defaultWorktreePath||(h.authMode||"github")!==c:!1,[h,g,c]),ue=!Z&&!H&&Ue&&!$,Ae=async()=>{if(ue){ee(!0);try{const s=await(await fetch(`${u}/api/v1/git/settings`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({defaultWorktreePath:g,authMode:c})})).json();if(!s.success)throw new Error(s.error?.message||"Failed to update settings");const n=s.data||{},d={defaultWorktreePath:n.defaultWorktreePath||y,authMode:n.authMode||"github"};j(d),v(d.defaultWorktreePath),T(d.authMode),i({title:"Updated",description:"Git settings saved"})}catch(t){console.error("Failed to update git settings",t),i({title:"Error",description:t?.message||"Failed to update git settings",variant:"destructive"})}finally{ee(!1)}}};return Z&&!h?e.jsx("div",{children:"Loading..."}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Git Settings"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Control how Coconut creates worktrees for change proposals and manual Git operations."})]}),e.jsx(he,{}),e.jsxs(pe,{children:[e.jsxs(ge,{children:[e.jsx(fe,{children:"Remote Authentication"}),e.jsx(be,{children:"Configure authentication for remote git operations."})]}),e.jsxs(je,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{className:"text-sm font-medium",children:"Remote URL"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"The git remote URL for your repository (origin)."}),e.jsxs("div",{className:"flex items-center justify-between gap-3 rounded border bg-muted/30 px-3 py-2",children:[w&&!a?e.jsxs("span",{className:"text-sm text-muted-foreground italic flex items-center gap-2",children:[e.jsx(A,{className:"h-3.5 w-3.5 animate-spin"}),"Loading..."]}):a?.remote?e.jsxs("a",{href:a.remote.replace(/\.git$/,"").replace(/^git@([^:]+):/,"https://$1/"),target:"_blank",rel:"noopener noreferrer",className:"text-sm text-primary hover:underline truncate inline-flex items-center gap-1.5",children:[a.remote,e.jsx(xe,{className:"h-3.5 w-3.5 shrink-0"})]}):e.jsx("span",{className:"text-sm text-muted-foreground italic",children:"Not configured"}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[a?.remote&&e.jsx(o,{variant:"ghost",size:"icon",className:"h-8 w-8 text-muted-foreground hover:text-destructive",onClick:()=>P(!0),disabled:z,title:"Remove remote",children:e.jsx(Fe,{className:"h-4 w-4"})}),e.jsx(o,{variant:"outline",size:"sm",onClick:()=>{G(a?.remote||""),R(!0)},children:a?.remote?"Edit":"Set Remote"})]})]})]}),e.jsx(he,{}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{className:"text-sm font-medium",children:"Authentication Mode"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Choose how Coconut authenticates with your remote repository when pushing or pulling."}),e.jsxs(Me,{value:c,onValueChange:t=>T(t||"github"),className:"grid gap-2 md:grid-cols-2",children:[e.jsx("label",{htmlFor:"mode-github",className:`cursor-pointer rounded-md border p-3 transition-colors ${c==="github"?"border-primary ring-1 ring-primary/40 bg-primary/5":"border-border bg-background hover:border-primary/60"}`,children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(ve,{value:"github",id:"mode-github",className:"mt-1 h-5 w-5 shrink-0 border-[1.5px]"}),e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsx("span",{className:"text-sm font-medium",children:"GitHub"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Use the Coconut control plane to fetch short-lived GitHub tokens automatically."})]})]})}),e.jsx("label",{htmlFor:"mode-local",className:`cursor-pointer rounded-md border p-3 transition-colors ${c==="local"?"border-primary ring-1 ring-primary/40 bg-primary/5":"border-border bg-background hover:border-primary/60"}`,children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(ve,{value:"local",id:"mode-local",className:"mt-1 h-5 w-5 shrink-0 border-[1.5px]"}),e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsx("span",{className:"text-sm font-medium",children:"Local configuration"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Manage credentials yourself using SSH keys, stored PATs, or OS credential helpers on this Coconut."})]})]})})]})]}),c==="github"&&!a&&e.jsxs("div",{className:"flex items-center justify-center gap-2 py-4 text-sm text-muted-foreground",children:[e.jsx(A,{className:"h-4 w-4 animate-spin"}),"Loading authentication status..."]}),c==="github"&&a&&!a.remote&&e.jsxs("div",{className:"rounded border border-amber-200 bg-amber-50 p-3 text-sm text-amber-700 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-200",children:[e.jsx("span",{className:"font-medium",children:"Remote URL required:"})," Set a remote URL above to enable GitHub authentication."]}),c==="github"&&a?.remote&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-3 rounded border p-3",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[w?e.jsx(A,{className:"h-5 w-5 mt-1 animate-spin text-muted-foreground"}):a?.authenticated?e.jsx(Oe,{className:"h-5 w-5 mt-1 text-green-600"}):e.jsx(Ie,{className:"h-5 w-5 mt-1 text-red-600"}),e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsx("div",{className:"font-medium",children:w?"Checking...":L?"Connected to GitHub":I?"GitHub authorization required":a?.authenticated?"Authenticated":"Not authenticated"}),Se&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(we,{className:"h-3.5 w-3.5"}),e.jsx("span",{children:L?"GitHub App credentials active":"Authorize with GitHub to continue"})]}),L&&de&&e.jsxs("span",{className:"rounded bg-muted px-2 py-0.5 text-[11px] text-muted-foreground",children:["Expires ",de]})]}),a?.error&&e.jsx("div",{className:"text-xs text-red-600",children:a.error})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 justify-end",children:[e.jsxs(o,{variant:"outline",size:"sm",onClick:l,disabled:w,children:[e.jsx(A,{className:"h-4 w-4 mr-2"+(w?" animate-spin":"")}),"Check Status"]}),L?e.jsx(o,{variant:"ghost",size:"sm",onClick:Ee,disabled:ie,children:ie?"Disconnecting…":"Disconnect GitHub"}):e.jsxs(o,{size:"sm",onClick:Re,disabled:p,children:[p?e.jsx(De,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(we,{className:"h-4 w-4 mr-2"}),p?"Authorizing…":I?"Reconnect GitHub":"Connect GitHub"]})]}),e.jsx("div",{className:"text-right",children:e.jsxs("a",{href:"https://app.coconut.dev/git",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-xs text-primary hover:underline",children:["Manage Github authentication",e.jsx(xe,{className:"h-3 w-3"})]})})]}),I&&e.jsx("div",{className:"rounded border border-amber-200 bg-amber-50 p-3 text-xs text-amber-700 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-200",children:"GitHub authorization has expired. Click “Reconnect GitHub” to refresh access."}),x&&(x.helper||x.origin)&&e.jsxs("div",{className:"rounded border bg-muted/50 p-3",children:[e.jsx("div",{className:"text-xs font-medium mb-1",children:"Current Configuration"}),e.jsxs("div",{className:"text-xs text-muted-foreground space-y-1",children:[x.helper&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx("span",{className:"font-mono",children:"credential.helper:"}),e.jsx("span",{className:"font-mono text-foreground",children:x.helper})]}),x.origin&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx("span",{className:"font-mono",children:"Configured in:"}),e.jsx("span",{className:"font-mono text-foreground",children:x.origin})]})]})]})]}),c==="local"&&e.jsxs("div",{className:"rounded bg-muted p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-sm font-medium",children:"Setup Git Credentials"}),e.jsxs(o,{variant:"outline",size:"sm",onClick:()=>N(!0),children:[e.jsx(ze,{className:"h-4 w-4 mr-2"}),"Enter Credentials"]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground space-y-2",children:[e.jsx("p",{children:"Configure credentials directly on this Coconut. Coconut will use your existing SSH keys or credential helpers without contacting the control plane."}),e.jsxs("div",{className:"space-y-2 ml-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Option 1: SSH Keys (Recommended)"}),e.jsxs("code",{className:"text-[11px] block mt-1 bg-background rounded px-2 py-1",children:['ssh-keygen -t ed25519 -C "your_email@example.com"',e.jsx("br",{}),"# Add ~/.ssh/id_ed25519.pub to your Git provider account"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Option 2: Git Credential Manager"}),e.jsxs("code",{className:"text-[11px] block mt-1 bg-background rounded px-2 py-1",children:["# macOS (already configured with osxkeychain)",e.jsx("br",{}),"git credential-osxkeychain",e.jsx("br",{}),e.jsx("br",{}),"# Or install Git Credential Manager",e.jsx("br",{}),"brew install git-credential-manager"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Option 3: Personal Access Token"}),e.jsxs("code",{className:"text-[11px] block mt-1 bg-background rounded px-2 py-1",children:["# Store credentials after first push/pull",e.jsx("br",{}),"git config credential.helper store"]})]})]}),e.jsx("p",{className:"mt-3",children:'After configuring, click "Check Status" to verify authentication.'})]})]})]})]}),e.jsxs(pe,{children:[e.jsxs(ge,{children:[e.jsx(fe,{children:"Worktree Location"}),e.jsx(be,{children:"Choose where new worktrees should be created relative to your project root."})]}),e.jsxs(je,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"default-worktree-path",children:"Default worktree path"}),e.jsx(U,{id:"default-worktree-path",value:X,onChange:t=>v(t.target.value),placeholder:"../worktrees",spellCheck:!1}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Paths are resolved from your project root. We recommend keeping worktrees outside the repository, for example ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-[11px] font-mono",children:V}),"."]}),$&&e.jsx("p",{className:"text-xs text-red-600",children:$})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(o,{type:"button",variant:"outline",size:"sm",onClick:()=>v(V),children:["Use ",V]}),e.jsxs(o,{type:"button",variant:"ghost",size:"sm",onClick:()=>v(y),children:["Reset to ",y]})]})]})]}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(o,{type:"button",variant:"outline",disabled:H,onClick:M,children:"Reload"}),e.jsx(o,{type:"button",disabled:!ue,onClick:Ae,children:H?"Saving...":"Save changes"})]}),e.jsx(W,{open:Ne,onOpenChange:N,children:e.jsxs(B,{children:[e.jsxs(q,{children:[e.jsx(J,{children:"Enter Git Credentials"}),e.jsx(K,{children:"Enter your username and personal access token for HTTPS authentication. Your credentials will be securely stored using your system's credential manager."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[!a?.remote&&e.jsx("div",{className:"rounded border border-amber-200 bg-amber-50 p-3 text-xs text-amber-700 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-200",children:"No remote URL configured. Set a remote URL first before entering credentials."}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"git-username",children:"Username"}),e.jsx(U,{id:"git-username",placeholder:"your-username",value:C,onChange:t=>F(t.target.value),autoComplete:"username"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"git-password",children:"Password / Personal Access Token"}),e.jsx(U,{id:"git-password",type:"password",placeholder:"ghp_xxxxxxxxxxxx or your password",value:k,onChange:t=>D(t.target.value),autoComplete:"current-password"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["We recommend using a Personal Access Token instead of your password.",e.jsx("br",{}),"GitHub: Settings → Developer settings → Personal access tokens",e.jsx("br",{}),"GitLab: Preferences → Access Tokens"]})]})]}),e.jsxs(Y,{children:[e.jsx(o,{variant:"outline",onClick:()=>{N(!1),F(""),D("")},children:"Cancel"}),e.jsx(o,{onClick:Le,disabled:re||!C||!k||!a?.remote,children:re?"Saving...":"Save Credentials"})]})]})}),e.jsx(W,{open:ke,onOpenChange:P,children:e.jsxs(B,{children:[e.jsxs(q,{children:[e.jsx(J,{children:"Remove Remote?"}),e.jsx(K,{children:"This will remove the origin remote from your local git configuration. The remote repository itself won't be affected."})]}),e.jsxs(Y,{children:[e.jsx(o,{variant:"outline",onClick:()=>P(!1),children:"Cancel"}),e.jsx(o,{variant:"destructive",onClick:async()=>{P(!1),await Pe()},disabled:z,children:z?"Removing...":"Remove Remote"})]})]})}),e.jsx(W,{open:Ce,onOpenChange:R,children:e.jsxs(B,{children:[e.jsxs(q,{children:[e.jsx(J,{children:a?.remote?"Edit Remote URL":"Set Remote URL"}),e.jsx(K,{children:"Configure the git remote URL for your repository. This is the origin remote used for push and pull operations."})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"remote-url",children:"Remote URL"}),e.jsx(U,{id:"remote-url",placeholder:"https://github.com/username/repo.git",value:E,onChange:t=>G(t.target.value),autoComplete:"off"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter your repository URL (HTTPS or SSH format)."})]})}),e.jsxs(Y,{children:[e.jsx(o,{variant:"outline",onClick:()=>{R(!1),G("")},children:"Cancel"}),e.jsx(o,{onClick:Ge,disabled:ne||!E.trim(),children:ne?"Saving...":"Save"})]})]})})]})}export{Xe as default};
|