crewly 1.0.3 โ 1.0.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/config/roles/orchestrator/prompt.md +61 -2
- package/config/skills/orchestrator/remember/instructions.md +8 -1
- package/config/skills/orchestrator/update-team/execute.sh +16 -0
- package/config/skills/orchestrator/update-team/instructions.md +21 -0
- package/config/skills/orchestrator/update-team/skill.json +20 -0
- package/dist/backend/backend/src/controllers/messaging/delivery-logs.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/delivery-logs.controller.js +4 -2
- package/dist/backend/backend/src/controllers/messaging/delivery-logs.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/scheduled-messages.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/scheduled-messages.controller.js +10 -8
- package/dist/backend/backend/src/controllers/messaging/scheduled-messages.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js +28 -26
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/project/git.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/project/git.controller.js +9 -7
- package/dist/backend/backend/src/controllers/project/git.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/project/project.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/project/project.controller.js +52 -50
- package/dist/backend/backend/src/controllers/project/project.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/skill/skill.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/skill/skill.controller.js +3 -1
- package/dist/backend/backend/src/controllers/skill/skill.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack-thread.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack-thread.controller.js +3 -1
- package/dist/backend/backend/src/controllers/slack/slack-thread.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/config.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/config.controller.js +3 -1
- package/dist/backend/backend/src/controllers/system/config.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/errors.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/errors.controller.js +7 -5
- package/dist/backend/backend/src/controllers/system/errors.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/scheduler.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/scheduler.controller.js +6 -4
- package/dist/backend/backend/src/controllers/system/scheduler.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.js +20 -19
- package/dist/backend/backend/src/controllers/system/system.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/assignments.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/assignments.controller.js +4 -2
- package/dist/backend/backend/src/controllers/task-management/assignments.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/in-progress-tasks.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/in-progress-tasks.controller.js +3 -1
- package/dist/backend/backend/src/controllers/task-management/in-progress-tasks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +30 -28
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/tasks.controller.js +7 -5
- package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/tickets.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/tickets.controller.js +12 -10
- package/dist/backend/backend/src/controllers/task-management/tickets.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +44 -42
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js +1 -0
- package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +5 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/factory.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/factory.routes.js +4 -2
- package/dist/backend/backend/src/routes/factory.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js +8 -2
- package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +6 -0
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +29 -6
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +22 -8
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +9 -3
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/context-loader.service.d.ts +1 -0
- package/dist/backend/backend/src/services/ai/context-loader.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/context-loader.service.js +9 -7
- package/dist/backend/backend/src/services/ai/context-loader.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-template.service.d.ts +1 -0
- package/dist/backend/backend/src/services/ai/prompt-template.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-template.service.js +7 -5
- package/dist/backend/backend/src/services/ai/prompt-template.service.js.map +1 -1
- package/dist/backend/backend/src/services/core/config.service.d.ts +6 -0
- package/dist/backend/backend/src/services/core/config.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/config.service.js +25 -5
- package/dist/backend/backend/src/services/core/config.service.js.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.d.ts +10 -2
- package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.js +45 -29
- package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +50 -33
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/team-activity-websocket.service.d.ts +4 -1
- package/dist/backend/backend/src/services/monitoring/team-activity-websocket.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/team-activity-websocket.service.js +28 -14
- package/dist/backend/backend/src/services/monitoring/team-activity-websocket.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/improvement-startup.service.d.ts +1 -0
- package/dist/backend/backend/src/services/orchestrator/improvement-startup.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/improvement-startup.service.js +22 -20
- package/dist/backend/backend/src/services/orchestrator/improvement-startup.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js +11 -2
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/safe-restart.service.d.ts +1 -0
- package/dist/backend/backend/src/services/orchestrator/safe-restart.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/safe-restart.service.js +25 -23
- package/dist/backend/backend/src/services/orchestrator/safe-restart.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/self-improvement.service.d.ts +1 -0
- package/dist/backend/backend/src/services/orchestrator/self-improvement.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/self-improvement.service.js +12 -10
- package/dist/backend/backend/src/services/orchestrator/self-improvement.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/slack-bridge-lazy.d.ts +17 -0
- package/dist/backend/backend/src/services/orchestrator/slack-bridge-lazy.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orchestrator/slack-bridge-lazy.js +30 -0
- package/dist/backend/backend/src/services/orchestrator/slack-bridge-lazy.js.map +1 -0
- package/dist/backend/backend/src/services/orchestrator/state-persistence.service.d.ts +1 -0
- package/dist/backend/backend/src/services/orchestrator/state-persistence.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/state-persistence.service.js +14 -12
- package/dist/backend/backend/src/services/orchestrator/state-persistence.service.js.map +1 -1
- package/dist/backend/backend/src/services/project/active-projects.service.d.ts +1 -0
- package/dist/backend/backend/src/services/project/active-projects.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project/active-projects.service.js +8 -6
- package/dist/backend/backend/src/services/project/active-projects.service.js.map +1 -1
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +1 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project/task-tracking.service.js +18 -16
- package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -1
- package/dist/backend/backend/src/services/project/ticket-editor.service.d.ts +1 -0
- package/dist/backend/backend/src/services/project/ticket-editor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project/ticket-editor.service.js +6 -4
- package/dist/backend/backend/src/services/project/ticket-editor.service.js.map +1 -1
- package/dist/backend/backend/src/services/settings/role.service.d.ts +1 -0
- package/dist/backend/backend/src/services/settings/role.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/settings/role.service.js +3 -1
- package/dist/backend/backend/src/services/settings/role.service.js.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-executor.service.d.ts +1 -0
- package/dist/backend/backend/src/services/skill/skill-executor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-executor.service.js +4 -2
- package/dist/backend/backend/src/services/skill/skill-executor.service.js.map +1 -1
- package/dist/backend/backend/src/services/skill/skill.service.d.ts +1 -0
- package/dist/backend/backend/src/services/skill/skill.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/skill.service.js +7 -5
- package/dist/backend/backend/src/services/skill/skill.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-image.service.d.ts +1 -0
- package/dist/backend/backend/src/services/slack/slack-image.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-image.service.js +6 -4
- package/dist/backend/backend/src/services/slack/slack-image.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +7 -5
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +1 -0
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +25 -20
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts +1 -0
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +19 -15
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/utils/process-recovery.d.ts +1 -0
- package/dist/backend/backend/src/utils/process-recovery.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/process-recovery.js +40 -37
- package/dist/backend/backend/src/utils/process-recovery.js.map +1 -1
- package/dist/backend/backend/src/utils/prompt-resolver.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/prompt-resolver.js +3 -1
- package/dist/backend/backend/src/utils/prompt-resolver.js.map +1 -1
- package/dist/backend/backend/src/utils/resource-monitor.d.ts +2 -1
- package/dist/backend/backend/src/utils/resource-monitor.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/resource-monitor.js +34 -24
- package/dist/backend/backend/src/utils/resource-monitor.js.map +1 -1
- package/dist/cli/cli/src/commands/onboard.d.ts +89 -0
- package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/onboard.js +268 -0
- package/dist/cli/cli/src/commands/onboard.js.map +1 -0
- package/dist/cli/cli/src/index.js +5 -0
- package/dist/cli/cli/src/index.js.map +1 -1
- package/dist/cli/cli/src/utils/marketplace.d.ts +22 -0
- package/dist/cli/cli/src/utils/marketplace.d.ts.map +1 -1
- package/dist/cli/cli/src/utils/marketplace.js +43 -0
- package/dist/cli/cli/src/utils/marketplace.js.map +1 -1
- package/frontend/dist/assets/{index-4c56763b.js โ index-419da091.js} +2 -2
- package/frontend/dist/assets/index-5adb4dff.css +33 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +2 -1
- package/frontend/dist/assets/index-c1dd0b10.css +0 -33
|
@@ -95,7 +95,7 @@ WARNING: This link could potentially be dangerous`)){const m=window.open();if(m)
|
|
|
95
95
|
`),ut.subscribeToSession(ee),C.current=ee,v.current){const pe=v.current.proposeDimensions();pe&&ut.resizeTerminal(ee,pe.cols,pe.rows)}M.current=setTimeout(()=>{ee===O.current&&(d(!1),N(`# Connection timeout for session: ${ee}\r
|
|
96
96
|
# No response from server after 10 seconds.\r
|
|
97
97
|
# Try refreshing the page or selecting a different session.\r
|
|
98
|
-
`)),M.current=null},1e4)},te=async()=>{var ee;try{const pe=await fetch("/api/terminal/sessions");if(!pe.ok){l(!0);return}const Z=await pe.json(),be=Z.success&&((ee=Z.data)!=null&&ee.sessions)?Z.data.sessions:[];if(Array.isArray(be)){const re=be.map(le=>({id:le,name:le,displayName:le==="crewly-orc"?"Orchestrator":le.replace("crewly-",""),type:le==="crewly-orc"?"orchestrator":"team_member"}));re.sort((le,fe)=>le.type==="orchestrator"?-1:fe.type==="orchestrator"?1:le.displayName.localeCompare(fe.displayName)),o(re),!re.some(le=>le.id===r)&&re.length>0&&s(re[0].id)}else o([]);l(!0)}catch{l(!0)}},ue=()=>{y(null),ie()};return P.useEffect(()=>{n&&m.current&&m.current.focus()},[n,x]),c.jsxs("div",{ref:p,className:`fixed top-0 right-0 h-full bg-surface-dark border-l border-border-dark flex flex-col z-50 transition-transform duration-300 ${n?"translate-x-0":"translate-x-full"} w-full sm:w-[600px]`,children:[c.jsxs("div",{className:"flex items-center justify-between p-3 sm:p-4 border-b border-border-dark",children:[c.jsxs("div",{className:"flex items-center space-x-2 sm:space-x-3 min-w-0",children:[c.jsx(Ox,{className:"w-5 h-5 text-text-secondary-dark shrink-0"}),c.jsx("span",{className:"font-medium text-text-primary-dark truncate",children:"Terminal"}),c.jsxs("div",{className:"flex items-center space-x-1.5 shrink-0",children:[c.jsx("div",{className:`w-2 h-2 rounded-full ${h==="connected"?"bg-green-400":h==="connecting"||h==="reconnecting"?"bg-yellow-400":h==="error"?"bg-red-400":"bg-gray-400"}`}),c.jsx("span",{className:"text-xs sm:text-sm text-text-secondary-dark",children:h==="connected"?"Live":h==="connecting"?"Connecting...":h==="reconnecting"?"Reconnecting...":h==="error"?"Error":"Disconnected"})]})]}),c.jsx("button",{onClick:e,className:"p-1 text-text-secondary-dark hover:text-text-primary-dark hover:bg-background-dark rounded transition-colors shrink-0","aria-label":"Close Terminal",children:c.jsx(Br,{className:"w-5 h-5"})})]}),c.jsx("div",{className:"px-3 sm:px-4 py-2 sm:py-3 border-b border-border-dark",children:c.jsxs("div",{className:"flex items-center space-x-2 sm:space-x-3",children:[c.jsx("label",{htmlFor:"session-select",className:"text-xs sm:text-sm font-medium text-text-secondary-dark shrink-0",children:"Session:"}),c.jsx("select",{id:"session-select",value:r,onChange:ee=>s(ee.target.value),className:"flex-1 min-w-0 px-2 sm:px-3 py-1 bg-background-dark border border-border-dark rounded text-xs sm:text-sm text-text-primary-dark focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent disabled:opacity-50",disabled:h!=="connected",children:i.map(ee=>c.jsx("option",{value:ee.id,children:ee.displayName},ee.id))})]})}),c.jsxs("div",{className:"flex-1 flex flex-col",children:[g&&c.jsxs("div",{className:"mx-4 my-2 px-4 py-3 bg-red-500/10 border-l-4 border-red-500 text-red-400 flex items-center space-x-2",children:[c.jsx(sh,{className:"w-4 h-4 flex-shrink-0"}),c.jsx("span",{className:"flex-1 text-sm",children:g}),c.jsx(wt,{onClick:ue,variant:"ghost",size:"sm",className:"text-red-400 hover:text-red-300",children:"Retry"})]}),c.jsx("div",{className:"flex-1 overflow-hidden",children:a&&i.length===0?c.jsxs("div",{className:"h-full flex flex-col items-center justify-center p-8 text-center",children:[c.jsx("div",{className:"w-16 h-16 rounded-full bg-surface-dark border border-border-dark flex items-center justify-center mb-4",children:c.jsx(Ox,{className:"w-8 h-8 text-text-secondary-dark"})}),c.jsx("h3",{className:"text-lg font-medium text-text-primary-dark mb-2",children:"No Terminal Sessions Available"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mb-6 max-w-sm",children:"The orchestrator is not running. Start the orchestrator to enable terminal sessions for your agents."}),c.jsxs(wt,{onClick:()=>{e(),t("/teams/orchestrator")},variant:"primary",size:"default",className:"flex items-center space-x-2",children:[c.jsx(jl,{className:"w-4 h-4"}),c.jsx("span",{children:"Go to Orchestrator"})]})]}):c.jsx("div",{ref:b,className:"h-full w-full bg-background-dark",style:{minHeight:"100%"}})}),u&&h==="connected"&&c.jsx("div",{className:"px-4 py-2 border-t border-border-dark",children:c.jsxs("div",{className:"flex items-center space-x-2 text-sm text-text-secondary-dark",children:[c.jsx("div",{className:"w-3 h-3 border-2 border-primary border-t-transparent rounded-full animate-spin"}),c.jsx("span",{children:"Loading terminal output..."})]})})]})]})},xH="/api/orchestrator/status",vH=5e3;function yL(){const[n,e]=P.useState(null),[t,r]=P.useState(!0),[s,i]=P.useState(null),o=P.useRef(!0),a=P.useRef(null),l=P.useCallback(async()=>{a.current&&a.current.abort();const d=new AbortController;a.current=d;try{const h=await yt.get(xH,{signal:d.signal,timeout:vH});if(!o.current)return;h.data.success&&h.data.data?(e(h.data.data),i(null)):i(h.data.error||"Failed to get orchestrator status")}catch(h){if(yt.isCancel(h)||!o.current)return;const f=h instanceof Error?h.message:"Unable to check orchestrator status";i(f),e({isActive:!1,agentStatus:null,message:"Unable to check orchestrator status",offlineMessage:"The orchestrator is currently offline. Please start it from the Dashboard."})}finally{o.current&&r(!1)}},[]),u=P.useCallback(async()=>{r(!0),await l()},[l]);return P.useEffect(()=>(o.current=!0,l(),()=>{o.current=!1,a.current&&a.current.abort()}),[l]),P.useEffect(()=>{const d=f=>{if(!o.current)return;const g=f.agentStatus==="active";e({isActive:g,agentStatus:f.agentStatus||null,message:g?"Orchestrator is active and ready.":f.agentStatus==="starting"||f.agentStatus==="started"?"Orchestrator is starting up. Please wait a moment and try again.":"Orchestrator is not running. Please start the orchestrator from the Dashboard.",offlineMessage:g?null:"The orchestrator is currently offline. Please start it from the Crewly dashboard."}),r(!1),i(null)},h=()=>{o.current&&l()};return ut.on("orchestrator_status_changed",d),ut.on("connected",h),()=>{ut.off("orchestrator_status_changed",d),ut.off("connected",h)}},[l]),{status:n,isLoading:t,error:s,refresh:u}}const yH=()=>{const{status:n,isLoading:e,refresh:t}=yL(),[r,s]=P.useState(!1),[i,o]=P.useState(!1),a=async()=>{o(!0),await t(),setTimeout(()=>o(!1),500)},l=(n==null?void 0:n.isActive)??!0,u=n==null?void 0:n.agentStatus;if(e||l||!n||r)return null;const d=u==="activating"||u==="starting"||u==="started",h=d?"bg-yellow-500/10 border-yellow-500/30":"bg-rose-500/10 border-rose-500/30",f=d?"text-yellow-400":"text-rose-400",g=d?"text-yellow-300":"text-rose-300",y=d?"text-yellow-200/80":"text-rose-200/80";return c.jsxs("div",{className:`flex items-center justify-between px-4 py-2.5 border-b ${h}`,children:[c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(Ep,{className:`shrink-0 ${f}`,size:18}),c.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[c.jsx("span",{className:`font-semibold ${g}`,children:d?"Orchestrator Initializing":"Orchestrator Not Running"}),c.jsx("span",{className:y,children:d?"The Crewly orchestrator is starting up. This may take a few moments...":"The Crewly orchestrator is not running. Check the application logs for issues."})]})]}),c.jsxs("div",{className:"flex items-center gap-1",children:[c.jsx(Ci,{icon:Cu,onClick:a,variant:"ghost",size:"sm",className:i?"animate-spin":"","aria-label":"Refresh status"}),c.jsx(Ci,{icon:Br,onClick:()=>s(!0),variant:"ghost",size:"sm","aria-label":"Dismiss banner"})]})]})},_H="/health",SH=5e3;function bH(){const[n,e]=P.useState(null),[t,r]=P.useState(!0),s=P.useRef(!0);return P.useEffect(()=>(s.current=!0,(async()=>{try{const o=await yt.get(_H,{timeout:SH});if(!s.current)return;e({currentVersion:o.data.version,latestVersion:o.data.latestVersion,updateAvailable:o.data.updateAvailable})}catch{}finally{s.current&&r(!1)}})(),()=>{s.current=!1}),[]),{versionInfo:n,isLoading:t}}const wH=()=>{const{versionInfo:n,isLoading:e}=bH(),[t,r]=P.useState(!1);return e||!(n!=null&&n.updateAvailable)||t?null:c.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 border-b bg-cyan-500/10 border-cyan-500/30",children:[c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(DF,{className:"shrink-0 text-cyan-400",size:18}),c.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[c.jsx("span",{className:"font-semibold text-cyan-300",children:"Update Available"}),c.jsxs("span",{className:"text-cyan-200/80",children:["Crewly v",n.latestVersion," is available (current: v",n.currentVersion,"). Run ",c.jsx("code",{className:"bg-cyan-500/20 px-1.5 py-0.5 rounded text-cyan-300",children:"crewly upgrade"})," to update."]})]})]}),c.jsx(Ci,{icon:Br,onClick:()=>r(!0),variant:"ghost",size:"sm","aria-label":"Dismiss update banner"})]})},xn="/api",CH=2*60*1e3;class AH{constructor(){Vs(this,"teamsCache",null);Vs(this,"teamsCachePromise",null)}async getProjects(){return(await yt.get(`${xn}/projects`)).data.data||[]}async getProject(e){const t=await yt.get(`${xn}/projects/${e}`);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Project not found");return t.data.data}async createProject(e,t,r){const s=await yt.post(`${xn}/projects`,{path:e,name:t,description:r});if(!s.data.success||!s.data.data)throw new Error(s.data.error||"Failed to create project");return s.data.data}async startProject(e,t){const r=await yt.post(`${xn}/projects/${e}/start`,{teamIds:t});if(!r.data.success)throw new Error(r.data.error||"Failed to start project");return{message:r.data.message||"Project started successfully"}}async assignTeamsToProject(e,t){const r=await this.getTeams(),s={};t.forEach(o=>{const a=r.find(l=>l.id===o);if(a&&a.members.length>0){const l=a.members[0].role;s[l]||(s[l]=[]),s[l].push(o)}});const i=await yt.post(`${xn}/projects/${e}/assign-teams`,{teamAssignments:s});if(!i.data.success)throw new Error(i.data.error||"Failed to assign teams")}async getTeams(e=!1){return!e&&this.teamsCache&&Date.now()-this.teamsCache.timestamp<CH?this.teamsCache.data:this.teamsCachePromise?this.teamsCachePromise:(this.teamsCachePromise=(async()=>{try{const r=(await yt.get(`${xn}/teams`)).data.data||[];return this.teamsCache={data:r,timestamp:Date.now()},r}finally{this.teamsCachePromise=null}})(),this.teamsCachePromise)}invalidateTeamsCache(){this.teamsCache=null}async getTeam(e){const t=await yt.get(`${xn}/teams/${e}`);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Team not found");return t.data.data}async createTeam(e){const t=await yt.post(`${xn}/teams`,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to create team");return this.invalidateTeamsCache(),t.data.data}async deleteTeam(e){const t=await yt.delete(`${xn}/teams/${e}`);if(!t.data.success)throw new Error(t.data.error||"Failed to delete team");this.invalidateTeamsCache()}async unassignTeamFromProject(e,t){const r=await yt.post(`${xn}/projects/${e}/unassign-team`,{teamId:t});if(!r.data.success)throw new Error(r.data.error||"Failed to unassign team")}async startTeam(e){await yt.post(`${xn}/teams/${e}/start`,{})}async getProjectTickets(e){return(await yt.get(`${xn}/projects/${e}/tickets`)).data.data||[]}async createTicket(e,t){const r=await yt.post(`${xn}/projects/${e}/tickets`,t);if(!r.data.success||!r.data.data)throw new Error(r.data.error||"Failed to create ticket");return r.data.data}async updateTicket(e,t){const r=await yt.patch(`${xn}/tickets/${e}`,t);if(!r.data.success||!r.data.data)throw new Error(r.data.error||"Failed to update ticket");return r.data.data}async deleteTicket(e,t){const r=await yt.delete(`${xn}/projects/${e}/tickets/${t}`);if(!r.data.success)throw new Error(r.data.error||"Failed to delete ticket")}async getPreviousSessions(){return(await yt.get(`${xn}/sessions/previous`)).data.data||{sessions:[]}}async dismissPreviousSessions(){await yt.post(`${xn}/sessions/previous/dismiss`)}async getAllTasks(e){return(await yt.get(`${xn}/projects/${e}/tasks`)).data.data||[]}async getMilestones(e){return(await yt.get(`${xn}/projects/${e}/milestones`)).data.data||[]}async getTasksByStatus(e,t){return(await yt.get(`${xn}/projects/${e}/tasks/status/${t}`)).data.data||[]}async getTasksByMilestone(e,t){return(await yt.get(`${xn}/projects/${e}/tasks/milestone/${t}`)).data.data||[]}async getTeamsBackupStatus(){const e=await yt.get(`${xn}/teams/backup/status`);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to get backup status");return e.data.data}async restoreTeamsFromBackup(){const e=await yt.post(`${xn}/teams/backup/restore`);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to restore from backup");return e.data.data}async getQueueStatus(){const e=await yt.get(`${xn}/messaging/queue/status`);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to get queue status");return e.data.data}async getPendingMessages(){return(await yt.get(`${xn}/messaging/queue/messages`)).data.data||[]}async cancelQueueMessage(e){const t=await yt.delete(`${xn}/messaging/queue/messages/${e}`);if(!t.data.success)throw new Error(t.data.error||"Failed to cancel message")}async clearQueue(){const e=await yt.delete(`${xn}/messaging/queue`);if(!e.data.success)throw new Error(e.data.error||"Failed to clear queue")}async getKnowledgeDocuments(e="global",t,r,s){const i={scope:e};return t&&(i.projectPath=t),r&&(i.category=r),s&&(i.search=s),(await yt.get(`${xn}/knowledge/documents`,{params:i})).data.data||[]}async getKnowledgeDocument(e,t="global",r){const s={scope:t};r&&(s.projectPath=r);const i=await yt.get(`${xn}/knowledge/documents/${e}`,{params:s});if(!i.data.success||!i.data.data)throw new Error(i.data.error||"Document not found");return i.data.data}async createKnowledgeDocument(e){const t=await yt.post(`${xn}/knowledge/documents`,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to create document");return t.data.data.id}async updateKnowledgeDocument(e,t){const r=await yt.put(`${xn}/knowledge/documents/${e}`,t);if(!r.data.success)throw new Error(r.data.error||"Failed to update document")}async deleteKnowledgeDocument(e,t="global",r){const s={scope:t};r&&(s.projectPath=r);const i=await yt.delete(`${xn}/knowledge/documents/${e}`,{params:s});if(!i.data.success)throw new Error(i.data.error||"Failed to delete document")}async getKnowledgeCategories(e="global",t){const r={scope:e};return t&&(r.projectPath=t),(await yt.get(`${xn}/knowledge/categories`,{params:r})).data.data||[]}}const sn=new AH,gc="/api/settings";class MH{async getSettings(){const e=await yt.get(gc);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to get settings");return e.data.data}async updateSettings(e){const t=await yt.put(gc,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to update settings");return t.data.data}async validateSettings(e){const t=await yt.post(`${gc}/validate`,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to validate settings");return t.data.data}async resetSettings(){const e=await yt.post(`${gc}/reset`);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to reset settings");return e.data.data}async resetSection(e){const t=await yt.post(`${gc}/reset/${e}`);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to reset section");return t.data.data}async exportSettings(){return(await yt.post(`${gc}/export`)).data}async importSettings(e){const t=await yt.post(`${gc}/import`,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to import settings");return t.data.data}}const Of=new MH,EH=()=>{const[n,e]=P.useState([]),[t,r]=P.useState(!1),[s,i]=P.useState(!1),[o,a]=P.useState(null),l=P.useRef(!1);P.useEffect(()=>{let y=!1;return(async()=>{var p;try{const[m,v]=await Promise.all([sn.getPreviousSessions(),Of.getSettings().catch(()=>null)]),x=m.sessions.filter(C=>C.role!=="orchestrator");if(y||x.length===0)return;if(e(x),(((p=v==null?void 0:v.general)==null?void 0:p.autoResumeOnRestart)??!0)&&!l.current){l.current=!0;const C=new Set;for(const M of x)M.teamId&&M.role!=="orchestrator"&&C.add(M.teamId);for(const M of C)try{await sn.startTeam(M)}catch{}try{await sn.dismissPreviousSessions()}catch{}return}r(!0)}catch{}})(),()=>{y=!0}},[]);const u=P.useMemo(()=>{const y=new Set;for(const b of n)b.teamId&&b.role!=="orchestrator"&&y.add(b.teamId);return Array.from(y)},[n]),d=u.length>0,h=P.useCallback(async()=>{i(!0);try{await sn.dismissPreviousSessions()}catch{}r(!1),i(!1)},[]),f=P.useCallback(async()=>{i(!0),a(null);const y=[];for(const b of u)try{await sn.startTeam(b)}catch{y.push(b)}if(y.length===0){try{await sn.dismissPreviousSessions()}catch{}r(!1)}else a(`Failed to start ${y.length} team(s). You can start them manually from the Teams page.`);i(!1)},[u]);if(!t)return null;const g=c.jsxs(c.Fragment,{children:[c.jsx(wt,{variant:"secondary",onClick:h,disabled:s,children:"Dismiss"}),c.jsx(wt,{variant:"primary",icon:jl,onClick:f,disabled:s||!d,children:"Resume All"})]});return c.jsxs(Qp,{isOpen:t,onClose:h,title:"Previous Sessions Detected",subtitle:"The following agents were running before the app restarted.",size:"lg",footer:g,loading:s,children:[c.jsx("div",{className:"space-y-2",children:n.map(y=>c.jsxs("div",{className:"flex items-center justify-between p-3 rounded-lg bg-background-dark border border-border-dark",children:[c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(oP,{className:"w-4 h-4 text-text-secondary-dark"}),c.jsxs("div",{children:[c.jsx("div",{className:"text-sm font-medium",children:y.name}),y.role&&c.jsx("div",{className:"text-xs text-text-secondary-dark",children:y.role})]})]}),c.jsxs("div",{className:"flex items-center gap-2",children:[c.jsx(Qb,{variant:y.hasResumeId?"success":"default",size:"sm",children:y.hasResumeId?"Resumable":"Restart"}),c.jsx(Qb,{variant:"default",size:"sm",children:y.runtimeType})]})]},y.name))}),o&&c.jsx("p",{className:"mt-3 text-xs text-rose-400",children:o}),c.jsx("p",{className:"mt-4 text-xs text-text-secondary-dark",children:'Click "Resume All" to restart all teams, or dismiss to start them manually from the Teams page.'})]})},TH=()=>{const[n,e]=P.useState(null),[t,r]=P.useState(!1),[s,i]=P.useState(!1),[o,a]=P.useState(null);P.useEffect(()=>{let f=!1;return(async()=>{try{const y=await sn.getTeamsBackupStatus();!f&&y.hasMismatch&&(e(y),r(!0))}catch{}})(),()=>{f=!0}},[]);const l=P.useCallback(()=>{r(!1)},[]),u=P.useCallback(async()=>{i(!0),a(null);try{const f=await sn.restoreTeamsFromBackup();f.errors&&f.errors.length>0?(a(`Restored ${f.restoredCount} of ${f.totalInBackup} teams. Some teams failed to restore.`),i(!1)):(r(!1),window.location.reload())}catch(f){a(f instanceof Error?f.message:"Failed to restore teams from backup"),i(!1)}},[]);if(!t||!n)return null;const d=n.backupTimestamp?new Date(n.backupTimestamp).toLocaleString():"unknown",h=c.jsxs(c.Fragment,{children:[c.jsx(wt,{variant:"secondary",onClick:l,disabled:s,children:"Dismiss"}),c.jsx(wt,{variant:"primary",icon:cP,onClick:u,disabled:s,children:"Restore"})]});return c.jsxs(Qp,{isOpen:t,onClose:l,title:"Teams Data Missing",subtitle:"A backup of your teams data is available.",size:"md",footer:h,loading:s,children:[c.jsxs("div",{className:"space-y-3",children:[c.jsxs("p",{className:"text-sm text-text-primary-dark",children:["Your teams data appears to be missing. A backup with"," ",c.jsxs("span",{className:"font-semibold",children:[n.backupTeamCount," team",n.backupTeamCount!==1?"s":""]})," ","from ",c.jsx("span",{className:"font-semibold",children:d})," is available."]}),c.jsx("p",{className:"text-xs text-text-secondary-dark",children:'Click "Restore" to recover your teams, or "Dismiss" to start fresh.'})]}),o&&c.jsx("p",{className:"mt-3 text-xs text-rose-400",children:o})]})},kH=()=>{const{isTerminalOpen:n,openTerminal:e,closeTerminal:t}=rm(),{isCollapsed:r}=zC(),[s,i]=P.useState(!1),o=()=>{n?t():e()};return c.jsxs("div",{className:"flex h-screen overflow-hidden bg-background-dark",children:[c.jsx(EH,{}),c.jsx(TH,{}),c.jsx("div",{className:`fixed inset-0 bg-black/60 z-40 md:hidden transition-opacity ${s?"opacity-100":"opacity-0 pointer-events-none"}`,onClick:()=>i(!1),"aria-hidden":"true"}),c.jsx("div",{className:fs("fixed left-0 top-0 h-full z-50 transition-all duration-300 ease-in-out","md:translate-x-0",s?"translate-x-0":"-translate-x-full",r?"md:w-16":"md:w-64","w-64"),children:c.jsx(x8,{isMobileOpen:s,onMobileClose:()=>i(!1)})}),c.jsxs("div",{className:fs("flex-1 flex flex-col min-w-0 transition-all duration-300 ease-in-out",r?"md:ml-16":"md:ml-64"),children:[c.jsxs("header",{className:"md:hidden h-16 flex items-center justify-between px-4 bg-surface-dark/80 backdrop-blur-sm border-b border-border-dark sticky top-0 z-30",children:[c.jsx(Ci,{variant:"ghost",icon:YF,onClick:()=>i(!0),"aria-label":"Open menu"}),c.jsx("h1",{className:"text-lg font-bold",children:"Crewly"}),c.jsx("div",{className:"w-10 h-10"})," "]}),c.jsxs("main",{className:"flex-1 flex flex-col min-h-0 overflow-hidden",children:[c.jsx(wH,{}),c.jsx(yH,{}),c.jsx("div",{className:"flex-1 p-4 md:p-6 min-h-0 overflow-y-auto",children:c.jsx(gF,{})})]})]}),c.jsx(Ci,{className:`fixed bottom-6 right-6 z-40 ${n?"bg-primary/90":""}`,icon:Ox,onClick:o,variant:"primary","aria-label":n?"Close Terminal":"Open Terminal"}),c.jsxs(c.Fragment,{children:[n&&c.jsx("div",{className:"fixed inset-0 bg-black/50 z-30",onClick:t}),c.jsx(gH,{isOpen:n,onClose:t})]})]})},CT={active:{bg:"bg-green-500/10",text:"text-green-400",label:"Running"},paused:{bg:"bg-yellow-500/10",text:"text-yellow-400",label:"Stopped"},completed:{bg:"bg-blue-500/10",text:"text-blue-400",label:"Completed"},blocked:{bg:"bg-red-500/10",text:"text-red-400",label:"Blocked"},stopped:{bg:"bg-gray-500/10",text:"text-gray-400",label:"Stopped"}},_L=({project:n,showStatus:e=!1,showTeams:t=!1,assignedTeams:r=[],onClick:s,progressPercent:i,progressLabel:o,progressBreakdown:a})=>{r.length||Object.values(n.teams||{}).flat().length;const l=new Date(n.updatedAt).toLocaleDateString(),u=CT[n.status]||CT.active,h=(f=>{if(!f)return"";const g=f.split("/").filter(Boolean),y=g.slice(-3).join("/"),b=g.length>3?`โฆ/${y}`:`/${g.join("/")}`;return b.length<=60?b:`โฆ${b.slice(-60)}`})(n.path);return c.jsxs("div",{className:`bg-surface-dark p-6 rounded-lg border border-border-dark transition-all hover:shadow-lg hover:border-primary/50 flex flex-col h-full ${s?"cursor-pointer":""}`,onClick:s,children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h3",{className:"font-semibold text-lg",children:n.name}),e&&c.jsx("span",{className:`text-xs font-medium px-2 py-1 rounded-full ${u.bg} ${u.text}`,children:u.label})]}),c.jsx("p",{className:"text-sm text-text-secondary-dark flex-grow mb-4 whitespace-nowrap overflow-hidden text-ellipsis",title:n.path,children:h}),typeof i=="number"&&c.jsxs("div",{className:"mb-6",children:[c.jsxs("div",{className:"flex justify-between items-center mb-1",children:[c.jsx("p",{className:"text-xs text-text-secondary-dark",children:"Progress"}),c.jsxs("p",{className:"text-xs font-semibold",children:[i,"%"]})]}),c.jsx("div",{className:"w-full bg-background-dark rounded-full h-2",children:c.jsx("div",{className:"bg-primary h-2 rounded-full",style:{width:`${Math.max(0,Math.min(100,i))}%`},title:a?`Open: ${a.open}, In progress: ${a.inProgress}, Pending: ${a.pending}, Done: ${a.done}, Blocked: ${a.blocked}`:void 0})})]}),c.jsxs("div",{className:"mt-auto flex items-center justify-between",children:[c.jsx("div",{className:"flex -space-x-3",children:r.flatMap(f=>f.members||[]).slice(0,3).map((f,g)=>c.jsx("div",{className:"w-8 h-8 rounded-full border-2 border-surface-dark bg-cover bg-center overflow-hidden",title:f.name,children:f.avatar?f.avatar.startsWith("http")||f.avatar.startsWith("data:")?c.jsx("img",{src:f.avatar,alt:f.name,className:"w-full h-full object-cover"}):c.jsx("div",{className:"w-full h-full bg-gradient-to-br from-primary/20 to-primary/40 flex items-center justify-center text-xs font-bold text-white",children:f.avatar}):c.jsx("div",{className:"w-full h-full bg-gradient-to-br from-primary/20 to-primary/40 flex items-center justify-center text-xs font-bold text-white",children:f.name.charAt(0).toUpperCase()})},`${f.id}-${g}`))}),c.jsxs("p",{className:"text-sm text-text-secondary-dark",children:["Updated ",l]})]})]})},Mh=({items:n,align:e="bottom-right",buttonClassName:t="text-text-secondary-dark hover:text-primary transition-colors",menuClassName:r="",icon:s=eU})=>{const[i,o]=P.useState(!1),a=P.useRef(null);return P.useEffect(()=>{const l=u=>{a.current&&!a.current.contains(u.target)&&o(!1)};return i&&document.addEventListener("mousedown",l),()=>document.removeEventListener("mousedown",l)},[i]),c.jsxs("div",{className:"relative",ref:a,children:[c.jsx("button",{type:"button",className:t,onClick:()=>o(l=>!l),"aria-label":"More options",children:c.jsx(s,{className:"w-4 h-4"})}),i&&c.jsx("div",{className:`absolute z-10 w-44 bg-surface-dark border border-border-dark rounded-lg shadow-lg p-1 ${e==="bottom-right"?"right-0 top-8":"right-0 bottom-8"} ${r}`,children:n.map((l,u)=>c.jsx("button",{className:`w-full text-left px-3 py-2 text-sm rounded hover:bg-background-dark ${l.danger?"text-red-300":""}`,onClick:()=>{o(!1),l.onClick()},children:l.label},u))})]})},RH={xs:"w-6 h-6 text-xs",sm:"w-8 h-8 text-sm",md:"w-10 h-10 text-base",lg:"w-12 h-12 text-lg",xl:"w-16 h-16 text-xl"},NH={active:"bg-green-500",inactive:"bg-gray-400",activating:"bg-yellow-500"},SL=({name:n,avatar:e,size:t="md",className:r="",showStatus:s=!1,status:i,ringClass:o=""})=>{const a=RH[t],l=()=>{if(e&&(e.startsWith("http")||e.startsWith("data:")))return c.jsx("img",{src:e,alt:`${n}'s avatar`,title:n,className:`${a} rounded-full object-cover ${o} ${r}`});if(e)return c.jsx("div",{className:`${a} rounded-full bg-background-dark border border-border-dark flex items-center justify-center ${o} ${r}`,title:n,children:c.jsx("span",{children:e})});const u=n?n.charAt(0).toUpperCase():"";return c.jsx("div",{className:`${a} rounded-full bg-background-dark border border-border-dark flex items-center justify-center ${o} ${r}`,title:n,children:u})};return c.jsxs("div",{className:"relative inline-block",children:[l(),s&&i&&c.jsx("span",{className:`absolute bottom-0 right-0 w-3 h-3 ${NH[i]} rounded-full border-2 border-white dark:border-gray-800`,title:i})]})},bL=({team:n,projectName:e,onClick:t,onViewTeam:r,onEditTeam:s,onDeleteTeam:i})=>{const o=n.members||[],a=o.slice(0,3),l=Math.max(o.length-3,0),u=o.some(d=>d.agentStatus==="active");return c.jsxs("div",{className:"relative bg-surface-dark border border-border-dark rounded-2xl p-5 hover:border-primary/50 transition-colors cursor-pointer flex flex-col min-h-[200px]",onClick:t,children:[c.jsxs("div",{className:"flex items-center justify-between mb-3",children:[c.jsx("div",{className:"text-lg font-semibold",children:n.name}),u&&c.jsx("span",{className:"px-2 py-1 text-xs font-medium rounded-full bg-green-500/10 text-green-400",children:"Active"})]}),e&&c.jsxs("div",{className:"flex items-center gap-2 text-text-secondary-dark text-sm mb-4",children:[c.jsx(Os,{className:"w-4 h-4"}),c.jsxs("span",{children:["Project ",e]})]}),c.jsxs("div",{className:"mt-auto flex items-center justify-between",children:[c.jsxs("div",{className:"flex items-center",children:[a.map((d,h)=>c.jsx("div",{style:{marginLeft:h===0?0:-6},children:c.jsx(SL,{name:d.name,avatar:d.avatar,size:"sm",ringClass:"ring-2 ring-surface-dark"})},d.id)),l>0&&c.jsxs("div",{className:"w-8 h-8 rounded-full bg-background-dark border border-border-dark flex items-center justify-center text-xs text-text-secondary-dark ring-2 ring-surface-dark",style:{marginLeft:-6},children:["+",l]})]}),c.jsx("div",{onClick:d=>d.stopPropagation(),children:c.jsx(Mh,{align:"bottom-right",items:[{label:"Edit Team",onClick:()=>s&&s(n.id)},{label:"View Team",onClick:()=>r&&r(n.id)},...i?[{label:"Delete Team",danger:!0,onClick:()=>i(n.id)}]:[]]})})]})]})},pw=({title:n,icon:e=c.jsx(Ps,{className:"text-4xl"}),onClick:t,className:r=""})=>c.jsxs("div",{onClick:t,className:`flex items-center justify-center flex-col p-6 rounded-lg border-2 border-dashed border-border-dark hover:border-primary transition-colors cursor-pointer text-text-secondary-dark hover:text-primary h-full ${r}`,children:[e,c.jsx("p",{className:"mt-2 text-sm font-semibold",children:n})]}),R1="/api",Ag=({title:n,value:e})=>c.jsxs("div",{className:"bg-surface-dark p-6 rounded-lg border border-border-dark transition-all hover:shadow-lg hover:border-primary/50",children:[c.jsx("p",{className:"text-sm font-medium text-text-secondary-dark",children:n}),c.jsx("p",{className:"text-3xl font-bold mt-1",children:e})]}),IH=()=>{const n=Ua(),[e,t]=P.useState([]),[r,s]=P.useState([]),[i,o]=P.useState({}),[a,l]=P.useState({}),[u,d]=P.useState(!0);P.useEffect(()=>{f()},[]);const h=async w=>{try{const M=(await yt.get(`${R1}/projects/${w}/tasks`)).data.data||[],T={open:0,inProgress:0,pending:0,done:0,blocked:0,total:M.length};M.forEach(R=>{var L;const B=((L=R.status)==null?void 0:L.toLowerCase())||"pending";B==="open"?T.open++:B==="in_progress"||B==="in-progress"?T.inProgress++:B==="done"||B==="completed"?T.done++:B==="blocked"?T.blocked++:T.pending++});const A=T.total>0?Math.round(T.done/T.total*100):0,E=`${T.done} of ${T.total} completed`;return{projectId:w,progressPercent:A,progressLabel:E,progressBreakdown:T}}catch(C){return console.error(`Error calculating progress for project ${w}:`,C),{projectId:w,progressPercent:0,progressLabel:"No tasks",progressBreakdown:{open:0,inProgress:0,pending:0,done:0,blocked:0,total:0}}}},f=async()=>{try{d(!0);const[w,C]=await Promise.all([yt.get(`${R1}/projects`),yt.get(`${R1}/teams`)]);if(w.data.success){const R=w.data.data||[];t(R);const B=R.map(z=>h(z.id)),O=(await Promise.all(B)).reduce((z,q)=>(z[q.projectId]=q,z),{});l(O)}const M=w.data.success?w.data.data||[]:[],T=C.data.success?C.data.data||[]:[],A=["https://picsum.photos/seed/1/64","https://picsum.photos/seed/2/64","https://picsum.photos/seed/3/64","https://picsum.photos/seed/4/64","https://picsum.photos/seed/5/64","https://picsum.photos/seed/6/64"],E=T.map(R=>({...R,members:R.members.map((B,L)=>({...B,avatar:B.avatar||A[L%A.length]}))}));if(C.data.success&&s(E),w.data.success&&C.data.success){const R=M.reduce((B,L)=>{const O=E.filter(z=>{var K,N;const q=(K=z.projectIds)==null?void 0:K.includes(L.id),X=(N=z.projectIds)==null?void 0:N.includes(L.name);return q||X});return B[L.id]=O,B},{});o(R)}}catch(w){console.error("Error loading dashboard data:",w)}finally{d(!1)}},g=w=>n(`/projects/${w}`),y=w=>n(`/teams/${w}`),b=()=>{n("/projects?create=true")},p=()=>{n("/teams?create=true")},m=()=>n("/factory");if(u)return c.jsxs("div",{className:"flex items-center justify-center min-h-64",children:[c.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-2 border-primary border-t-transparent"}),c.jsx("p",{className:"ml-3 text-text-secondary-dark",children:"Loading dashboard..."})]});const v=e.slice(0,2),x=r.slice(0,6);return c.jsxs("div",{className:"max-w-7xl mx-auto",children:[c.jsx("div",{className:"flex flex-col md:flex-row items-start md:items-center justify-between gap-4 mb-8",children:c.jsxs("div",{children:[c.jsx("h2",{className:"text-3xl font-bold tracking-tight",children:"Dashboard"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mt-1",children:"Welcome back. Here's a summary of your teams and projects."})]})}),c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-6 mb-10",children:[c.jsx(Ag,{title:"Projects",value:e.length}),c.jsx(Ag,{title:"Teams",value:r.length}),c.jsx(Ag,{title:"Active Projects",value:e.filter(w=>w.status==="active").length}),c.jsx(Ag,{title:"Running Agents",value:r.flatMap(w=>w.members).filter(w=>w.agentStatus==="active").length}),c.jsx("button",{type:"button",onClick:m,className:"bg-gradient-to-br from-primary/20 to-purple-500/20 p-6 rounded-lg border border-primary/30 transition-all hover:shadow-lg hover:shadow-primary/20 hover:border-primary hover:scale-[1.02] group",children:c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(tP,{className:"w-8 h-8 text-primary group-hover:scale-110 transition-transform"}),c.jsxs("div",{className:"text-left",children:[c.jsx("p",{className:"text-sm font-medium text-text-secondary-dark",children:"3D View"}),c.jsx("p",{className:"text-lg font-bold text-primary",children:"Factory"})]})]})})]}),c.jsxs("div",{className:"space-y-10",children:[c.jsxs("section",{children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h3",{className:"text-xl font-semibold",children:"Projects"}),c.jsx(rh,{to:"/projects",className:"text-sm font-semibold text-primary hover:underline",children:"View All"})]}),c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6",children:[v.map(w=>{const C=a[w.id];return c.jsx(_L,{project:w,showStatus:!0,showTeams:!0,assignedTeams:i[w.id]||[],onClick:()=>g(w.id),progressPercent:C==null?void 0:C.progressPercent,progressLabel:C==null?void 0:C.progressLabel,progressBreakdown:C==null?void 0:C.progressBreakdown},w.id)}),c.jsx(pw,{title:"Create New Project",onClick:b})]})]}),c.jsxs("section",{children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h3",{className:"text-xl font-semibold",children:"Teams"}),c.jsx(rh,{to:"/teams",className:"text-sm font-semibold text-primary hover:underline",children:"View All"})]}),c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6",children:[x.map(w=>c.jsx(bL,{team:w,onClick:()=>y(w.id)},w.id)),c.jsx(pw,{title:"Create New Team",onClick:p})]})]})]})]})},PH=({onSelect:n,onCreateProject:e,onClose:t,initialPath:r,title:s="Select Folder",actionButtonText:i})=>{const[o,a]=P.useState(""),[l,u]=P.useState(null),[d,h]=P.useState([]),[f,g]=P.useState(!0),[y,b]=P.useState(""),[p,m]=P.useState(!1),[v,x]=P.useState(!1),w=!!e,C=i||(w?"Create Project Here":"Select"),M=P.useCallback(async O=>{g(!0),b("");try{const z=new URLSearchParams;O&&z.set("path",O),p&&z.set("showHidden","true");const X=await(await fetch(`/api/directories?${z.toString()}`)).json();X.success?(a(X.data.currentPath),u(X.data.parentPath),h(X.data.entries)):b(X.error||"Failed to load directory")}catch{b("Failed to connect to server")}finally{g(!1)}},[p]);P.useEffect(()=>{M(r)},[r,M]);const T=O=>{M(O)},A=()=>{l&&M(l)},E=()=>{M()},R=async()=>{if(w&&e){x(!0),b("");try{await e(o),t()}catch(O){b(O instanceof Error?O.message:"Failed to create project"),x(!1)}}else n&&(n(o),t())},B=O=>{O.type==="directory"&&T(O.path)},L=async O=>{if(O.type==="directory")if(w&&e){x(!0),b("");try{await e(O.path),t()}catch(z){b(z instanceof Error?z.message:"Failed to create project"),x(!1)}}else n&&(n(O.path),t())};return c.jsx("div",{className:"fixed inset-0 bg-background-dark/80 backdrop-blur-sm flex items-center justify-center p-4 z-[60]",children:c.jsxs("div",{className:"bg-surface-dark border border-border-dark rounded-xl shadow-lg w-full max-w-2xl max-h-[80vh] flex flex-col",children:[c.jsxs("div",{className:"p-4 border-b border-border-dark flex items-center justify-between",children:[c.jsx("h3",{className:"text-lg font-semibold",children:s}),c.jsx("button",{className:"text-text-secondary-dark hover:text-text-primary-dark transition-colors",onClick:t,disabled:v,children:c.jsx(Br,{className:"w-5 h-5"})})]}),c.jsxs("div",{className:"px-4 py-2 border-b border-border-dark flex items-center gap-2",children:[c.jsx("button",{className:"p-2 hover:bg-border-dark/50 rounded-lg transition-colors disabled:opacity-50",onClick:A,disabled:!l||f,title:"Go up",children:c.jsx(HF,{className:"w-4 h-4"})}),c.jsx("button",{className:"p-2 hover:bg-border-dark/50 rounded-lg transition-colors",onClick:E,disabled:f,title:"Go to home",children:c.jsx(sP,{className:"w-4 h-4"})}),c.jsx("button",{className:"p-2 hover:bg-border-dark/50 rounded-lg transition-colors",onClick:()=>M(o),disabled:f,title:"Refresh",children:c.jsx(Cu,{className:`w-4 h-4 ${f?"animate-spin":""}`})}),c.jsx("div",{className:"flex-1"}),c.jsxs("label",{className:"flex items-center gap-2 text-sm text-text-secondary-dark cursor-pointer",children:[c.jsx("input",{type:"checkbox",checked:p,onChange:O=>m(O.target.checked),className:"rounded border-border-dark"}),"Show hidden"]})]}),c.jsx("div",{className:"px-4 py-2 bg-background-dark/50 border-b border-border-dark",children:c.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[c.jsx("span",{className:"text-text-secondary-dark",children:"Path:"}),c.jsx("code",{className:"bg-background-dark px-2 py-1 rounded text-xs flex-1 overflow-x-auto whitespace-nowrap",children:o})]})}),c.jsx("div",{className:"flex-1 overflow-y-auto p-2 min-h-[300px]",children:f?c.jsx("div",{className:"flex items-center justify-center h-full",children:c.jsx("div",{className:"w-6 h-6 border-2 border-primary/20 border-t-primary rounded-full animate-spin"})}):y?c.jsx("div",{className:"flex items-center justify-center h-full text-red-400 text-sm",children:y}):d.length===0?c.jsx("div",{className:"flex items-center justify-center h-full text-text-secondary-dark text-sm",children:"Empty directory"}):c.jsx("div",{className:"space-y-1",children:d.map(O=>c.jsxs("button",{className:`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-left hover:bg-border-dark/50 transition-colors ${O.isHidden?"opacity-60":""}`,onClick:()=>B(O),onDoubleClick:()=>L(O),children:[c.jsx(nP,{className:"w-5 h-5 text-blue-400 flex-shrink-0"}),c.jsx("span",{className:"flex-1 truncate",children:O.name}),c.jsx(DC,{className:"w-4 h-4 text-text-secondary-dark"})]},O.path))})}),c.jsxs("div",{className:"p-4 border-t border-border-dark flex flex-col gap-3",children:[y&&c.jsx("p",{className:"text-red-400 text-sm",children:y}),c.jsxs("div",{className:"flex items-center justify-between",children:[c.jsxs("p",{className:"text-xs text-text-secondary-dark",children:["Double-click to ",w?"create project in":"select"," a folder"]}),c.jsxs("div",{className:"flex gap-2",children:[c.jsx("button",{className:"bg-transparent border border-border-dark text-text-primary-dark font-semibold py-2 px-4 rounded-lg hover:bg-border-dark/50 transition-colors disabled:opacity-50",onClick:t,disabled:v,children:"Cancel"}),c.jsx("button",{className:"bg-primary text-white font-semibold py-2 px-4 rounded-lg flex items-center gap-2 hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",onClick:R,disabled:v||f,children:v?c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"w-4 h-4 border-2 border-white/20 border-t-white rounded-full animate-spin"}),c.jsx("span",{children:"Creating..."})]}):c.jsxs(c.Fragment,{children:[c.jsx(XF,{className:"w-4 h-4"}),c.jsx("span",{children:C})]})})]})]})]})]})})},LH=({onSave:n,onClose:e})=>{const[t,r]=P.useState(""),[s,i]=P.useState(!1),[o,a]=P.useState(""),[l,u]=P.useState(!1),d=async g=>{if(g.preventDefault(),!t.trim()){a("Please enter a project path");return}try{i(!0),a(""),await n(t.trim())}catch(y){a(y instanceof Error?y.message:"Failed to create project")}finally{i(!1)}},h=()=>{u(!0)},f=async g=>{await n(g)};return c.jsxs("div",{className:"fixed inset-0 bg-background-dark/80 backdrop-blur-sm flex items-center justify-center p-4 z-50",children:[c.jsxs("div",{className:"bg-surface-dark border border-border-dark rounded-xl shadow-lg w-full max-w-md",children:[c.jsxs("div",{className:"p-6",children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h3",{className:"text-xl font-semibold",children:"Create New Project"}),c.jsx("button",{className:"text-text-secondary-dark hover:text-text-primary-dark transition-colors",onClick:e,disabled:s,children:c.jsx(Br,{className:"w-6 h-6"})})]}),c.jsx("form",{onSubmit:d,children:c.jsx("div",{className:"space-y-4",children:c.jsxs("div",{children:[c.jsxs("label",{className:"block text-sm font-medium text-text-secondary-dark mb-2",htmlFor:"project-path",children:["Project Path ",c.jsx("span",{className:"text-red-400",children:"*"})]}),c.jsxs("div",{className:"flex items-center gap-2",children:[c.jsx("input",{className:"w-full bg-background-dark border border-border-dark rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-primary focus:border-primary placeholder-text-secondary-dark/50",id:"project-path",placeholder:"/Users/name/my-project",type:"text",value:t,onChange:g=>r(g.target.value),disabled:s,required:!0}),c.jsxs("button",{type:"button",className:"bg-background-dark border border-border-dark text-text-secondary-dark font-semibold py-2 px-4 rounded-lg flex items-center gap-2 hover:bg-border-dark/50 hover:text-text-primary-dark transition-colors text-sm whitespace-nowrap",onClick:h,disabled:s,children:[c.jsx(Os,{className:"w-4 h-4"}),c.jsx("span",{children:"Browse"})]})]}),c.jsxs("p",{className:"text-xs text-text-secondary-dark mt-2",children:["Enter the ",c.jsx("strong",{children:"full absolute path"})," to your project directory, or use Browse to navigate to it."]}),o&&c.jsx("p",{className:"text-red-400 text-sm mt-2",children:o})]})})})]}),c.jsxs("div",{className:"bg-background-dark/50 px-6 py-4 border-t border-border-dark flex justify-end gap-3 rounded-b-xl",children:[c.jsx("button",{type:"button",className:"bg-transparent border border-border-dark text-text-primary-dark font-semibold py-2 px-4 rounded-lg hover:bg-border-dark/50 transition-colors",onClick:e,disabled:s,children:"Cancel"}),c.jsx("button",{type:"submit",className:"bg-primary text-white font-semibold py-2 px-4 rounded-lg flex items-center gap-2 hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",onClick:d,disabled:s||!t.trim(),children:s?c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"w-4 h-4 border-2 border-white/20 border-t-white rounded-full animate-spin"}),c.jsx("span",{children:"Creating..."})]}):c.jsx("span",{children:"Create Project"})})]})]}),l&&c.jsx(PH,{title:"Create New Project",onCreateProject:f,onClose:()=>u(!1)})]})},AT="/api",BH=()=>{const n=Ua(),[e,t]=ZI(),[r,s]=P.useState([]),[i,o]=P.useState(!0),[a,l]=P.useState(""),[u,d]=P.useState("all"),[h,f]=P.useState(!1),[g,y]=P.useState({}),[b,p]=P.useState({});P.useEffect(()=>{m(),e.get("create")==="true"&&(f(!0),e.delete("create"),t(e,{replace:!0}))},[]);const m=async()=>{try{o(!0);const T=await yt.get(`${AT}/projects`);if(T.data.success){const A=T.data.data||[];s(A),v(A).catch(E=>console.error("Progress calc failed:",E)),x(A).catch(E=>console.error("Teams loading failed:",E))}}catch(T){console.error("Error loading projects:",T)}finally{o(!1)}},v=async T=>{const A=await Promise.all(T.map(async E=>{try{const R=await sn.getAllTasks(E.id),B=R.length;if(B===0)return[E.id,{percent:0,active:0,total:0,open:0,inProgress:0,pending:0,done:0,blocked:0}];const L=R.filter(j=>j.status==="open").length,O=R.filter(j=>j.status==="in_progress").length,z=R.filter(j=>j.status==="pending").length,q=R.filter(j=>j.status==="done"||j.status==="completed").length,X=R.filter(j=>j.status==="blocked").length,K=L+O+z,N=Math.round(q/B*100);return[E.id,{percent:N,active:K,total:B,open:L,inProgress:O,pending:z,done:q,blocked:X}]}catch(R){return console.warn("Failed to load tasks for project",E.id,R),[E.id,{percent:0,active:0,total:0,open:0,inProgress:0,pending:0,done:0,blocked:0}]}}));y(Object.fromEntries(A))},x=async T=>{try{const A=await sn.getTeams(),E=["https://picsum.photos/seed/1/64","https://picsum.photos/seed/2/64","https://picsum.photos/seed/3/64","https://picsum.photos/seed/4/64","https://picsum.photos/seed/5/64","https://picsum.photos/seed/6/64"],R=A.map(L=>({...L,members:L.members.map((O,z)=>({...O,avatar:O.avatar||E[z%E.length]}))})),B=T.map(L=>{const O=R.filter(z=>{var K,N;const q=(K=z.projectIds)==null?void 0:K.includes(L.id),X=(N=z.projectIds)==null?void 0:N.includes(L.name);return q||X});return[L.id,O]});p(Object.fromEntries(B))}catch(A){console.error("Failed to load teams for projects:",A)}},w=async T=>{try{const A=await yt.post(`${AT}/projects`,{path:T});A.data.success&&A.data.data&&(s(E=>[A.data.data,...E]),f(!1),n(`/projects/${A.data.data.id}`))}catch(A){throw console.error("Error creating project:",A),A}},C=T=>{n(`/projects/${T}`)},M=r.filter(T=>{const A=T.name.toLowerCase().includes(a.toLowerCase())||T.path.toLowerCase().includes(a.toLowerCase()),E=u==="all"||T.status===u;return A&&E});return i?c.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:c.jsxs("div",{className:"text-center",children:[c.jsx("div",{className:"w-12 h-12 border-4 border-primary/20 border-t-primary rounded-full animate-spin mb-4 mx-auto"}),c.jsx("p",{className:"text-text-secondary-dark",children:"Loading projects..."})]})}):c.jsxs("div",{className:"max-w-7xl mx-auto",children:[c.jsxs("div",{className:"flex flex-col md:flex-row items-start md:items-center justify-between gap-4 mb-8",children:[c.jsxs("div",{children:[c.jsx("h2",{className:"text-3xl font-bold tracking-tight",children:"Projects"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mt-1",children:"Manage and monitor your Crewly projects"})]}),c.jsxs("button",{className:"bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors flex items-center gap-2",onClick:()=>f(!0),children:[c.jsx(Ps,{className:"w-5 h-5"}),"New Project"]})]}),c.jsxs("div",{className:"flex flex-col md:flex-row items-center justify-between gap-4 mb-6",children:[c.jsxs("div",{className:"relative w-full md:w-auto md:flex-grow max-w-md",children:[c.jsx(UC,{className:"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary-dark w-5 h-5"}),c.jsx("input",{type:"text",placeholder:"Search projects...",value:a,onChange:T=>l(T.target.value),className:"w-full bg-surface-dark border border-border-dark rounded-lg pl-10 pr-4 py-2.5 text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors"})]}),c.jsx("div",{className:"flex items-center gap-4",children:c.jsxs("select",{value:u,onChange:T=>d(T.target.value),className:"bg-surface-dark border border-border-dark rounded-lg px-4 py-2.5 text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors",children:[c.jsx("option",{value:"all",children:"All Status"}),c.jsx("option",{value:"active",children:"Active"}),c.jsx("option",{value:"paused",children:"Paused"}),c.jsx("option",{value:"completed",children:"Completed"})]})})]}),c.jsx("div",{children:M.length>0?c.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:[M.map(T=>{var A,E,R,B;return c.jsx(_L,{project:T,showStatus:!0,showTeams:!0,assignedTeams:b[T.id]||[],onClick:()=>C(T.id),progressPercent:(A=g[T.id])==null?void 0:A.percent,progressLabel:typeof((E=g[T.id])==null?void 0:E.total)=="number"?`${((R=g[T.id])==null?void 0:R.done)||0} of ${((B=g[T.id])==null?void 0:B.total)||0} completed`:void 0,progressBreakdown:g[T.id]?{open:g[T.id].open,inProgress:g[T.id].inProgress,pending:g[T.id].pending,done:g[T.id].done,blocked:g[T.id].blocked,total:g[T.id].total}:void 0},T.id)}),c.jsx(pw,{title:"New Project",onClick:()=>f(!0)})]}):c.jsxs("div",{className:"text-center py-16",children:[c.jsx("div",{className:"flex justify-center mb-4",children:c.jsx(nP,{className:"w-12 h-12 text-text-secondary-dark/50",strokeWidth:1.5})}),c.jsx("h3",{className:"text-lg font-semibold mb-2",children:a||u!=="all"?"No projects found":"No projects yet"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mb-6",children:a||u!=="all"?"Try adjusting your search or filter criteria":"Create your first project to get started with Crewly"}),!a&&u==="all"&&c.jsxs("button",{className:"bg-primary text-white px-6 py-3 rounded-lg hover:bg-primary/90 transition-colors inline-flex items-center gap-2",onClick:()=>f(!0),children:[c.jsx(Ps,{className:"w-5 h-5"}),"Create Project"]})]})}),h&&c.jsx(LH,{onSave:w,onClose:()=>f(!1)})]})},jH=({project:n,onClose:e,onAssignmentComplete:t})=>{const[r,s]=P.useState([]),[i,o]=P.useState(new Set),[a,l]=P.useState(!0),[u,d]=P.useState(!1),[h,f]=P.useState(null);P.useEffect(()=>{g()},[]);const g=async()=>{try{l(!0);const v=await sn.getTeams();s(v);const x=new Set(v.filter(w=>{var C;return(C=w.projectIds)==null?void 0:C.includes(n.id)}).map(w=>w.id));o(x)}catch(v){f("Failed to load teams"),console.error("Error loading teams:",v)}finally{l(!1)}},y=v=>{const x=new Set(i);x.has(v)?x.delete(v):x.add(v),o(x)},b=async()=>{try{d(!0),f(null),await sn.assignTeamsToProject(n.id,Array.from(i)),t(),e()}catch(v){f(v instanceof Error?v.message:"Failed to assign teams"),console.error("Error assigning teams:",v)}finally{d(!1)}},p=v=>{v.target===v.currentTarget&&e()},m=v=>({orchestrator:"#8b5cf6",pm:"#3b82f6",developer:"#10b981",qa:"#f59e0b",tester:"#ef4444",designer:"#ec4899"})[v]||"#6b7280";return c.jsx("div",{className:"modal-overlay",onClick:p,children:c.jsxs("div",{className:"modal-content team-assignment-modal",children:[c.jsxs("div",{className:"modal-header",children:[c.jsxs("div",{className:"modal-title",children:[c.jsx(si,{className:"title-icon"}),c.jsxs("div",{children:[c.jsx("h2",{children:"Assign Teams"}),c.jsxs("p",{children:['Select teams to assign to "',n.name,'"']})]})]}),c.jsx("button",{className:"close-button",onClick:e,children:c.jsx(Br,{size:20})})]}),c.jsx("div",{className:"modal-body",children:a?c.jsxs("div",{className:"loading-state",children:[c.jsx("div",{className:"loading-spinner"}),c.jsx("p",{children:"Loading teams..."})]}):h?c.jsxs("div",{className:"error-state",children:[c.jsxs("p",{children:["Error: ",h]}),c.jsx(wt,{onClick:g,className:"retry-button",variant:"outline",size:"sm",children:"Retry"})]}):r.length===0?c.jsxs("div",{className:"empty-state",children:[c.jsx(si,{size:48}),c.jsx("h3",{children:"No Teams Available"}),c.jsx("p",{children:"Create some teams first before assigning them to projects."})]}):c.jsxs("div",{className:"teams-selection",children:[c.jsxs("div",{className:"selection-header",children:[c.jsxs("h3",{children:["Available Teams (",r.length,")"]}),c.jsxs("p",{children:["Selected: ",i.size," team",i.size!==1?"s":""]})]}),c.jsx("div",{className:"teams-grid",children:r.map(v=>{var C,M,T;const x=i.has(v.id),w=(C=v.projectIds)==null?void 0:C.includes(n.id);return c.jsxs("div",{className:`team-selection-card ${x?"selected":""}`,onClick:()=>y(v.id),children:[x&&c.jsx("div",{className:"selection-indicator",children:c.jsx(La,{size:16})}),c.jsxs("div",{className:"team-card-header",children:[c.jsxs("div",{className:"team-info",children:[c.jsx("h4",{className:"team-name",children:v.name}),v.description&&c.jsx("p",{className:"team-description",children:v.description})]}),c.jsx("div",{className:"team-meta",children:c.jsx("span",{className:"team-meta-info",children:new Date(v.updatedAt).toLocaleDateString()})})]}),c.jsxs("div",{className:"team-members-summary",children:[c.jsxs("div",{className:"members-count",children:[c.jsx(si,{size:14}),c.jsxs("span",{children:[((M=v.members)==null?void 0:M.length)||0," member",(((T=v.members)==null?void 0:T.length)||0)!==1?"s":""]})]}),v.members&&v.members.length>0&&c.jsxs("div",{className:"member-roles",children:[v.members.slice(0,3).map((A,E)=>c.jsx("span",{className:"role-badge",style:{color:m(A.role)},children:A.role},E)),v.members.length>3&&c.jsxs("span",{className:"more-roles",children:["+",v.members.length-3," more"]})]})]}),w&&c.jsx("div",{className:"assignment-status current-project",children:"Currently assigned to this project"})]},v.id)})})]})}),c.jsxs("div",{className:"modal-footer",children:[c.jsx(wt,{className:"secondary-button",onClick:e,disabled:u,variant:"secondary",children:"Cancel"}),c.jsxs(wt,{className:"primary-button",onClick:b,disabled:u||r.length===0,loading:u,icon:La,children:["Assign ",i.size," Team",i.size!==1?"s":""]})]})]})})},MT={in_progress:{icon:Ha,color:"text-primary",label:"In Progress"},open:{icon:Yb,color:"text-text-secondary-dark",label:"Open"},pending:{icon:Yb,color:"text-text-secondary-dark",label:"Open"},done:{icon:Bl,color:"text-green-400",label:"Done"},completed:{icon:Bl,color:"text-green-400",label:"Done"},blocked:{icon:sh,color:"text-red-400",label:"Blocked"}},ET={high:{color:"text-red-400",label:"High"},critical:{color:"text-red-500",label:"Critical"},medium:{color:"text-yellow-400",label:"Medium"},low:{color:"text-green-400",label:"Low"}},DH=({isOpen:n,onClose:e,task:t,onEdit:r,onAssign:s,taskAssignmentLoading:i})=>{var u;if(!n||!t)return null;const o=MT[t.status]||MT.open,a=ET[t.priority]||ET.medium,l=o.icon;return c.jsx("div",{className:"fixed inset-0 bg-black/60 z-50 flex items-center justify-center p-4",onClick:e,children:c.jsxs("div",{className:"bg-surface-dark w-full max-w-4xl rounded-xl shadow-2xl flex flex-col h-[90vh]",onClick:d=>d.stopPropagation(),children:[c.jsxs("div",{className:"flex items-center justify-between p-6 border-b border-border-dark flex-shrink-0",children:[c.jsxs("div",{className:"flex items-center gap-4",children:[c.jsx("span",{className:"bg-primary/10 text-primary p-2 rounded-lg",children:c.jsx(l,{className:"w-5 h-5"})}),c.jsxs("div",{children:[c.jsx("h3",{className:"text-xl font-bold",children:t.title}),c.jsxs("p",{className:"text-sm text-text-secondary-dark",children:["In ",c.jsx("span",{className:"text-primary",children:"Crewly Project"})]})]})]}),c.jsxs("div",{className:"flex items-center gap-2",children:[c.jsx(wt,{variant:"ghost",size:"icon",className:"w-8 h-8",children:c.jsx(ZF,{className:"w-4 h-4"})}),c.jsx(wt,{variant:"ghost",size:"icon",onClick:e,className:"w-8 h-8",children:c.jsx(Br,{className:"w-4 h-4"})})]})]}),c.jsxs("div",{className:"flex-grow p-6 overflow-y-auto",children:[c.jsxs("div",{className:"flex items-center justify-between mb-6",children:[c.jsxs("div",{className:"flex items-center gap-6",children:[c.jsxs("div",{children:[c.jsx("label",{className:"text-xs font-semibold text-text-secondary-dark uppercase tracking-wider",children:"Status"}),c.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[c.jsx(l,{className:`${o.color} w-5 h-5`}),c.jsx("p",{className:"text-sm font-medium",children:o.label})]})]}),c.jsxs("div",{children:[c.jsx("label",{className:"text-xs font-semibold text-text-secondary-dark uppercase tracking-wider",children:"Priority"}),c.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[c.jsx("div",{className:`w-3 h-3 rounded-full ${a.color.replace("text-","bg-")}`}),c.jsx("p",{className:"text-sm font-medium",children:a.label})]})]}),c.jsxs("div",{children:[c.jsx("label",{className:"text-xs font-semibold text-text-secondary-dark uppercase tracking-wider",children:"Milestone"}),c.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[c.jsx("div",{className:"w-3 h-3 rounded bg-primary/80"}),c.jsx("p",{className:"text-sm font-medium",children:((u=t.milestoneId)==null?void 0:u.replace(/_/g," ").replace(/^m\d+\s*/,""))||t.milestone||"General"})]})]})]}),c.jsxs("div",{className:"flex items-center gap-2",children:[r&&c.jsx(wt,{variant:"secondary",size:"sm",icon:lP,onClick:()=>r(t),children:"Edit"}),s&&t.status!=="done"&&t.status!=="completed"&&c.jsx(wt,{variant:"primary",size:"sm",onClick:()=>s(t),loading:i===t.id,disabled:i===t.id,children:i===t.id?"Starting...":"Start Task"})]})]}),c.jsxs("div",{className:"mb-6",children:[c.jsx("h4",{className:"text-lg font-semibold mb-4",children:"Description"}),c.jsx("div",{className:"text-text-secondary-dark leading-relaxed prose prose-invert max-w-none text-sm",children:t.description?c.jsx("div",{children:t.description.split(`
|
|
98
|
+
`)),M.current=null},1e4)},te=async()=>{var ee;try{const pe=await fetch("/api/terminal/sessions");if(!pe.ok){l(!0);return}const Z=await pe.json(),be=Z.success&&((ee=Z.data)!=null&&ee.sessions)?Z.data.sessions:[];if(Array.isArray(be)){const re=be.map(le=>({id:le,name:le,displayName:le==="crewly-orc"?"Orchestrator":le.replace("crewly-",""),type:le==="crewly-orc"?"orchestrator":"team_member"}));re.sort((le,fe)=>le.type==="orchestrator"?-1:fe.type==="orchestrator"?1:le.displayName.localeCompare(fe.displayName)),o(re),!re.some(le=>le.id===r)&&re.length>0&&s(re[0].id)}else o([]);l(!0)}catch{l(!0)}},ue=()=>{y(null),ie()};return P.useEffect(()=>{n&&m.current&&m.current.focus()},[n,x]),c.jsxs("div",{ref:p,className:`fixed top-0 right-0 h-full bg-surface-dark border-l border-border-dark flex flex-col z-50 transition-transform duration-300 ${n?"translate-x-0":"translate-x-full"} w-full sm:w-[600px]`,children:[c.jsxs("div",{className:"flex items-center justify-between p-3 sm:p-4 border-b border-border-dark",children:[c.jsxs("div",{className:"flex items-center space-x-2 sm:space-x-3 min-w-0",children:[c.jsx(Ox,{className:"w-5 h-5 text-text-secondary-dark shrink-0"}),c.jsx("span",{className:"font-medium text-text-primary-dark truncate",children:"Terminal"}),c.jsxs("div",{className:"flex items-center space-x-1.5 shrink-0",children:[c.jsx("div",{className:`w-2 h-2 rounded-full ${h==="connected"?"bg-green-400":h==="connecting"||h==="reconnecting"?"bg-yellow-400":h==="error"?"bg-red-400":"bg-gray-400"}`}),c.jsx("span",{className:"text-xs sm:text-sm text-text-secondary-dark",children:h==="connected"?"Live":h==="connecting"?"Connecting...":h==="reconnecting"?"Reconnecting...":h==="error"?"Error":"Disconnected"})]})]}),c.jsx("button",{onClick:e,className:"p-1 text-text-secondary-dark hover:text-text-primary-dark hover:bg-background-dark rounded transition-colors shrink-0","aria-label":"Close Terminal",children:c.jsx(Br,{className:"w-5 h-5"})})]}),c.jsx("div",{className:"px-3 sm:px-4 py-2 sm:py-3 border-b border-border-dark",children:c.jsxs("div",{className:"flex items-center space-x-2 sm:space-x-3",children:[c.jsx("label",{htmlFor:"session-select",className:"text-xs sm:text-sm font-medium text-text-secondary-dark shrink-0",children:"Session:"}),c.jsx("select",{id:"session-select",value:r,onChange:ee=>s(ee.target.value),className:"flex-1 min-w-0 px-2 sm:px-3 py-1 bg-background-dark border border-border-dark rounded text-xs sm:text-sm text-text-primary-dark focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent disabled:opacity-50",disabled:h!=="connected",children:i.map(ee=>c.jsx("option",{value:ee.id,children:ee.displayName},ee.id))})]})}),c.jsxs("div",{className:"flex-1 flex flex-col",children:[g&&c.jsxs("div",{className:"mx-4 my-2 px-4 py-3 bg-red-500/10 border-l-4 border-red-500 text-red-400 flex items-center space-x-2",children:[c.jsx(sh,{className:"w-4 h-4 flex-shrink-0"}),c.jsx("span",{className:"flex-1 text-sm",children:g}),c.jsx(wt,{onClick:ue,variant:"ghost",size:"sm",className:"text-red-400 hover:text-red-300",children:"Retry"})]}),c.jsx("div",{className:"flex-1 overflow-hidden",children:a&&i.length===0?c.jsxs("div",{className:"h-full flex flex-col items-center justify-center p-8 text-center",children:[c.jsx("div",{className:"w-16 h-16 rounded-full bg-surface-dark border border-border-dark flex items-center justify-center mb-4",children:c.jsx(Ox,{className:"w-8 h-8 text-text-secondary-dark"})}),c.jsx("h3",{className:"text-lg font-medium text-text-primary-dark mb-2",children:"No Terminal Sessions Available"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mb-6 max-w-sm",children:"The orchestrator is not running. Start the orchestrator to enable terminal sessions for your agents."}),c.jsxs(wt,{onClick:()=>{e(),t("/teams/orchestrator")},variant:"primary",size:"default",className:"flex items-center space-x-2",children:[c.jsx(jl,{className:"w-4 h-4"}),c.jsx("span",{children:"Go to Orchestrator"})]})]}):c.jsx("div",{ref:b,className:"h-full w-full bg-background-dark",style:{minHeight:"100%"}})}),u&&h==="connected"&&c.jsx("div",{className:"px-4 py-2 border-t border-border-dark",children:c.jsxs("div",{className:"flex items-center space-x-2 text-sm text-text-secondary-dark",children:[c.jsx("div",{className:"w-3 h-3 border-2 border-primary border-t-transparent rounded-full animate-spin"}),c.jsx("span",{children:"Loading terminal output..."})]})})]})]})},xH="/api/orchestrator/status",vH=5e3;function yL(){const[n,e]=P.useState(null),[t,r]=P.useState(!0),[s,i]=P.useState(null),o=P.useRef(!0),a=P.useRef(null),l=P.useCallback(async()=>{a.current&&a.current.abort();const d=new AbortController;a.current=d;try{const h=await yt.get(xH,{signal:d.signal,timeout:vH});if(!o.current)return;h.data.success&&h.data.data?(e(h.data.data),i(null)):i(h.data.error||"Failed to get orchestrator status")}catch(h){if(yt.isCancel(h)||!o.current)return;const f=h instanceof Error?h.message:"Unable to check orchestrator status";i(f),e({isActive:!1,agentStatus:null,message:"Unable to check orchestrator status",offlineMessage:"The orchestrator is currently offline. Please start it from the Dashboard."})}finally{o.current&&r(!1)}},[]),u=P.useCallback(async()=>{r(!0),await l()},[l]);return P.useEffect(()=>(o.current=!0,l(),()=>{o.current=!1,a.current&&a.current.abort()}),[l]),P.useEffect(()=>{const d=f=>{if(!o.current)return;const g=f.agentStatus??f.status??(f.running===!0?"active":f.running===!1?"inactive":void 0),y=g==="active";e({isActive:y,agentStatus:g||null,message:y?"Orchestrator is active and ready.":g==="starting"||g==="started"?"Orchestrator is starting up. Please wait a moment and try again.":"Orchestrator is not running. Please start the orchestrator from the Dashboard.",offlineMessage:y?null:"The orchestrator is currently offline. Please start it from the Crewly dashboard."}),r(!1),i(null)},h=()=>{o.current&&l()};return ut.on("orchestrator_status_changed",d),ut.on("connected",h),()=>{ut.off("orchestrator_status_changed",d),ut.off("connected",h)}},[l]),{status:n,isLoading:t,error:s,refresh:u}}const yH=()=>{const{status:n,isLoading:e,refresh:t}=yL(),[r,s]=P.useState(!1),[i,o]=P.useState(!1),a=async()=>{o(!0),await t(),setTimeout(()=>o(!1),500)},l=(n==null?void 0:n.isActive)??!0,u=n==null?void 0:n.agentStatus;if(e||l||!n||r)return null;const d=u==="activating"||u==="starting"||u==="started",h=d?"bg-yellow-500/10 border-yellow-500/30":"bg-rose-500/10 border-rose-500/30",f=d?"text-yellow-400":"text-rose-400",g=d?"text-yellow-300":"text-rose-300",y=d?"text-yellow-200/80":"text-rose-200/80";return c.jsxs("div",{className:`flex items-center justify-between px-4 py-2.5 border-b ${h}`,children:[c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(Ep,{className:`shrink-0 ${f}`,size:18}),c.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[c.jsx("span",{className:`font-semibold ${g}`,children:d?"Orchestrator Initializing":"Orchestrator Not Running"}),c.jsx("span",{className:y,children:d?"The Crewly orchestrator is starting up. This may take a few moments...":"The Crewly orchestrator is not running. Check the application logs for issues."})]})]}),c.jsxs("div",{className:"flex items-center gap-1",children:[c.jsx(Ci,{icon:Cu,onClick:a,variant:"ghost",size:"sm",className:i?"animate-spin":"","aria-label":"Refresh status"}),c.jsx(Ci,{icon:Br,onClick:()=>s(!0),variant:"ghost",size:"sm","aria-label":"Dismiss banner"})]})]})},_H="/health",SH=5e3;function bH(){const[n,e]=P.useState(null),[t,r]=P.useState(!0),s=P.useRef(!0);return P.useEffect(()=>(s.current=!0,(async()=>{try{const o=await yt.get(_H,{timeout:SH});if(!s.current)return;e({currentVersion:o.data.version,latestVersion:o.data.latestVersion,updateAvailable:o.data.updateAvailable})}catch{}finally{s.current&&r(!1)}})(),()=>{s.current=!1}),[]),{versionInfo:n,isLoading:t}}const wH=()=>{const{versionInfo:n,isLoading:e}=bH(),[t,r]=P.useState(!1);return e||!(n!=null&&n.updateAvailable)||t?null:c.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 border-b bg-cyan-500/10 border-cyan-500/30",children:[c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(DF,{className:"shrink-0 text-cyan-400",size:18}),c.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[c.jsx("span",{className:"font-semibold text-cyan-300",children:"Update Available"}),c.jsxs("span",{className:"text-cyan-200/80",children:["Crewly v",n.latestVersion," is available (current: v",n.currentVersion,"). Run ",c.jsx("code",{className:"bg-cyan-500/20 px-1.5 py-0.5 rounded text-cyan-300",children:"crewly upgrade"})," to update."]})]})]}),c.jsx(Ci,{icon:Br,onClick:()=>r(!0),variant:"ghost",size:"sm","aria-label":"Dismiss update banner"})]})},xn="/api",CH=2*60*1e3;class AH{constructor(){Vs(this,"teamsCache",null);Vs(this,"teamsCachePromise",null)}async getProjects(){return(await yt.get(`${xn}/projects`)).data.data||[]}async getProject(e){const t=await yt.get(`${xn}/projects/${e}`);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Project not found");return t.data.data}async createProject(e,t,r){const s=await yt.post(`${xn}/projects`,{path:e,name:t,description:r});if(!s.data.success||!s.data.data)throw new Error(s.data.error||"Failed to create project");return s.data.data}async startProject(e,t){const r=await yt.post(`${xn}/projects/${e}/start`,{teamIds:t});if(!r.data.success)throw new Error(r.data.error||"Failed to start project");return{message:r.data.message||"Project started successfully"}}async assignTeamsToProject(e,t){const r=await this.getTeams(),s={};t.forEach(o=>{const a=r.find(l=>l.id===o);if(a&&a.members.length>0){const l=a.members[0].role;s[l]||(s[l]=[]),s[l].push(o)}});const i=await yt.post(`${xn}/projects/${e}/assign-teams`,{teamAssignments:s});if(!i.data.success)throw new Error(i.data.error||"Failed to assign teams")}async getTeams(e=!1){return!e&&this.teamsCache&&Date.now()-this.teamsCache.timestamp<CH?this.teamsCache.data:this.teamsCachePromise?this.teamsCachePromise:(this.teamsCachePromise=(async()=>{try{const r=(await yt.get(`${xn}/teams`,{timeout:15e3})).data.data||[];return this.teamsCache={data:r,timestamp:Date.now()},r}finally{this.teamsCachePromise=null}})(),this.teamsCachePromise)}invalidateTeamsCache(){this.teamsCache=null}async getTeam(e){const t=await yt.get(`${xn}/teams/${e}`);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Team not found");return t.data.data}async createTeam(e){const t=await yt.post(`${xn}/teams`,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to create team");return this.invalidateTeamsCache(),t.data.data}async deleteTeam(e){const t=await yt.delete(`${xn}/teams/${e}`);if(!t.data.success)throw new Error(t.data.error||"Failed to delete team");this.invalidateTeamsCache()}async unassignTeamFromProject(e,t){const r=await yt.post(`${xn}/projects/${e}/unassign-team`,{teamId:t});if(!r.data.success)throw new Error(r.data.error||"Failed to unassign team")}async startTeam(e){await yt.post(`${xn}/teams/${e}/start`,{})}async getProjectTickets(e){return(await yt.get(`${xn}/projects/${e}/tickets`)).data.data||[]}async createTicket(e,t){const r=await yt.post(`${xn}/projects/${e}/tickets`,t);if(!r.data.success||!r.data.data)throw new Error(r.data.error||"Failed to create ticket");return r.data.data}async updateTicket(e,t){const r=await yt.patch(`${xn}/tickets/${e}`,t);if(!r.data.success||!r.data.data)throw new Error(r.data.error||"Failed to update ticket");return r.data.data}async deleteTicket(e,t){const r=await yt.delete(`${xn}/projects/${e}/tickets/${t}`);if(!r.data.success)throw new Error(r.data.error||"Failed to delete ticket")}async getPreviousSessions(){return(await yt.get(`${xn}/sessions/previous`)).data.data||{sessions:[]}}async dismissPreviousSessions(){await yt.post(`${xn}/sessions/previous/dismiss`)}async getAllTasks(e){return(await yt.get(`${xn}/projects/${e}/tasks`)).data.data||[]}async getMilestones(e){return(await yt.get(`${xn}/projects/${e}/milestones`)).data.data||[]}async getTasksByStatus(e,t){return(await yt.get(`${xn}/projects/${e}/tasks/status/${t}`)).data.data||[]}async getTasksByMilestone(e,t){return(await yt.get(`${xn}/projects/${e}/tasks/milestone/${t}`)).data.data||[]}async getTeamsBackupStatus(){const e=await yt.get(`${xn}/teams/backup/status`);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to get backup status");return e.data.data}async restoreTeamsFromBackup(){const e=await yt.post(`${xn}/teams/backup/restore`);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to restore from backup");return e.data.data}async getQueueStatus(){const e=await yt.get(`${xn}/messaging/queue/status`);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to get queue status");return e.data.data}async getPendingMessages(){return(await yt.get(`${xn}/messaging/queue/messages`)).data.data||[]}async cancelQueueMessage(e){const t=await yt.delete(`${xn}/messaging/queue/messages/${e}`);if(!t.data.success)throw new Error(t.data.error||"Failed to cancel message")}async clearQueue(){const e=await yt.delete(`${xn}/messaging/queue`);if(!e.data.success)throw new Error(e.data.error||"Failed to clear queue")}async getKnowledgeDocuments(e="global",t,r,s){const i={scope:e};return t&&(i.projectPath=t),r&&(i.category=r),s&&(i.search=s),(await yt.get(`${xn}/knowledge/documents`,{params:i})).data.data||[]}async getKnowledgeDocument(e,t="global",r){const s={scope:t};r&&(s.projectPath=r);const i=await yt.get(`${xn}/knowledge/documents/${e}`,{params:s});if(!i.data.success||!i.data.data)throw new Error(i.data.error||"Document not found");return i.data.data}async createKnowledgeDocument(e){const t=await yt.post(`${xn}/knowledge/documents`,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to create document");return t.data.data.id}async updateKnowledgeDocument(e,t){const r=await yt.put(`${xn}/knowledge/documents/${e}`,t);if(!r.data.success)throw new Error(r.data.error||"Failed to update document")}async deleteKnowledgeDocument(e,t="global",r){const s={scope:t};r&&(s.projectPath=r);const i=await yt.delete(`${xn}/knowledge/documents/${e}`,{params:s});if(!i.data.success)throw new Error(i.data.error||"Failed to delete document")}async getKnowledgeCategories(e="global",t){const r={scope:e};return t&&(r.projectPath=t),(await yt.get(`${xn}/knowledge/categories`,{params:r})).data.data||[]}}const sn=new AH,gc="/api/settings";class MH{async getSettings(){const e=await yt.get(gc);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to get settings");return e.data.data}async updateSettings(e){const t=await yt.put(gc,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to update settings");return t.data.data}async validateSettings(e){const t=await yt.post(`${gc}/validate`,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to validate settings");return t.data.data}async resetSettings(){const e=await yt.post(`${gc}/reset`);if(!e.data.success||!e.data.data)throw new Error(e.data.error||"Failed to reset settings");return e.data.data}async resetSection(e){const t=await yt.post(`${gc}/reset/${e}`);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to reset section");return t.data.data}async exportSettings(){return(await yt.post(`${gc}/export`)).data}async importSettings(e){const t=await yt.post(`${gc}/import`,e);if(!t.data.success||!t.data.data)throw new Error(t.data.error||"Failed to import settings");return t.data.data}}const Of=new MH,EH=()=>{const[n,e]=P.useState([]),[t,r]=P.useState(!1),[s,i]=P.useState(!1),[o,a]=P.useState(null),l=P.useRef(!1);P.useEffect(()=>{let y=!1;return(async()=>{var p;try{const[m,v]=await Promise.all([sn.getPreviousSessions(),Of.getSettings().catch(()=>null)]),x=m.sessions.filter(C=>C.role!=="orchestrator");if(y||x.length===0)return;if(e(x),(((p=v==null?void 0:v.general)==null?void 0:p.autoResumeOnRestart)??!0)&&!l.current){l.current=!0;const C=new Set;for(const M of x)M.teamId&&M.role!=="orchestrator"&&C.add(M.teamId);for(const M of C)try{await sn.startTeam(M)}catch{}try{await sn.dismissPreviousSessions()}catch{}return}r(!0)}catch{}})(),()=>{y=!0}},[]);const u=P.useMemo(()=>{const y=new Set;for(const b of n)b.teamId&&b.role!=="orchestrator"&&y.add(b.teamId);return Array.from(y)},[n]),d=u.length>0,h=P.useCallback(async()=>{i(!0);try{await sn.dismissPreviousSessions()}catch{}r(!1),i(!1)},[]),f=P.useCallback(async()=>{i(!0),a(null);const y=[];for(const b of u)try{await sn.startTeam(b)}catch{y.push(b)}if(y.length===0){try{await sn.dismissPreviousSessions()}catch{}r(!1)}else a(`Failed to start ${y.length} team(s). You can start them manually from the Teams page.`);i(!1)},[u]);if(!t)return null;const g=c.jsxs(c.Fragment,{children:[c.jsx(wt,{variant:"secondary",onClick:h,disabled:s,children:"Dismiss"}),c.jsx(wt,{variant:"primary",icon:jl,onClick:f,disabled:s||!d,children:"Resume All"})]});return c.jsxs(Qp,{isOpen:t,onClose:h,title:"Previous Sessions Detected",subtitle:"The following agents were running before the app restarted.",size:"lg",footer:g,loading:s,children:[c.jsx("div",{className:"space-y-2",children:n.map(y=>c.jsxs("div",{className:"flex items-center justify-between p-3 rounded-lg bg-background-dark border border-border-dark",children:[c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(oP,{className:"w-4 h-4 text-text-secondary-dark"}),c.jsxs("div",{children:[c.jsx("div",{className:"text-sm font-medium",children:y.name}),y.role&&c.jsx("div",{className:"text-xs text-text-secondary-dark",children:y.role})]})]}),c.jsxs("div",{className:"flex items-center gap-2",children:[c.jsx(Qb,{variant:y.hasResumeId?"success":"default",size:"sm",children:y.hasResumeId?"Resumable":"Restart"}),c.jsx(Qb,{variant:"default",size:"sm",children:y.runtimeType})]})]},y.name))}),o&&c.jsx("p",{className:"mt-3 text-xs text-rose-400",children:o}),c.jsx("p",{className:"mt-4 text-xs text-text-secondary-dark",children:'Click "Resume All" to restart all teams, or dismiss to start them manually from the Teams page.'})]})},TH=()=>{const[n,e]=P.useState(null),[t,r]=P.useState(!1),[s,i]=P.useState(!1),[o,a]=P.useState(null);P.useEffect(()=>{let f=!1;return(async()=>{try{const y=await sn.getTeamsBackupStatus();!f&&y.hasMismatch&&(e(y),r(!0))}catch{}})(),()=>{f=!0}},[]);const l=P.useCallback(()=>{r(!1)},[]),u=P.useCallback(async()=>{i(!0),a(null);try{const f=await sn.restoreTeamsFromBackup();f.errors&&f.errors.length>0?(a(`Restored ${f.restoredCount} of ${f.totalInBackup} teams. Some teams failed to restore.`),i(!1)):(r(!1),window.location.reload())}catch(f){a(f instanceof Error?f.message:"Failed to restore teams from backup"),i(!1)}},[]);if(!t||!n)return null;const d=n.backupTimestamp?new Date(n.backupTimestamp).toLocaleString():"unknown",h=c.jsxs(c.Fragment,{children:[c.jsx(wt,{variant:"secondary",onClick:l,disabled:s,children:"Dismiss"}),c.jsx(wt,{variant:"primary",icon:cP,onClick:u,disabled:s,children:"Restore"})]});return c.jsxs(Qp,{isOpen:t,onClose:l,title:"Teams Data Missing",subtitle:"A backup of your teams data is available.",size:"md",footer:h,loading:s,children:[c.jsxs("div",{className:"space-y-3",children:[c.jsxs("p",{className:"text-sm text-text-primary-dark",children:["Your teams data appears to be missing. A backup with"," ",c.jsxs("span",{className:"font-semibold",children:[n.backupTeamCount," team",n.backupTeamCount!==1?"s":""]})," ","from ",c.jsx("span",{className:"font-semibold",children:d})," is available."]}),c.jsx("p",{className:"text-xs text-text-secondary-dark",children:'Click "Restore" to recover your teams, or "Dismiss" to start fresh.'})]}),o&&c.jsx("p",{className:"mt-3 text-xs text-rose-400",children:o})]})},kH=()=>{const{isTerminalOpen:n,openTerminal:e,closeTerminal:t}=rm(),{isCollapsed:r}=zC(),[s,i]=P.useState(!1),o=()=>{n?t():e()};return c.jsxs("div",{className:"flex h-screen overflow-hidden bg-background-dark",children:[c.jsx(EH,{}),c.jsx(TH,{}),c.jsx("div",{className:`fixed inset-0 bg-black/60 z-40 md:hidden transition-opacity ${s?"opacity-100":"opacity-0 pointer-events-none"}`,onClick:()=>i(!1),"aria-hidden":"true"}),c.jsx("div",{className:fs("fixed left-0 top-0 h-full z-50 transition-all duration-300 ease-in-out","md:translate-x-0",s?"translate-x-0":"-translate-x-full",r?"md:w-16":"md:w-64","w-64"),children:c.jsx(x8,{isMobileOpen:s,onMobileClose:()=>i(!1)})}),c.jsxs("div",{className:fs("flex-1 flex flex-col min-w-0 transition-all duration-300 ease-in-out",r?"md:ml-16":"md:ml-64"),children:[c.jsxs("header",{className:"md:hidden h-16 flex items-center justify-between px-4 bg-surface-dark/80 backdrop-blur-sm border-b border-border-dark sticky top-0 z-30",children:[c.jsx(Ci,{variant:"ghost",icon:YF,onClick:()=>i(!0),"aria-label":"Open menu"}),c.jsx("h1",{className:"text-lg font-bold",children:"Crewly"}),c.jsx("div",{className:"w-10 h-10"})," "]}),c.jsxs("main",{className:"flex-1 flex flex-col min-h-0 overflow-hidden",children:[c.jsx(wH,{}),c.jsx(yH,{}),c.jsx("div",{className:"flex-1 p-4 md:p-6 min-h-0 overflow-y-auto",children:c.jsx(gF,{})})]})]}),c.jsx(Ci,{className:`fixed bottom-6 right-6 z-40 ${n?"bg-primary/90":""}`,icon:Ox,onClick:o,variant:"primary","aria-label":n?"Close Terminal":"Open Terminal"}),c.jsxs(c.Fragment,{children:[n&&c.jsx("div",{className:"fixed inset-0 bg-black/50 z-30",onClick:t}),c.jsx(gH,{isOpen:n,onClose:t})]})]})},CT={active:{bg:"bg-green-500/10",text:"text-green-400",label:"Running"},paused:{bg:"bg-yellow-500/10",text:"text-yellow-400",label:"Stopped"},completed:{bg:"bg-blue-500/10",text:"text-blue-400",label:"Completed"},blocked:{bg:"bg-red-500/10",text:"text-red-400",label:"Blocked"},stopped:{bg:"bg-gray-500/10",text:"text-gray-400",label:"Stopped"}},_L=({project:n,showStatus:e=!1,showTeams:t=!1,assignedTeams:r=[],onClick:s,progressPercent:i,progressLabel:o,progressBreakdown:a})=>{r.length||Object.values(n.teams||{}).flat().length;const l=new Date(n.updatedAt).toLocaleDateString(),u=CT[n.status]||CT.active,h=(f=>{if(!f)return"";const g=f.split("/").filter(Boolean),y=g.slice(-3).join("/"),b=g.length>3?`โฆ/${y}`:`/${g.join("/")}`;return b.length<=60?b:`โฆ${b.slice(-60)}`})(n.path);return c.jsxs("div",{className:`bg-surface-dark p-6 rounded-lg border border-border-dark transition-all hover:shadow-lg hover:border-primary/50 flex flex-col h-full ${s?"cursor-pointer":""}`,onClick:s,children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h3",{className:"font-semibold text-lg",children:n.name}),e&&c.jsx("span",{className:`text-xs font-medium px-2 py-1 rounded-full ${u.bg} ${u.text}`,children:u.label})]}),c.jsx("p",{className:"text-sm text-text-secondary-dark flex-grow mb-4 whitespace-nowrap overflow-hidden text-ellipsis",title:n.path,children:h}),typeof i=="number"&&c.jsxs("div",{className:"mb-6",children:[c.jsxs("div",{className:"flex justify-between items-center mb-1",children:[c.jsx("p",{className:"text-xs text-text-secondary-dark",children:"Progress"}),c.jsxs("p",{className:"text-xs font-semibold",children:[i,"%"]})]}),c.jsx("div",{className:"w-full bg-background-dark rounded-full h-2",children:c.jsx("div",{className:"bg-primary h-2 rounded-full",style:{width:`${Math.max(0,Math.min(100,i))}%`},title:a?`Open: ${a.open}, In progress: ${a.inProgress}, Pending: ${a.pending}, Done: ${a.done}, Blocked: ${a.blocked}`:void 0})})]}),c.jsxs("div",{className:"mt-auto flex items-center justify-between",children:[c.jsx("div",{className:"flex -space-x-3",children:r.flatMap(f=>f.members||[]).slice(0,3).map((f,g)=>c.jsx("div",{className:"w-8 h-8 rounded-full border-2 border-surface-dark bg-cover bg-center overflow-hidden",title:f.name,children:f.avatar?f.avatar.startsWith("http")||f.avatar.startsWith("data:")?c.jsx("img",{src:f.avatar,alt:f.name,className:"w-full h-full object-cover"}):c.jsx("div",{className:"w-full h-full bg-gradient-to-br from-primary/20 to-primary/40 flex items-center justify-center text-xs font-bold text-white",children:f.avatar}):c.jsx("div",{className:"w-full h-full bg-gradient-to-br from-primary/20 to-primary/40 flex items-center justify-center text-xs font-bold text-white",children:f.name.charAt(0).toUpperCase()})},`${f.id}-${g}`))}),c.jsxs("p",{className:"text-sm text-text-secondary-dark",children:["Updated ",l]})]})]})},Mh=({items:n,align:e="bottom-right",buttonClassName:t="text-text-secondary-dark hover:text-primary transition-colors",menuClassName:r="",icon:s=eU})=>{const[i,o]=P.useState(!1),a=P.useRef(null);return P.useEffect(()=>{const l=u=>{a.current&&!a.current.contains(u.target)&&o(!1)};return i&&document.addEventListener("mousedown",l),()=>document.removeEventListener("mousedown",l)},[i]),c.jsxs("div",{className:"relative",ref:a,children:[c.jsx("button",{type:"button",className:t,onClick:()=>o(l=>!l),"aria-label":"More options",children:c.jsx(s,{className:"w-4 h-4"})}),i&&c.jsx("div",{className:`absolute z-10 w-44 bg-surface-dark border border-border-dark rounded-lg shadow-lg p-1 ${e==="bottom-right"?"right-0 top-8":"right-0 bottom-8"} ${r}`,children:n.map((l,u)=>c.jsx("button",{className:`w-full text-left px-3 py-2 text-sm rounded hover:bg-background-dark ${l.danger?"text-red-300":""}`,onClick:()=>{o(!1),l.onClick()},children:l.label},u))})]})},RH={xs:"w-6 h-6 text-xs",sm:"w-8 h-8 text-sm",md:"w-10 h-10 text-base",lg:"w-12 h-12 text-lg",xl:"w-16 h-16 text-xl"},NH={active:"bg-green-500",inactive:"bg-gray-400",activating:"bg-yellow-500"},SL=({name:n,avatar:e,size:t="md",className:r="",showStatus:s=!1,status:i,ringClass:o=""})=>{const a=RH[t],l=()=>{if(e&&(e.startsWith("http")||e.startsWith("data:")))return c.jsx("img",{src:e,alt:`${n}'s avatar`,title:n,className:`${a} rounded-full object-cover ${o} ${r}`});if(e)return c.jsx("div",{className:`${a} rounded-full bg-background-dark border border-border-dark flex items-center justify-center ${o} ${r}`,title:n,children:c.jsx("span",{children:e})});const u=n?n.charAt(0).toUpperCase():"";return c.jsx("div",{className:`${a} rounded-full bg-background-dark border border-border-dark flex items-center justify-center ${o} ${r}`,title:n,children:u})};return c.jsxs("div",{className:"relative inline-block",children:[l(),s&&i&&c.jsx("span",{className:`absolute bottom-0 right-0 w-3 h-3 ${NH[i]} rounded-full border-2 border-white dark:border-gray-800`,title:i})]})},bL=({team:n,projectName:e,onClick:t,onViewTeam:r,onEditTeam:s,onDeleteTeam:i})=>{const o=n.members||[],a=o.slice(0,3),l=Math.max(o.length-3,0),u=o.some(d=>d.agentStatus==="active");return c.jsxs("div",{className:"relative bg-surface-dark border border-border-dark rounded-2xl p-5 hover:border-primary/50 transition-colors cursor-pointer flex flex-col min-h-[200px]",onClick:t,children:[c.jsxs("div",{className:"flex items-center justify-between mb-3",children:[c.jsx("div",{className:"text-lg font-semibold",children:n.name}),u&&c.jsx("span",{className:"px-2 py-1 text-xs font-medium rounded-full bg-green-500/10 text-green-400",children:"Active"})]}),e&&c.jsxs("div",{className:"flex items-center gap-2 text-text-secondary-dark text-sm mb-4",children:[c.jsx(Os,{className:"w-4 h-4"}),c.jsxs("span",{children:["Project ",e]})]}),c.jsxs("div",{className:"mt-auto flex items-center justify-between",children:[c.jsxs("div",{className:"flex items-center",children:[a.map((d,h)=>c.jsx("div",{style:{marginLeft:h===0?0:-6},children:c.jsx(SL,{name:d.name,avatar:d.avatar,size:"sm",ringClass:"ring-2 ring-surface-dark"})},d.id)),l>0&&c.jsxs("div",{className:"w-8 h-8 rounded-full bg-background-dark border border-border-dark flex items-center justify-center text-xs text-text-secondary-dark ring-2 ring-surface-dark",style:{marginLeft:-6},children:["+",l]})]}),c.jsx("div",{onClick:d=>d.stopPropagation(),children:c.jsx(Mh,{align:"bottom-right",items:[{label:"Edit Team",onClick:()=>s&&s(n.id)},{label:"View Team",onClick:()=>r&&r(n.id)},...i?[{label:"Delete Team",danger:!0,onClick:()=>i(n.id)}]:[]]})})]})]})},pw=({title:n,icon:e=c.jsx(Ps,{className:"text-4xl"}),onClick:t,className:r=""})=>c.jsxs("div",{onClick:t,className:`flex items-center justify-center flex-col p-6 rounded-lg border-2 border-dashed border-border-dark hover:border-primary transition-colors cursor-pointer text-text-secondary-dark hover:text-primary h-full ${r}`,children:[e,c.jsx("p",{className:"mt-2 text-sm font-semibold",children:n})]}),R1="/api",Ag=({title:n,value:e})=>c.jsxs("div",{className:"bg-surface-dark p-6 rounded-lg border border-border-dark transition-all hover:shadow-lg hover:border-primary/50",children:[c.jsx("p",{className:"text-sm font-medium text-text-secondary-dark",children:n}),c.jsx("p",{className:"text-3xl font-bold mt-1",children:e})]}),IH=()=>{const n=Ua(),[e,t]=P.useState([]),[r,s]=P.useState([]),[i,o]=P.useState({}),[a,l]=P.useState({}),[u,d]=P.useState(!0);P.useEffect(()=>{f()},[]);const h=async w=>{try{const M=(await yt.get(`${R1}/projects/${w}/tasks`)).data.data||[],T={open:0,inProgress:0,pending:0,done:0,blocked:0,total:M.length};M.forEach(R=>{var L;const B=((L=R.status)==null?void 0:L.toLowerCase())||"pending";B==="open"?T.open++:B==="in_progress"||B==="in-progress"?T.inProgress++:B==="done"||B==="completed"?T.done++:B==="blocked"?T.blocked++:T.pending++});const A=T.total>0?Math.round(T.done/T.total*100):0,E=`${T.done} of ${T.total} completed`;return{projectId:w,progressPercent:A,progressLabel:E,progressBreakdown:T}}catch(C){return console.error(`Error calculating progress for project ${w}:`,C),{projectId:w,progressPercent:0,progressLabel:"No tasks",progressBreakdown:{open:0,inProgress:0,pending:0,done:0,blocked:0,total:0}}}},f=async()=>{try{d(!0);const[w,C]=await Promise.all([yt.get(`${R1}/projects`),yt.get(`${R1}/teams`)]);if(w.data.success){const R=w.data.data||[];t(R);const B=R.map(z=>h(z.id)),O=(await Promise.all(B)).reduce((z,q)=>(z[q.projectId]=q,z),{});l(O)}const M=w.data.success?w.data.data||[]:[],T=C.data.success?C.data.data||[]:[],A=["https://picsum.photos/seed/1/64","https://picsum.photos/seed/2/64","https://picsum.photos/seed/3/64","https://picsum.photos/seed/4/64","https://picsum.photos/seed/5/64","https://picsum.photos/seed/6/64"],E=T.map(R=>({...R,members:R.members.map((B,L)=>({...B,avatar:B.avatar||A[L%A.length]}))}));if(C.data.success&&s(E),w.data.success&&C.data.success){const R=M.reduce((B,L)=>{const O=E.filter(z=>{var K,N;const q=(K=z.projectIds)==null?void 0:K.includes(L.id),X=(N=z.projectIds)==null?void 0:N.includes(L.name);return q||X});return B[L.id]=O,B},{});o(R)}}catch(w){console.error("Error loading dashboard data:",w)}finally{d(!1)}},g=w=>n(`/projects/${w}`),y=w=>n(`/teams/${w}`),b=()=>{n("/projects?create=true")},p=()=>{n("/teams?create=true")},m=()=>n("/factory");if(u)return c.jsxs("div",{className:"flex items-center justify-center min-h-64",children:[c.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-2 border-primary border-t-transparent"}),c.jsx("p",{className:"ml-3 text-text-secondary-dark",children:"Loading dashboard..."})]});const v=e.slice(0,2),x=r.slice(0,6);return c.jsxs("div",{className:"max-w-7xl mx-auto",children:[c.jsx("div",{className:"flex flex-col md:flex-row items-start md:items-center justify-between gap-4 mb-8",children:c.jsxs("div",{children:[c.jsx("h2",{className:"text-3xl font-bold tracking-tight",children:"Dashboard"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mt-1",children:"Welcome back. Here's a summary of your teams and projects."})]})}),c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-6 mb-10",children:[c.jsx(Ag,{title:"Projects",value:e.length}),c.jsx(Ag,{title:"Teams",value:r.length}),c.jsx(Ag,{title:"Active Projects",value:e.filter(w=>w.status==="active").length}),c.jsx(Ag,{title:"Running Agents",value:r.flatMap(w=>w.members).filter(w=>w.agentStatus==="active").length}),c.jsx("button",{type:"button",onClick:m,className:"bg-gradient-to-br from-primary/20 to-purple-500/20 p-6 rounded-lg border border-primary/30 transition-all hover:shadow-lg hover:shadow-primary/20 hover:border-primary hover:scale-[1.02] group",children:c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(tP,{className:"w-8 h-8 text-primary group-hover:scale-110 transition-transform"}),c.jsxs("div",{className:"text-left",children:[c.jsx("p",{className:"text-sm font-medium text-text-secondary-dark",children:"3D View"}),c.jsx("p",{className:"text-lg font-bold text-primary",children:"Factory"})]})]})})]}),c.jsxs("div",{className:"space-y-10",children:[c.jsxs("section",{children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h3",{className:"text-xl font-semibold",children:"Projects"}),c.jsx(rh,{to:"/projects",className:"text-sm font-semibold text-primary hover:underline",children:"View All"})]}),c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6",children:[v.map(w=>{const C=a[w.id];return c.jsx(_L,{project:w,showStatus:!0,showTeams:!0,assignedTeams:i[w.id]||[],onClick:()=>g(w.id),progressPercent:C==null?void 0:C.progressPercent,progressLabel:C==null?void 0:C.progressLabel,progressBreakdown:C==null?void 0:C.progressBreakdown},w.id)}),c.jsx(pw,{title:"Create New Project",onClick:b})]})]}),c.jsxs("section",{children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h3",{className:"text-xl font-semibold",children:"Teams"}),c.jsx(rh,{to:"/teams",className:"text-sm font-semibold text-primary hover:underline",children:"View All"})]}),c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6",children:[x.map(w=>c.jsx(bL,{team:w,onClick:()=>y(w.id)},w.id)),c.jsx(pw,{title:"Create New Team",onClick:p})]})]})]})]})},PH=({onSelect:n,onCreateProject:e,onClose:t,initialPath:r,title:s="Select Folder",actionButtonText:i})=>{const[o,a]=P.useState(""),[l,u]=P.useState(null),[d,h]=P.useState([]),[f,g]=P.useState(!0),[y,b]=P.useState(""),[p,m]=P.useState(!1),[v,x]=P.useState(!1),w=!!e,C=i||(w?"Create Project Here":"Select"),M=P.useCallback(async O=>{g(!0),b("");try{const z=new URLSearchParams;O&&z.set("path",O),p&&z.set("showHidden","true");const X=await(await fetch(`/api/directories?${z.toString()}`)).json();X.success?(a(X.data.currentPath),u(X.data.parentPath),h(X.data.entries)):b(X.error||"Failed to load directory")}catch{b("Failed to connect to server")}finally{g(!1)}},[p]);P.useEffect(()=>{M(r)},[r,M]);const T=O=>{M(O)},A=()=>{l&&M(l)},E=()=>{M()},R=async()=>{if(w&&e){x(!0),b("");try{await e(o),t()}catch(O){b(O instanceof Error?O.message:"Failed to create project"),x(!1)}}else n&&(n(o),t())},B=O=>{O.type==="directory"&&T(O.path)},L=async O=>{if(O.type==="directory")if(w&&e){x(!0),b("");try{await e(O.path),t()}catch(z){b(z instanceof Error?z.message:"Failed to create project"),x(!1)}}else n&&(n(O.path),t())};return c.jsx("div",{className:"fixed inset-0 bg-background-dark/80 backdrop-blur-sm flex items-center justify-center p-4 z-[60]",children:c.jsxs("div",{className:"bg-surface-dark border border-border-dark rounded-xl shadow-lg w-full max-w-2xl max-h-[80vh] flex flex-col",children:[c.jsxs("div",{className:"p-4 border-b border-border-dark flex items-center justify-between",children:[c.jsx("h3",{className:"text-lg font-semibold",children:s}),c.jsx("button",{className:"text-text-secondary-dark hover:text-text-primary-dark transition-colors",onClick:t,disabled:v,children:c.jsx(Br,{className:"w-5 h-5"})})]}),c.jsxs("div",{className:"px-4 py-2 border-b border-border-dark flex items-center gap-2",children:[c.jsx("button",{className:"p-2 hover:bg-border-dark/50 rounded-lg transition-colors disabled:opacity-50",onClick:A,disabled:!l||f,title:"Go up",children:c.jsx(HF,{className:"w-4 h-4"})}),c.jsx("button",{className:"p-2 hover:bg-border-dark/50 rounded-lg transition-colors",onClick:E,disabled:f,title:"Go to home",children:c.jsx(sP,{className:"w-4 h-4"})}),c.jsx("button",{className:"p-2 hover:bg-border-dark/50 rounded-lg transition-colors",onClick:()=>M(o),disabled:f,title:"Refresh",children:c.jsx(Cu,{className:`w-4 h-4 ${f?"animate-spin":""}`})}),c.jsx("div",{className:"flex-1"}),c.jsxs("label",{className:"flex items-center gap-2 text-sm text-text-secondary-dark cursor-pointer",children:[c.jsx("input",{type:"checkbox",checked:p,onChange:O=>m(O.target.checked),className:"rounded border-border-dark"}),"Show hidden"]})]}),c.jsx("div",{className:"px-4 py-2 bg-background-dark/50 border-b border-border-dark",children:c.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[c.jsx("span",{className:"text-text-secondary-dark",children:"Path:"}),c.jsx("code",{className:"bg-background-dark px-2 py-1 rounded text-xs flex-1 overflow-x-auto whitespace-nowrap",children:o})]})}),c.jsx("div",{className:"flex-1 overflow-y-auto p-2 min-h-[300px]",children:f?c.jsx("div",{className:"flex items-center justify-center h-full",children:c.jsx("div",{className:"w-6 h-6 border-2 border-primary/20 border-t-primary rounded-full animate-spin"})}):y?c.jsx("div",{className:"flex items-center justify-center h-full text-red-400 text-sm",children:y}):d.length===0?c.jsx("div",{className:"flex items-center justify-center h-full text-text-secondary-dark text-sm",children:"Empty directory"}):c.jsx("div",{className:"space-y-1",children:d.map(O=>c.jsxs("button",{className:`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-left hover:bg-border-dark/50 transition-colors ${O.isHidden?"opacity-60":""}`,onClick:()=>B(O),onDoubleClick:()=>L(O),children:[c.jsx(nP,{className:"w-5 h-5 text-blue-400 flex-shrink-0"}),c.jsx("span",{className:"flex-1 truncate",children:O.name}),c.jsx(DC,{className:"w-4 h-4 text-text-secondary-dark"})]},O.path))})}),c.jsxs("div",{className:"p-4 border-t border-border-dark flex flex-col gap-3",children:[y&&c.jsx("p",{className:"text-red-400 text-sm",children:y}),c.jsxs("div",{className:"flex items-center justify-between",children:[c.jsxs("p",{className:"text-xs text-text-secondary-dark",children:["Double-click to ",w?"create project in":"select"," a folder"]}),c.jsxs("div",{className:"flex gap-2",children:[c.jsx("button",{className:"bg-transparent border border-border-dark text-text-primary-dark font-semibold py-2 px-4 rounded-lg hover:bg-border-dark/50 transition-colors disabled:opacity-50",onClick:t,disabled:v,children:"Cancel"}),c.jsx("button",{className:"bg-primary text-white font-semibold py-2 px-4 rounded-lg flex items-center gap-2 hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",onClick:R,disabled:v||f,children:v?c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"w-4 h-4 border-2 border-white/20 border-t-white rounded-full animate-spin"}),c.jsx("span",{children:"Creating..."})]}):c.jsxs(c.Fragment,{children:[c.jsx(XF,{className:"w-4 h-4"}),c.jsx("span",{children:C})]})})]})]})]})]})})},LH=({onSave:n,onClose:e})=>{const[t,r]=P.useState(""),[s,i]=P.useState(!1),[o,a]=P.useState(""),[l,u]=P.useState(!1),d=async g=>{if(g.preventDefault(),!t.trim()){a("Please enter a project path");return}try{i(!0),a(""),await n(t.trim())}catch(y){a(y instanceof Error?y.message:"Failed to create project")}finally{i(!1)}},h=()=>{u(!0)},f=async g=>{await n(g)};return c.jsxs("div",{className:"fixed inset-0 bg-background-dark/80 backdrop-blur-sm flex items-center justify-center p-4 z-50",children:[c.jsxs("div",{className:"bg-surface-dark border border-border-dark rounded-xl shadow-lg w-full max-w-md",children:[c.jsxs("div",{className:"p-6",children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h3",{className:"text-xl font-semibold",children:"Create New Project"}),c.jsx("button",{className:"text-text-secondary-dark hover:text-text-primary-dark transition-colors",onClick:e,disabled:s,children:c.jsx(Br,{className:"w-6 h-6"})})]}),c.jsx("form",{onSubmit:d,children:c.jsx("div",{className:"space-y-4",children:c.jsxs("div",{children:[c.jsxs("label",{className:"block text-sm font-medium text-text-secondary-dark mb-2",htmlFor:"project-path",children:["Project Path ",c.jsx("span",{className:"text-red-400",children:"*"})]}),c.jsxs("div",{className:"flex items-center gap-2",children:[c.jsx("input",{className:"w-full bg-background-dark border border-border-dark rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-primary focus:border-primary placeholder-text-secondary-dark/50",id:"project-path",placeholder:"/Users/name/my-project",type:"text",value:t,onChange:g=>r(g.target.value),disabled:s,required:!0}),c.jsxs("button",{type:"button",className:"bg-background-dark border border-border-dark text-text-secondary-dark font-semibold py-2 px-4 rounded-lg flex items-center gap-2 hover:bg-border-dark/50 hover:text-text-primary-dark transition-colors text-sm whitespace-nowrap",onClick:h,disabled:s,children:[c.jsx(Os,{className:"w-4 h-4"}),c.jsx("span",{children:"Browse"})]})]}),c.jsxs("p",{className:"text-xs text-text-secondary-dark mt-2",children:["Enter the ",c.jsx("strong",{children:"full absolute path"})," to your project directory, or use Browse to navigate to it."]}),o&&c.jsx("p",{className:"text-red-400 text-sm mt-2",children:o})]})})})]}),c.jsxs("div",{className:"bg-background-dark/50 px-6 py-4 border-t border-border-dark flex justify-end gap-3 rounded-b-xl",children:[c.jsx("button",{type:"button",className:"bg-transparent border border-border-dark text-text-primary-dark font-semibold py-2 px-4 rounded-lg hover:bg-border-dark/50 transition-colors",onClick:e,disabled:s,children:"Cancel"}),c.jsx("button",{type:"submit",className:"bg-primary text-white font-semibold py-2 px-4 rounded-lg flex items-center gap-2 hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",onClick:d,disabled:s||!t.trim(),children:s?c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"w-4 h-4 border-2 border-white/20 border-t-white rounded-full animate-spin"}),c.jsx("span",{children:"Creating..."})]}):c.jsx("span",{children:"Create Project"})})]})]}),l&&c.jsx(PH,{title:"Create New Project",onCreateProject:f,onClose:()=>u(!1)})]})},AT="/api",BH=()=>{const n=Ua(),[e,t]=ZI(),[r,s]=P.useState([]),[i,o]=P.useState(!0),[a,l]=P.useState(""),[u,d]=P.useState("all"),[h,f]=P.useState(!1),[g,y]=P.useState({}),[b,p]=P.useState({});P.useEffect(()=>{m(),e.get("create")==="true"&&(f(!0),e.delete("create"),t(e,{replace:!0}))},[]);const m=async()=>{try{o(!0);const T=await yt.get(`${AT}/projects`);if(T.data.success){const A=T.data.data||[];s(A),v(A).catch(E=>console.error("Progress calc failed:",E)),x(A).catch(E=>console.error("Teams loading failed:",E))}}catch(T){console.error("Error loading projects:",T)}finally{o(!1)}},v=async T=>{const A=await Promise.all(T.map(async E=>{try{const R=await sn.getAllTasks(E.id),B=R.length;if(B===0)return[E.id,{percent:0,active:0,total:0,open:0,inProgress:0,pending:0,done:0,blocked:0}];const L=R.filter(j=>j.status==="open").length,O=R.filter(j=>j.status==="in_progress").length,z=R.filter(j=>j.status==="pending").length,q=R.filter(j=>j.status==="done"||j.status==="completed").length,X=R.filter(j=>j.status==="blocked").length,K=L+O+z,N=Math.round(q/B*100);return[E.id,{percent:N,active:K,total:B,open:L,inProgress:O,pending:z,done:q,blocked:X}]}catch(R){return console.warn("Failed to load tasks for project",E.id,R),[E.id,{percent:0,active:0,total:0,open:0,inProgress:0,pending:0,done:0,blocked:0}]}}));y(Object.fromEntries(A))},x=async T=>{try{const A=await sn.getTeams(),E=["https://picsum.photos/seed/1/64","https://picsum.photos/seed/2/64","https://picsum.photos/seed/3/64","https://picsum.photos/seed/4/64","https://picsum.photos/seed/5/64","https://picsum.photos/seed/6/64"],R=A.map(L=>({...L,members:L.members.map((O,z)=>({...O,avatar:O.avatar||E[z%E.length]}))})),B=T.map(L=>{const O=R.filter(z=>{var K,N;const q=(K=z.projectIds)==null?void 0:K.includes(L.id),X=(N=z.projectIds)==null?void 0:N.includes(L.name);return q||X});return[L.id,O]});p(Object.fromEntries(B))}catch(A){console.error("Failed to load teams for projects:",A)}},w=async T=>{try{const A=await yt.post(`${AT}/projects`,{path:T});A.data.success&&A.data.data&&(s(E=>[A.data.data,...E]),f(!1),n(`/projects/${A.data.data.id}`))}catch(A){throw console.error("Error creating project:",A),A}},C=T=>{n(`/projects/${T}`)},M=r.filter(T=>{const A=T.name.toLowerCase().includes(a.toLowerCase())||T.path.toLowerCase().includes(a.toLowerCase()),E=u==="all"||T.status===u;return A&&E});return i?c.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:c.jsxs("div",{className:"text-center",children:[c.jsx("div",{className:"w-12 h-12 border-4 border-primary/20 border-t-primary rounded-full animate-spin mb-4 mx-auto"}),c.jsx("p",{className:"text-text-secondary-dark",children:"Loading projects..."})]})}):c.jsxs("div",{className:"max-w-7xl mx-auto",children:[c.jsxs("div",{className:"flex flex-col md:flex-row items-start md:items-center justify-between gap-4 mb-8",children:[c.jsxs("div",{children:[c.jsx("h2",{className:"text-3xl font-bold tracking-tight",children:"Projects"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mt-1",children:"Manage and monitor your Crewly projects"})]}),c.jsxs("button",{className:"bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors flex items-center gap-2",onClick:()=>f(!0),children:[c.jsx(Ps,{className:"w-5 h-5"}),"New Project"]})]}),c.jsxs("div",{className:"flex flex-col md:flex-row items-center justify-between gap-4 mb-6",children:[c.jsxs("div",{className:"relative w-full md:w-auto md:flex-grow max-w-md",children:[c.jsx(UC,{className:"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary-dark w-5 h-5"}),c.jsx("input",{type:"text",placeholder:"Search projects...",value:a,onChange:T=>l(T.target.value),className:"w-full bg-surface-dark border border-border-dark rounded-lg pl-10 pr-4 py-2.5 text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors"})]}),c.jsx("div",{className:"flex items-center gap-4",children:c.jsxs("select",{value:u,onChange:T=>d(T.target.value),className:"bg-surface-dark border border-border-dark rounded-lg px-4 py-2.5 text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors",children:[c.jsx("option",{value:"all",children:"All Status"}),c.jsx("option",{value:"active",children:"Active"}),c.jsx("option",{value:"paused",children:"Paused"}),c.jsx("option",{value:"completed",children:"Completed"})]})})]}),c.jsx("div",{children:M.length>0?c.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:[M.map(T=>{var A,E,R,B;return c.jsx(_L,{project:T,showStatus:!0,showTeams:!0,assignedTeams:b[T.id]||[],onClick:()=>C(T.id),progressPercent:(A=g[T.id])==null?void 0:A.percent,progressLabel:typeof((E=g[T.id])==null?void 0:E.total)=="number"?`${((R=g[T.id])==null?void 0:R.done)||0} of ${((B=g[T.id])==null?void 0:B.total)||0} completed`:void 0,progressBreakdown:g[T.id]?{open:g[T.id].open,inProgress:g[T.id].inProgress,pending:g[T.id].pending,done:g[T.id].done,blocked:g[T.id].blocked,total:g[T.id].total}:void 0},T.id)}),c.jsx(pw,{title:"New Project",onClick:()=>f(!0)})]}):c.jsxs("div",{className:"text-center py-16",children:[c.jsx("div",{className:"flex justify-center mb-4",children:c.jsx(nP,{className:"w-12 h-12 text-text-secondary-dark/50",strokeWidth:1.5})}),c.jsx("h3",{className:"text-lg font-semibold mb-2",children:a||u!=="all"?"No projects found":"No projects yet"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mb-6",children:a||u!=="all"?"Try adjusting your search or filter criteria":"Create your first project to get started with Crewly"}),!a&&u==="all"&&c.jsxs("button",{className:"bg-primary text-white px-6 py-3 rounded-lg hover:bg-primary/90 transition-colors inline-flex items-center gap-2",onClick:()=>f(!0),children:[c.jsx(Ps,{className:"w-5 h-5"}),"Create Project"]})]})}),h&&c.jsx(LH,{onSave:w,onClose:()=>f(!1)})]})},jH=({project:n,onClose:e,onAssignmentComplete:t})=>{const[r,s]=P.useState([]),[i,o]=P.useState(new Set),[a,l]=P.useState(!0),[u,d]=P.useState(!1),[h,f]=P.useState(null);P.useEffect(()=>{g()},[]);const g=async()=>{try{l(!0);const v=await sn.getTeams();s(v);const x=new Set(v.filter(w=>{var C;return(C=w.projectIds)==null?void 0:C.includes(n.id)}).map(w=>w.id));o(x)}catch(v){f("Failed to load teams"),console.error("Error loading teams:",v)}finally{l(!1)}},y=v=>{const x=new Set(i);x.has(v)?x.delete(v):x.add(v),o(x)},b=async()=>{try{d(!0),f(null),await sn.assignTeamsToProject(n.id,Array.from(i)),t(),e()}catch(v){f(v instanceof Error?v.message:"Failed to assign teams"),console.error("Error assigning teams:",v)}finally{d(!1)}},p=v=>{v.target===v.currentTarget&&e()},m=v=>({orchestrator:"#8b5cf6",pm:"#3b82f6",developer:"#10b981",qa:"#f59e0b",tester:"#ef4444",designer:"#ec4899"})[v]||"#6b7280";return c.jsx("div",{className:"modal-overlay",onClick:p,children:c.jsxs("div",{className:"modal-content team-assignment-modal",children:[c.jsxs("div",{className:"modal-header",children:[c.jsxs("div",{className:"modal-title",children:[c.jsx(si,{className:"title-icon"}),c.jsxs("div",{children:[c.jsx("h2",{children:"Assign Teams"}),c.jsxs("p",{children:['Select teams to assign to "',n.name,'"']})]})]}),c.jsx("button",{className:"close-button",onClick:e,children:c.jsx(Br,{size:20})})]}),c.jsx("div",{className:"modal-body",children:a?c.jsxs("div",{className:"loading-state",children:[c.jsx("div",{className:"loading-spinner"}),c.jsx("p",{children:"Loading teams..."})]}):h?c.jsxs("div",{className:"error-state",children:[c.jsxs("p",{children:["Error: ",h]}),c.jsx(wt,{onClick:g,className:"retry-button",variant:"outline",size:"sm",children:"Retry"})]}):r.length===0?c.jsxs("div",{className:"empty-state",children:[c.jsx(si,{size:48}),c.jsx("h3",{children:"No Teams Available"}),c.jsx("p",{children:"Create some teams first before assigning them to projects."})]}):c.jsxs("div",{className:"teams-selection",children:[c.jsxs("div",{className:"selection-header",children:[c.jsxs("h3",{children:["Available Teams (",r.length,")"]}),c.jsxs("p",{children:["Selected: ",i.size," team",i.size!==1?"s":""]})]}),c.jsx("div",{className:"teams-grid",children:r.map(v=>{var C,M,T;const x=i.has(v.id),w=(C=v.projectIds)==null?void 0:C.includes(n.id);return c.jsxs("div",{className:`team-selection-card ${x?"selected":""}`,onClick:()=>y(v.id),children:[x&&c.jsx("div",{className:"selection-indicator",children:c.jsx(La,{size:16})}),c.jsxs("div",{className:"team-card-header",children:[c.jsxs("div",{className:"team-info",children:[c.jsx("h4",{className:"team-name",children:v.name}),v.description&&c.jsx("p",{className:"team-description",children:v.description})]}),c.jsx("div",{className:"team-meta",children:c.jsx("span",{className:"team-meta-info",children:new Date(v.updatedAt).toLocaleDateString()})})]}),c.jsxs("div",{className:"team-members-summary",children:[c.jsxs("div",{className:"members-count",children:[c.jsx(si,{size:14}),c.jsxs("span",{children:[((M=v.members)==null?void 0:M.length)||0," member",(((T=v.members)==null?void 0:T.length)||0)!==1?"s":""]})]}),v.members&&v.members.length>0&&c.jsxs("div",{className:"member-roles",children:[v.members.slice(0,3).map((A,E)=>c.jsx("span",{className:"role-badge",style:{color:m(A.role)},children:A.role},E)),v.members.length>3&&c.jsxs("span",{className:"more-roles",children:["+",v.members.length-3," more"]})]})]}),w&&c.jsx("div",{className:"assignment-status current-project",children:"Currently assigned to this project"})]},v.id)})})]})}),c.jsxs("div",{className:"modal-footer",children:[c.jsx(wt,{className:"secondary-button",onClick:e,disabled:u,variant:"secondary",children:"Cancel"}),c.jsxs(wt,{className:"primary-button",onClick:b,disabled:u||r.length===0,loading:u,icon:La,children:["Assign ",i.size," Team",i.size!==1?"s":""]})]})]})})},MT={in_progress:{icon:Ha,color:"text-primary",label:"In Progress"},open:{icon:Yb,color:"text-text-secondary-dark",label:"Open"},pending:{icon:Yb,color:"text-text-secondary-dark",label:"Open"},done:{icon:Bl,color:"text-green-400",label:"Done"},completed:{icon:Bl,color:"text-green-400",label:"Done"},blocked:{icon:sh,color:"text-red-400",label:"Blocked"}},ET={high:{color:"text-red-400",label:"High"},critical:{color:"text-red-500",label:"Critical"},medium:{color:"text-yellow-400",label:"Medium"},low:{color:"text-green-400",label:"Low"}},DH=({isOpen:n,onClose:e,task:t,onEdit:r,onAssign:s,taskAssignmentLoading:i})=>{var u;if(!n||!t)return null;const o=MT[t.status]||MT.open,a=ET[t.priority]||ET.medium,l=o.icon;return c.jsx("div",{className:"fixed inset-0 bg-black/60 z-50 flex items-center justify-center p-4",onClick:e,children:c.jsxs("div",{className:"bg-surface-dark w-full max-w-4xl rounded-xl shadow-2xl flex flex-col h-[90vh]",onClick:d=>d.stopPropagation(),children:[c.jsxs("div",{className:"flex items-center justify-between p-6 border-b border-border-dark flex-shrink-0",children:[c.jsxs("div",{className:"flex items-center gap-4",children:[c.jsx("span",{className:"bg-primary/10 text-primary p-2 rounded-lg",children:c.jsx(l,{className:"w-5 h-5"})}),c.jsxs("div",{children:[c.jsx("h3",{className:"text-xl font-bold",children:t.title}),c.jsxs("p",{className:"text-sm text-text-secondary-dark",children:["In ",c.jsx("span",{className:"text-primary",children:"Crewly Project"})]})]})]}),c.jsxs("div",{className:"flex items-center gap-2",children:[c.jsx(wt,{variant:"ghost",size:"icon",className:"w-8 h-8",children:c.jsx(ZF,{className:"w-4 h-4"})}),c.jsx(wt,{variant:"ghost",size:"icon",onClick:e,className:"w-8 h-8",children:c.jsx(Br,{className:"w-4 h-4"})})]})]}),c.jsxs("div",{className:"flex-grow p-6 overflow-y-auto",children:[c.jsxs("div",{className:"flex items-center justify-between mb-6",children:[c.jsxs("div",{className:"flex items-center gap-6",children:[c.jsxs("div",{children:[c.jsx("label",{className:"text-xs font-semibold text-text-secondary-dark uppercase tracking-wider",children:"Status"}),c.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[c.jsx(l,{className:`${o.color} w-5 h-5`}),c.jsx("p",{className:"text-sm font-medium",children:o.label})]})]}),c.jsxs("div",{children:[c.jsx("label",{className:"text-xs font-semibold text-text-secondary-dark uppercase tracking-wider",children:"Priority"}),c.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[c.jsx("div",{className:`w-3 h-3 rounded-full ${a.color.replace("text-","bg-")}`}),c.jsx("p",{className:"text-sm font-medium",children:a.label})]})]}),c.jsxs("div",{children:[c.jsx("label",{className:"text-xs font-semibold text-text-secondary-dark uppercase tracking-wider",children:"Milestone"}),c.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[c.jsx("div",{className:"w-3 h-3 rounded bg-primary/80"}),c.jsx("p",{className:"text-sm font-medium",children:((u=t.milestoneId)==null?void 0:u.replace(/_/g," ").replace(/^m\d+\s*/,""))||t.milestone||"General"})]})]})]}),c.jsxs("div",{className:"flex items-center gap-2",children:[r&&c.jsx(wt,{variant:"secondary",size:"sm",icon:lP,onClick:()=>r(t),children:"Edit"}),s&&t.status!=="done"&&t.status!=="completed"&&c.jsx(wt,{variant:"primary",size:"sm",onClick:()=>s(t),loading:i===t.id,disabled:i===t.id,children:i===t.id?"Starting...":"Start Task"})]})]}),c.jsxs("div",{className:"mb-6",children:[c.jsx("h4",{className:"text-lg font-semibold mb-4",children:"Description"}),c.jsx("div",{className:"text-text-secondary-dark leading-relaxed prose prose-invert max-w-none text-sm",children:t.description?c.jsx("div",{children:t.description.split(`
|
|
99
99
|
`).map((d,h)=>c.jsx("p",{className:"mb-2",children:d},h))}):c.jsx("p",{className:"italic text-text-secondary-dark",children:"No description provided"})})]}),t.acceptanceCriteria&&t.acceptanceCriteria.length>0&&c.jsxs("div",{className:"mb-6",children:[c.jsxs("h4",{className:"text-lg font-semibold mb-4",children:["Acceptance Criteria (",t.acceptanceCriteria.length,")"]}),c.jsx("div",{className:"space-y-2",children:t.acceptanceCriteria.map((d,h)=>c.jsxs("div",{className:"flex items-start gap-2 p-3 bg-background-dark rounded-lg",children:[c.jsx(Bl,{className:"w-4 h-4 text-green-400 mt-0.5 flex-shrink-0"}),c.jsx("span",{className:"text-sm",children:d})]},h))})]}),t.tasks&&t.tasks.length>0&&c.jsxs("div",{className:"mb-6",children:[c.jsxs("h4",{className:"text-lg font-semibold mb-4",children:["Subtasks (",t.tasks.length,")"]}),c.jsx("div",{className:"space-y-2",children:t.tasks.map((d,h)=>c.jsxs("div",{className:"flex items-start gap-2 p-3 bg-background-dark rounded-lg",children:[c.jsx(Yb,{className:"w-4 h-4 text-text-secondary-dark mt-0.5 flex-shrink-0"}),c.jsx("span",{className:"text-sm",children:d.replace(/^\[x\]\s*|\[\s*\]\s*/i,"")})]},h))})]}),t.assignee&&c.jsxs("div",{className:"mb-6",children:[c.jsx("h4",{className:"text-lg font-semibold mb-4",children:"Assignment"}),c.jsx("div",{className:"p-3 bg-background-dark rounded-lg",children:c.jsxs("p",{className:"text-sm",children:[c.jsx("span",{className:"text-text-secondary-dark",children:"Assigned to:"})," ",c.jsx("span",{className:"font-medium",children:t.assignee})]})})]})]})]})})},OH=({projectPath:n,onClose:e})=>{const[t,r]=P.useState(null),[s,i]=P.useState([]),[o,a]=P.useState(!1),[l,u]=P.useState(!1),[d,h]=P.useState(null),f={"project-spec.md":`# Project Specification
|
|
100
100
|
|
|
101
101
|
## Overview
|
|
@@ -4916,4 +4916,4 @@ You are a...`,className:"font-mono text-sm"}),c.jsx("p",{className:"text-xs text
|
|
|
4916
4916
|
|
|
4917
4917
|
Provide detailed instructions for this skill...`,rows:8,className:"font-mono text-sm"})]})]}),c.jsxs("div",{className:"flex items-center justify-end gap-3 p-6 border-t border-border-dark bg-background-dark",children:[c.jsx(wt,{variant:"secondary",onClick:t,type:"button",children:"Cancel"}),c.jsx(wt,{type:"submit",onClick:d,disabled:o,loading:o,children:o?"Saving...":"Save Skill"})]})]})})},bte=({skillName:n,onConfirm:e,onCancel:t})=>{const r=s=>{s.target===s.currentTarget&&t()};return c.jsx("div",{className:"fixed inset-0 bg-background-dark/80 backdrop-blur-sm flex items-center justify-center z-50",onClick:r,children:c.jsxs("div",{className:"bg-surface-dark border border-border-dark rounded-xl shadow-lg w-full max-w-md m-4",onClick:s=>s.stopPropagation(),children:[c.jsx("div",{className:"p-6 border-b border-border-dark",children:c.jsx("h2",{className:"text-xl font-semibold text-text-primary-dark",children:"Delete Skill"})}),c.jsx("div",{className:"p-6",children:c.jsxs("p",{className:"text-text-secondary-dark",children:["Are you sure you want to delete ",c.jsx("strong",{className:"text-text-primary-dark",children:n}),"? This action cannot be undone."]})}),c.jsxs("div",{className:"flex items-center justify-end gap-3 p-6 border-t border-border-dark bg-background-dark rounded-b-xl",children:[c.jsx(wt,{variant:"secondary",onClick:t,children:"Cancel"}),c.jsx(wt,{variant:"danger",onClick:e,children:"Delete"})]})]})})},wte=()=>{const[n,e]=P.useState({connected:!1}),[t,r]=P.useState(!0),[s,i]=P.useState(!1),[o,a]=P.useState(null),[l,u]=P.useState({botToken:"",appToken:"",signingSecret:"",defaultChannel:""}),d=P.useCallback(async()=>{var y,b,p,m,v,x,w;try{a(null);const M=await(await fetch("/api/slack/status")).json();M.success?e({connected:((y=M.data)==null?void 0:y.isConfigured)||!1,workspaceName:(b=M.data)==null?void 0:b.workspaceName,botName:(p=M.data)==null?void 0:p.botName,channels:(m=M.data)==null?void 0:m.channels,lastMessageAt:(v=M.data)==null?void 0:v.lastMessageAt,messagesSent:(x=M.data)==null?void 0:x.messagesSent,messagesReceived:(w=M.data)==null?void 0:w.messagesReceived}):e({connected:!1,error:M.error})}catch{e({connected:!1,error:"Failed to fetch status"})}finally{r(!1)}},[]);P.useEffect(()=>{d()},[d]);const h=y=>{const{name:b,value:p}=y.target;u(m=>({...m,[b]:p}))},f=async y=>{y.preventDefault(),i(!0),a(null);try{const b=await fetch("/api/slack/connect",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({botToken:l.botToken,appToken:l.appToken,signingSecret:l.signingSecret,defaultChannelId:l.defaultChannel||void 0})}),p=await b.json();if(!b.ok||!p.success)throw new Error(p.error||"Connection failed");u({botToken:"",appToken:"",signingSecret:"",defaultChannel:""}),await d()}catch(b){a(b instanceof Error?b.message:"Failed to connect to Slack")}finally{i(!1)}},g=async()=>{if(window.confirm("Are you sure you want to disconnect from Slack?"))try{a(null);const y=await fetch("/api/slack/disconnect",{method:"POST"}),b=await y.json();if(!y.ok||!b.success)throw new Error(b.error||"Disconnect failed");await d()}catch(y){a(y instanceof Error?y.message:"Failed to disconnect")}};return t?c.jsxs("div",{className:"flex flex-col items-center justify-center py-16",children:[c.jsx("div",{className:"w-10 h-10 border-4 border-primary/20 border-t-primary rounded-full animate-spin mb-4"}),c.jsx("p",{className:"text-text-secondary-dark",children:"Loading Slack status..."})]}):c.jsxs("div",{className:"space-y-6 max-w-3xl",children:[c.jsxs("div",{children:[c.jsx("h2",{className:"text-xl font-semibold",children:"Slack Integration"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mt-1",children:"Connect Slack to communicate with the orchestrator from your phone or desktop Slack app."})]}),o&&c.jsxs("div",{className:"bg-rose-500/10 border border-rose-500/30 text-rose-400 px-4 py-3 rounded-lg flex items-center justify-between",children:[c.jsxs("div",{className:"flex items-center gap-2",children:[c.jsx(Ep,{className:"w-5 h-5"}),c.jsx("span",{children:o})]}),c.jsx("button",{onClick:()=>a(null),className:"text-rose-400 hover:text-rose-300 p-1",children:c.jsx(Br,{className:"w-4 h-4"})})]}),n.connected?c.jsxs("div",{className:"space-y-6",children:[c.jsxs("div",{className:"bg-emerald-500/10 border border-emerald-500/30 rounded-lg p-4 flex items-center gap-3",children:[c.jsx(Bl,{className:"w-5 h-5 text-emerald-400"}),c.jsx("span",{className:"text-emerald-400 font-medium",children:"Connected to Slack"})]}),c.jsxs("div",{className:"bg-surface-dark border border-border-dark rounded-lg p-6",children:[c.jsx("h3",{className:"text-sm font-semibold text-text-secondary-dark uppercase tracking-wide mb-4",children:"Connection Details"}),c.jsxs("div",{className:"space-y-3",children:[n.workspaceName&&c.jsxs("div",{className:"flex items-center justify-between py-2 border-b border-border-dark",children:[c.jsx("span",{className:"text-sm text-text-secondary-dark",children:"Workspace"}),c.jsx("span",{className:"text-sm font-medium",children:n.workspaceName})]}),n.botName&&c.jsxs("div",{className:"flex items-center justify-between py-2 border-b border-border-dark",children:[c.jsx("span",{className:"text-sm text-text-secondary-dark",children:"Bot Name"}),c.jsx("span",{className:"text-sm font-medium",children:n.botName})]}),n.channels&&n.channels.length>0&&c.jsxs("div",{className:"flex items-center justify-between py-2 border-b border-border-dark",children:[c.jsx("span",{className:"text-sm text-text-secondary-dark",children:"Channels"}),c.jsx("span",{className:"text-sm font-medium",children:n.channels.join(", ")})]}),n.messagesSent!==void 0&&c.jsxs("div",{className:"flex items-center justify-between py-2 border-b border-border-dark",children:[c.jsx("span",{className:"text-sm text-text-secondary-dark",children:"Messages Sent"}),c.jsx("span",{className:"text-sm font-medium",children:n.messagesSent})]}),n.messagesReceived!==void 0&&c.jsxs("div",{className:"flex items-center justify-between py-2 border-b border-border-dark",children:[c.jsx("span",{className:"text-sm text-text-secondary-dark",children:"Messages Received"}),c.jsx("span",{className:"text-sm font-medium",children:n.messagesReceived})]}),n.lastMessageAt&&c.jsxs("div",{className:"flex items-center justify-between py-2",children:[c.jsx("span",{className:"text-sm text-text-secondary-dark",children:"Last Activity"}),c.jsx("span",{className:"text-sm font-medium",children:new Date(n.lastMessageAt).toLocaleString()})]})]})]}),c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(wt,{variant:"secondary",onClick:d,icon:Cu,children:"Refresh Status"}),c.jsx(wt,{variant:"danger",onClick:g,icon:uU,children:"Disconnect"})]})]}):c.jsxs("div",{className:"space-y-6",children:[c.jsxs("div",{className:"bg-amber-500/10 border border-amber-500/30 rounded-lg p-4 flex items-center gap-3",children:[c.jsx(Ep,{className:"w-5 h-5 text-amber-400"}),c.jsx("span",{className:"text-amber-400 font-medium",children:"Not connected to Slack"})]}),c.jsxs("div",{className:"bg-surface-dark border border-border-dark rounded-lg p-6",children:[c.jsx("h3",{className:"text-sm font-semibold text-text-secondary-dark uppercase tracking-wide mb-4",children:"Setup Instructions"}),c.jsxs("ol",{className:"list-decimal list-inside space-y-3 text-sm text-text-secondary-dark",children:[c.jsxs("li",{children:["Create a Slack App at"," ",c.jsxs("a",{href:"https://api.slack.com/apps",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline inline-flex items-center gap-1",children:["api.slack.com/apps",c.jsx(OC,{className:"w-3 h-3"})]})]}),c.jsx("li",{children:"Enable Socket Mode in your app settings and create an App Token (starts with xapp-)"}),c.jsxs("li",{children:["Add Bot Token Scopes under OAuth & Permissions:",c.jsxs("ul",{className:"list-disc list-inside ml-4 mt-1.5 space-y-1",children:[c.jsxs("li",{children:[c.jsx("code",{className:"text-xs bg-background-dark px-1.5 py-0.5 rounded",children:"chat:write"})," - Send messages"]}),c.jsxs("li",{children:[c.jsx("code",{className:"text-xs bg-background-dark px-1.5 py-0.5 rounded",children:"channels:read"})," - View channels"]}),c.jsxs("li",{children:[c.jsx("code",{className:"text-xs bg-background-dark px-1.5 py-0.5 rounded",children:"app_mentions:read"})," - Respond to mentions"]}),c.jsxs("li",{children:[c.jsx("code",{className:"text-xs bg-background-dark px-1.5 py-0.5 rounded",children:"im:read"}),", ",c.jsx("code",{className:"text-xs bg-background-dark px-1.5 py-0.5 rounded",children:"im:write"})," - Direct messages"]}),c.jsxs("li",{children:[c.jsx("code",{className:"text-xs bg-background-dark px-1.5 py-0.5 rounded",children:"files:read"})," - Receive images from Slack"]}),c.jsxs("li",{children:[c.jsx("code",{className:"text-xs bg-background-dark px-1.5 py-0.5 rounded",children:"files:write"})," - Upload images to Slack"]}),c.jsxs("li",{children:[c.jsx("code",{className:"text-xs bg-background-dark px-1.5 py-0.5 rounded",children:"reactions:write"})," - Typing/completion indicators (optional)"]})]}),c.jsxs("p",{className:"text-xs text-amber-400/80 mt-1.5 ml-4",children:["Note: Adding ",c.jsx("code",{className:"text-xs bg-background-dark px-1 py-0.5 rounded",children:"files:read"})," and ",c.jsx("code",{className:"text-xs bg-background-dark px-1 py-0.5 rounded",children:"files:write"})," scopes requires reinstalling the app to your workspace."]})]}),c.jsx("li",{children:"Install the app to your workspace"}),c.jsx("li",{children:"Copy the Bot Token (xoxb-...), App Token (xapp-...), and Signing Secret"})]})]}),c.jsxs("form",{onSubmit:f,className:"bg-surface-dark border border-border-dark rounded-lg p-6 space-y-4",children:[c.jsx("h3",{className:"text-sm font-semibold text-text-secondary-dark uppercase tracking-wide mb-4",children:"Connect to Slack"}),c.jsxs("div",{children:[c.jsx(Ht,{htmlFor:"botToken",required:!0,children:"Bot Token (xoxb-...)"}),c.jsx(gr,{id:"botToken",name:"botToken",type:"password",value:l.botToken,onChange:h,placeholder:"xoxb-your-bot-token",required:!0,autoComplete:"off"})]}),c.jsxs("div",{children:[c.jsx(Ht,{htmlFor:"appToken",required:!0,children:"App Token (xapp-...)"}),c.jsx(gr,{id:"appToken",name:"appToken",type:"password",value:l.appToken,onChange:h,placeholder:"xapp-your-app-token",required:!0,autoComplete:"off"})]}),c.jsxs("div",{children:[c.jsx(Ht,{htmlFor:"signingSecret",required:!0,children:"Signing Secret"}),c.jsx(gr,{id:"signingSecret",name:"signingSecret",type:"password",value:l.signingSecret,onChange:h,placeholder:"Your signing secret",required:!0,autoComplete:"off"})]}),c.jsxs("div",{children:[c.jsx(Ht,{htmlFor:"defaultChannel",children:"Default Channel (optional)"}),c.jsx(gr,{id:"defaultChannel",name:"defaultChannel",type:"text",value:l.defaultChannel,onChange:h,placeholder:"C1234567890 or #crewly"}),c.jsx("p",{className:"text-xs text-text-secondary-dark mt-1",children:"Channel ID or name where notifications will be sent by default"})]}),c.jsx("div",{className:"pt-2",children:c.jsx(wt,{type:"submit",disabled:s||!l.botToken||!l.appToken||!l.signingSecret,loading:s,fullWidth:!0,children:s?"Connecting...":"Connect to Slack"})})]})]})]})},Cte=()=>{const[n,e]=P.useState("general"),t=[{id:"general",label:"General",icon:uP},{id:"roles",label:"Roles",icon:Yp},{id:"skills",label:"Skills",icon:mP},{id:"slack",label:"Slack",icon:iP}],r=()=>{switch(n){case"general":return c.jsx(ite,{});case"roles":return c.jsx(ute,{});case"skills":return c.jsx(gte,{});case"slack":return c.jsx(wte,{});default:return null}};return c.jsxs("div",{className:"max-w-7xl mx-auto",children:[c.jsxs("div",{className:"mb-8",children:[c.jsx("h1",{className:"text-3xl font-bold tracking-tight",children:"Settings"}),c.jsx("p",{className:"text-sm text-text-secondary-dark mt-1",children:"Configure Crewly behavior and manage roles and skills"})]}),c.jsx("nav",{className:"flex gap-1 border-b border-border-dark mb-6",role:"tablist",children:t.map(s=>c.jsxs("button",{className:`flex items-center gap-2 px-4 py-3 text-sm font-medium border-b-2 transition-colors -mb-px ${n===s.id?"border-primary text-primary":"border-transparent text-text-secondary-dark hover:text-text-primary-dark hover:bg-surface-dark"}`,onClick:()=>e(s.id),"aria-selected":n===s.id,role:"tab",id:`tab-${s.id}`,"aria-controls":`panel-${s.id}`,children:[c.jsx(s.icon,{className:"w-4 h-4"}),c.jsx("span",{children:s.label})]},s.id))}),c.jsx("main",{role:"tabpanel",id:`panel-${n}`,"aria-labelledby":`tab-${n}`,children:r()})]})},pa="/api/chat";class Ate{async parseResponse(e,t){const r=await e.text();if(!r)throw new Error(t);try{return JSON.parse(r)}catch{throw new Error(t)}}async sendMessage(e){const t=await fetch(`${pa}/send`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),r=await this.parseResponse(t,"Failed to send message");if(!r.success)throw new Error(r.error||"Failed to send message");return r.data}async getMessages(e,t,r){const s=new URLSearchParams({conversationId:e});t&&s.set("limit",t.toString()),r&&s.set("before",r);const i=await fetch(`${pa}/messages?${s.toString()}`),o=await this.parseResponse(i,"Failed to load messages");if(!o.success)throw new Error(o.error||"Failed to load messages");return o.data}async getConversations(e=!1){const r=await fetch(`${pa}/conversations${e?"?includeArchived=true":""}`),s=await this.parseResponse(r,"Failed to load conversations");if(!s.success)throw new Error(s.error||"Failed to load conversations");return s.data}async getCurrentConversation(){const e=await fetch(`${pa}/conversations/current`),t=await this.parseResponse(e,"Failed to load current conversation");if(!t.success)throw new Error(t.error||"Failed to load current conversation");return t.data}async createConversation(e){const t=await fetch(`${pa}/conversations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:e})}),r=await this.parseResponse(t,"Request failed");if(!r.success)throw new Error(r.error||"Failed to create conversation");return r.data}async updateConversation(e,t){const r=await fetch(`${pa}/conversations/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),s=await this.parseResponse(r,"Request failed");if(!s.success)throw new Error(s.error||"Failed to update conversation");return s.data}async deleteConversation(e){const t=await fetch(`${pa}/conversations/${e}`,{method:"DELETE"}),r=await this.parseResponse(t,"Request failed");if(!r.success)throw new Error(r.error||"Failed to delete conversation")}async archiveConversation(e){const t=await fetch(`${pa}/conversations/${e}/archive`,{method:"PUT"}),r=await this.parseResponse(t,"Request failed");if(!r.success)throw new Error(r.error||"Failed to archive conversation")}async clearConversation(e){const t=await fetch(`${pa}/conversations/${e}/clear`,{method:"POST"}),r=await this.parseResponse(t,"Request failed");if(!r.success)throw new Error(r.error||"Failed to clear conversation")}}const Do=new Ate,yD=P.createContext(null),Mte=({children:n})=>{const[e,t]=P.useState([]),[r,s]=P.useState(null),[i,o]=P.useState([]),[a,l]=P.useState(!0),[u,d]=P.useState(!1),[h,f]=P.useState(null),[g,y]=P.useState(!1),b=P.useRef(null);P.useEffect(()=>{b.current=r},[r]);const p=P.useCallback(L=>{let O;const z=L;if(z&&typeof z=="object"&&("data"in z&&z.data&&typeof z.data=="object"?O=z.data:"id"in z&&(O=z)),!O||!O.id)return;const q=b.current;O.conversationId===(q==null?void 0:q.id)&&(o(X=>X.some(K=>K.id===O.id)?X:[...X,O]),y(!1)),t(X=>X.map(K=>K.id===O.conversationId?{...K,lastMessage:{content:O.content.slice(0,100),timestamp:O.timestamp,from:O.from},messageCount:K.messageCount+1,updatedAt:O.timestamp}:K))},[]),m=P.useCallback(L=>{const O=L,z=O.data||O,q=b.current;z.conversationId===(q==null?void 0:q.id)&&y(z.isTyping??!1)},[]),v=P.useCallback(L=>{let O;const z=L;if(z&&typeof z=="object"&&("data"in z&&z.data&&typeof z.data=="object"?O=z.data:"id"in z&&(O=z)),!O||!O.id)return;t(X=>{const K=X.findIndex(N=>N.id===O.id);if(K>=0){const N=[...X];return N[K]=O,N}return[O,...X]});const q=b.current;(q==null?void 0:q.id)===O.id&&s(O)},[]);P.useEffect(()=>(ut.on("chat_message",p),ut.on("chat_typing",m),ut.on("conversation_updated",v),ut.subscribeToChat(),()=>{ut.off("chat_message",p),ut.off("chat_typing",m),ut.off("conversation_updated",v),ut.unsubscribeFromChat()}),[p,m,v]),P.useEffect(()=>{(async()=>{l(!0);try{const[O,z]=await Promise.all([Do.getConversations(),Do.getCurrentConversation()]);if(t(O),z){s(z);const q=await Do.getMessages(z.id);o(q)}}catch(O){f(O instanceof Error?O.message:"Failed to load chat")}finally{l(!1)}})()},[]);const x=P.useCallback(async L=>{if(!(!L.trim()||u)){d(!0),f(null);try{const O=await Do.sendMessage({content:L,conversationId:r==null?void 0:r.id});o(z=>z.some(q=>q.id===O.message.id)?z:[...z,O.message]),r||(s(O.conversation),t(z=>[O.conversation,...z])),O.orchestrator&&!O.orchestrator.forwarded&&O.orchestrator.error&&f(O.orchestrator.error)}catch(O){f(O instanceof Error?O.message:"Failed to send message")}finally{d(!1)}}},[u,r]),w=P.useCallback(async L=>{const O=e.find(z=>z.id===L);if(O){s(O),l(!0),f(null);try{const z=await Do.getMessages(L);o(z)}catch(z){f(z instanceof Error?z.message:"Failed to load messages")}finally{l(!1)}}},[e]),C=P.useCallback(async L=>{const O=await Do.createConversation(L);return t(z=>[O,...z]),s(O),o([]),O},[]),M=P.useCallback(async L=>{if(await Do.deleteConversation(L),t(O=>O.filter(z=>z.id!==L)),(r==null?void 0:r.id)===L){const O=e.filter(z=>z.id!==L);O.length>0?await w(O[0].id):(s(null),o([]))}},[r,e,w]),T=P.useCallback(async L=>{if(await Do.archiveConversation(L),t(O=>O.filter(z=>z.id!==L)),(r==null?void 0:r.id)===L){const O=e.filter(z=>z.id!==L);O.length>0?await w(O[0].id):(s(null),o([]))}},[r,e,w]),A=P.useCallback(async L=>{await Do.clearConversation(L),(r==null?void 0:r.id)===L&&o([])},[r]),E=P.useCallback(async()=>{if(!r)return;const L=await Do.getMessages(r.id);o(L)},[r]),R=P.useCallback(()=>{f(null)},[]),B={conversations:e,currentConversation:r,messages:i,isLoading:a,isSending:u,error:h,isTyping:g,sendMessage:x,selectConversation:w,createConversation:C,deleteConversation:M,archiveConversation:T,clearConversation:A,refreshMessages:E,clearError:R};return c.jsx(yD.Provider,{value:B,children:n})},_D=()=>{const n=P.useContext(yD);if(!n)throw new Error("useChat must be used within a ChatProvider");return n},Rr={MINUTE:60*1e3,HOUR:60*60*1e3,DAY:24*60*60*1e3,WEEK:7*24*60*60*1e3,MONTH:30*24*60*60*1e3,YEAR:365*24*60*60*1e3};function Ete(n,e=new Date){const t=typeof n=="string"?new Date(n):n,r=e.getTime()-t.getTime();if(r<0)return Tte(Math.abs(r));if(r<Rr.MINUTE)return"just now";if(r<Rr.HOUR){const s=Math.floor(r/Rr.MINUTE);return`${s} ${s===1?"minute":"minutes"} ago`}if(r<Rr.DAY){const s=Math.floor(r/Rr.HOUR);return`${s} ${s===1?"hour":"hours"} ago`}if(r<Rr.DAY*2)return"Yesterday";if(r<Rr.WEEK)return`${Math.floor(r/Rr.DAY)} days ago`;if(r<Rr.MONTH){const s=Math.floor(r/Rr.WEEK);return`${s} ${s===1?"week":"weeks"} ago`}if(r<Rr.YEAR){const s=Math.floor(r/Rr.MONTH);return`${s} ${s===1?"month":"months"} ago`}return kte(t)}function Tte(n){if(n<Rr.MINUTE)return"in a moment";if(n<Rr.HOUR){const t=Math.floor(n/Rr.MINUTE);return`in ${t} ${t===1?"minute":"minutes"}`}if(n<Rr.DAY){const t=Math.floor(n/Rr.HOUR);return`in ${t} ${t===1?"hour":"hours"}`}return n<Rr.DAY*2?"Tomorrow":`in ${Math.floor(n/Rr.DAY)} days`}function kte(n,e={}){const t={month:"short",day:"numeric",year:"numeric",...e};return n.toLocaleDateString(void 0,t)}function Rte(n){if(n.from.name)return n.from.name;switch(n.from.type){case"user":return"You";case"orchestrator":return"Orchestrator";case"agent":return n.from.role??"Agent";case"system":return"System";default:return"Unknown"}}function Nte(n){switch(n.from.type){case"user":return"๐ค";case"orchestrator":return"๐ค";case"agent":return"๐ง";case"system":return"โน๏ธ";default:return"๐ฌ"}}function Ite(n){return n.split(/(```[\s\S]*?```)/g).map((t,r)=>{if(t.startsWith("```")&&t.endsWith("```")){const s=t.slice(3,-3),i=s.indexOf(`
|
|
4918
4918
|
`),o=i>0?s.slice(0,i).trim():"",a=i>0?s.slice(i+1):s;return c.jsx("pre",{className:"code-block","data-language":o,children:c.jsx("code",{children:a})},r)}return c.jsx("span",{children:Pte(t)},r)})}function Pte(n){return n.split(/(`[^`]+`)/g).map((t,r)=>{if(t.startsWith("`")&&t.endsWith("`"))return c.jsx("code",{className:"inline-code",children:t.slice(1,-1)},r);let s=t;const i=/\*\*([^*]+)\*\*/g,o=t.split(i);return o.length>1&&(s=o.map((a,l)=>l%2===1?c.jsx("strong",{children:a},`bold-${r}-${l}`):a)),c.jsx(Cn.Fragment,{children:s},r)})}const Lte=({message:n})=>{var l,u,d;const[e,t]=P.useState(!1),r=n.from.type==="user",s=n.from.type==="system",i=!!((l=n.metadata)!=null&&l.rawOutput),o=()=>{var h;return e&&((h=n.metadata)!=null&&h.rawOutput)?c.jsx("pre",{className:"raw-output","data-testid":"raw-output",children:n.metadata.rawOutput}):n.contentType==="code"||n.contentType==="markdown"||n.contentType==="text"?c.jsx("div",{className:"formatted-content",children:Ite(n.content)}):c.jsx("p",{children:n.content})},a=["chat-message",n.from.type,r?"user-message":"",s?"system-message":"",n.status==="error"?"error-status":""].filter(Boolean).join(" ");return c.jsxs("div",{className:a,"data-testid":"chat-message",children:[c.jsxs("div",{className:"message-header",children:[c.jsx("span",{className:"sender-icon","aria-hidden":"true",children:Nte(n)}),c.jsx("span",{className:"sender-name",children:Rte(n)}),c.jsx("span",{className:"message-time",children:Ete(n.timestamp)}),i&&c.jsx("button",{className:"toggle-raw-btn",onClick:()=>t(!e),title:e?"Show formatted":"Show raw output","aria-label":e?"Show formatted":"Show raw output","data-testid":"toggle-raw-button",children:e?"๐":"๐"})]}),c.jsx("div",{className:"message-content",children:o()}),((u=n.metadata)==null?void 0:u.skillUsed)&&c.jsx("div",{className:"message-metadata",children:c.jsxs("span",{className:"skill-badge",children:["Skill: ",n.metadata.skillUsed]})}),((d=n.metadata)==null?void 0:d.taskCreated)&&c.jsx("div",{className:"message-metadata",children:c.jsxs("span",{className:"task-badge",children:["Task created: ",n.metadata.taskCreated]})}),n.status==="error"&&c.jsx("div",{className:"message-error",role:"alert",children:"Failed to deliver"})]})};const Bte=({disabled:n=!1,disabledPlaceholder:e})=>{const{sendMessage:t,isSending:r,error:s,clearError:i}=_D(),[o,a]=P.useState(""),l=P.useRef(null);P.useEffect(()=>{const g=l.current;g&&(g.style.height="auto",g.style.height=`${Math.min(g.scrollHeight,200)}px`)},[o]);const u=n||r,d=async()=>{if(!o.trim()||u)return;const g=o.trim();a(""),i(),l.current&&(l.current.style.height="auto"),await t(g)},h=g=>{g.key==="Enter"&&!g.shiftKey&&(g.preventDefault(),d())},f=g=>{a(g.target.value),s&&i()};return c.jsxs("div",{className:"chat-input-container","data-testid":"chat-input-container",children:[s&&c.jsxs("div",{className:"input-error",role:"alert","data-testid":"chat-input-error",children:[c.jsxs("span",{children:["Error: ",s]}),c.jsx("button",{className:"dismiss-error",onClick:i,"aria-label":"Dismiss error",children:"ร"})]}),c.jsxs("div",{className:"input-wrapper",children:[c.jsx("textarea",{ref:l,value:o,onChange:f,onKeyDown:h,placeholder:n&&e?e:"Type a message... (Enter to send, Shift+Enter for new line)",disabled:u,rows:1,className:`message-input ${n?"disabled-offline":""}`,"data-testid":"chat-message-input","aria-label":"Message input"}),c.jsx("button",{onClick:d,disabled:!o.trim()||u,className:"send-button",title:n?"Orchestrator offline":"Send message","data-testid":"chat-send-button","aria-label":r?"Sending message":n?"Orchestrator offline":"Send message",children:r?c.jsx("span",{className:"sending-indicator","aria-hidden":"true",children:"โณ"}):c.jsx("span",{className:"send-icon","aria-hidden":"true",children:"โค"})})]}),c.jsxs("div",{className:"input-hints",children:[c.jsxs("span",{children:["Press ",c.jsx("kbd",{children:"Enter"})," to send"]}),c.jsxs("span",{children:[c.jsx("kbd",{children:"Shift"})," + ",c.jsx("kbd",{children:"Enter"})," for new line"]})]})]})};const jte=()=>c.jsxs("div",{className:"typing-indicator","data-testid":"typing-indicator",children:[c.jsx("span",{className:"sender-icon","aria-hidden":"true",children:"๐ค"}),c.jsx("span",{className:"sender-name",children:"Orchestrator"}),c.jsxs("div",{className:"typing-dots","aria-label":"Orchestrator is typing",children:[c.jsx("span",{className:"dot"}),c.jsx("span",{className:"dot"}),c.jsx("span",{className:"dot"})]})]});const Dte=60;function Ote(n,e){return n.length<=e?n:n.slice(0,e)+"..."}function Fte(n){const e=Date.now()-new Date(n).getTime(),t=Math.floor(e/1e3);if(t<60)return"just now";const r=Math.floor(t/60);return r<60?`${r}m ago`:`${Math.floor(r/60)}h ago`}const Ute=()=>{const[n,e]=P.useState(null),[t,r]=P.useState([]),[s,i]=P.useState(!1),[o,a]=P.useState(new Set);P.useEffect(()=>{let M=!1;async function T(){try{const[A,E]=await Promise.all([sn.getQueueStatus(),sn.getPendingMessages()]);M||(e(A),r(E))}catch{}}return T(),()=>{M=!0}},[]);const l=P.useCallback(M=>{e(M)},[]),u=P.useCallback(M=>{r(T=>T.some(A=>A.id===M.id)?T:[...T,M])},[]),d=P.useCallback(M=>{r(T=>T.map(A=>A.id===M.id?{...A,status:"processing",processingStartedAt:M.processingStartedAt}:A))},[]),h=P.useCallback(M=>{r(T=>T.filter(A=>A.id!==M.id))},[]),f=P.useCallback(M=>{r(T=>T.filter(A=>A.id!==M.id))},[]),g=P.useCallback(M=>{r(T=>T.filter(A=>A.id!==M.id)),a(T=>{const A=new Set(T);return A.delete(M.id),A})},[]);P.useEffect(()=>(ut.on("queue:status_update",l),ut.on("queue:message_enqueued",u),ut.on("queue:message_processing",d),ut.on("queue:message_completed",h),ut.on("queue:message_failed",f),ut.on("queue:message_cancelled",g),()=>{ut.off("queue:status_update",l),ut.off("queue:message_enqueued",u),ut.off("queue:message_processing",d),ut.off("queue:message_completed",h),ut.off("queue:message_failed",f),ut.off("queue:message_cancelled",g)}),[l,u,d,h,f,g]);const y=async M=>{a(T=>new Set(T).add(M));try{await sn.cancelQueueMessage(M)}catch{a(T=>{const A=new Set(T);return A.delete(M),A})}},[b,p]=P.useState(!1),m=async()=>{p(!0);try{await sn.clearQueue(),r([]),e(null)}catch{}finally{p(!1)}},v=(n==null?void 0:n.pendingCount)??t.filter(M=>M.status==="pending").length,x=(n==null?void 0:n.isProcessing)??t.some(M=>M.status==="processing");if(v===0&&!x&&t.length===0)return null;const w=[];v>0&&w.push(`${v} queued`),x&&w.push("1 processing");const C=w.join(" ยท ");return c.jsxs("div",{className:"queue-status-bar","data-testid":"queue-status-bar",children:[c.jsxs("div",{className:"queue-status-summary",onClick:()=>i(!s),"data-testid":"queue-status-summary",role:"button",tabIndex:0,onKeyDown:M=>{(M.key==="Enter"||M.key===" ")&&(M.preventDefault(),i(!s))},children:[x&&c.jsx("div",{className:"queue-spinner","data-testid":"queue-spinner"}),c.jsx("span",{className:"queue-status-text",children:C}),c.jsx("button",{className:"queue-clear-all-btn",onClick:M=>{M.stopPropagation(),m()},disabled:b,"data-testid":"queue-clear-all-btn",title:"Clear all queued messages",children:b?"Clearing...":"Clear All"}),c.jsx("button",{className:`queue-toggle-btn${s?" expanded":""}`,"aria-label":s?"Collapse queue":"Expand queue",tabIndex:-1,children:"โผ"})]}),c.jsx("div",{className:`queue-message-list${s?" expanded":""}`,"data-testid":"queue-message-list",children:t.map(M=>c.jsxs("div",{className:`queue-message-item${M.status==="processing"?" processing":""}`,"data-testid":"queue-message-item",children:[c.jsx("div",{className:"queue-item-status",children:M.status==="processing"?c.jsx("div",{className:"queue-spinner"}):c.jsx("span",{"aria-label":"pending",children:"๐"})}),c.jsxs("div",{className:"queue-item-content",children:[c.jsx("p",{className:"queue-item-preview",children:Ote(M.content,Dte)}),c.jsxs("div",{className:"queue-item-meta",children:[c.jsx("span",{className:"queue-source-badge",children:M.source==="slack"?"slack":"web"}),c.jsx("span",{className:"queue-item-time",children:Fte(M.enqueuedAt)})]})]}),c.jsx("button",{className:"queue-cancel-btn",onClick:()=>M.status==="processing"?m():y(M.id),disabled:o.has(M.id)||b,"data-testid":"queue-cancel-btn",children:o.has(M.id)||b?"Cancelling...":"Cancel"})]},M.id))})]})};const Hte=()=>{const{messages:n,isLoading:e,error:t,isTyping:r,currentConversation:s}=_D(),{status:i,isLoading:o}=yL(),a=P.useRef(null);if(P.useEffect(()=>{a.current&&(a.current.scrollTop=a.current.scrollHeight)},[n,r]),e&&n.length===0)return c.jsx("div",{className:"chat-panel loading","data-testid":"chat-panel-loading",children:c.jsxs("div",{className:"loading-spinner",children:[c.jsx("div",{className:"spinner"}),c.jsx("span",{children:"Loading conversation..."})]})});if(t&&n.length===0)return c.jsx("div",{className:"chat-panel error","data-testid":"chat-panel-error",children:c.jsxs("div",{className:"error-message",children:[c.jsx("span",{className:"error-icon",children:"โ ๏ธ"}),c.jsxs("p",{children:["Error: ",t]}),c.jsx("button",{onClick:()=>window.location.reload(),className:"retry-button",children:"Retry"})]})});const l=!o&&i&&!i.isActive;return c.jsxs("div",{className:"chat-panel","data-testid":"chat-panel",children:[c.jsxs("header",{className:"chat-header",children:[c.jsx("h2",{children:(s==null?void 0:s.title)??"Chat with Orchestrator"}),c.jsxs("span",{className:"message-count",children:[n.length," ",n.length===1?"message":"messages"]})]}),c.jsx(Ute,{}),l&&c.jsxs("div",{className:"orchestrator-offline-banner","data-testid":"orchestrator-offline-banner",children:[c.jsx("span",{className:"offline-icon","aria-hidden":"true",children:"โ ๏ธ"}),c.jsxs("div",{className:"offline-content",children:[c.jsx("strong",{children:"Orchestrator Offline"}),c.jsx("p",{children:(i==null?void 0:i.offlineMessage)||(i==null?void 0:i.message)})]}),c.jsx(rh,{to:"/",className:"dashboard-link",children:"Go to Dashboard"})]}),c.jsxs("div",{className:"messages-container",ref:a,"data-testid":"messages-container",children:[n.length===0?c.jsx("div",{className:"empty-chat","data-testid":"empty-chat",children:c.jsxs("div",{className:"welcome-message",children:[c.jsx("h3",{children:"Welcome to Crewly"}),c.jsx("p",{children:"Start a conversation with the Orchestrator."}),c.jsx("p",{children:"Try asking to:"}),c.jsxs("ul",{children:[c.jsx("li",{children:"Create a new project"}),c.jsx("li",{children:"Assign a task to an agent"}),c.jsx("li",{children:"Check project status"}),c.jsx("li",{children:"Configure a team"})]})]})}):c.jsx(c.Fragment,{children:n.map(u=>c.jsx(Lte,{message:u},u.id))}),r&&c.jsx(jte,{}),c.jsx("div",{className:"messages-end"})]}),c.jsx(Bte,{disabled:l,disabledPlaceholder:"Orchestrator is offline. Start it from the Dashboard to chat."})]})};const zte=()=>c.jsxs("div",{className:"chat-page messenger-style",children:[c.jsxs("header",{className:"chat-page-header",children:[c.jsx("h1",{children:"Chat with Orchestrator"}),c.jsx("p",{children:"Communicate with the Crewly orchestrator to manage projects and teams"})]}),c.jsx("div",{className:"chat-page-content",children:c.jsx("main",{className:"chat-page-main",children:c.jsx(Hte,{})})})]}),xm="/api/marketplace";async function Gte(n){const e=new URLSearchParams;n!=null&&n.type&&e.set("type",n.type),n!=null&&n.search&&e.set("search",n.search),n!=null&&n.sort&&e.set("sort",n.sort);const t=e.toString(),r=`${xm}${t?`?${t}`:""}`;return(await yt.get(r)).data.data}async function Wte(n){return(await yt.post(`${xm}/${n}/install`)).data}async function Vte(n){return(await yt.post(`${xm}/${n}/uninstall`)).data}async function Xte(n){return(await yt.post(`${xm}/${n}/update`)).data}async function Kte(){await yt.post(`${xm}/refresh`)}const Jte=[{label:"All",value:"all"},{label:"Skills",value:"skill"},{label:"3D Models",value:"model"},{label:"Roles",value:"role"}],qte=[{label:"Popular",value:"popular"},{label:"Highest Rated",value:"rating"},{label:"Newest",value:"newest"}];function $te(n){return n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)}const Yte={skill:"bg-blue-500/20 text-blue-400",model:"bg-purple-500/20 text-purple-400",role:"bg-emerald-500/20 text-emerald-400"};function Qte(){const[n,e]=P.useState([]),[t,r]=P.useState(!0),[s,i]=P.useState("all"),[o,a]=P.useState(""),[l,u]=P.useState("popular"),[d,h]=P.useState(null),[f,g]=P.useState(null),y=P.useCallback(async()=>{try{r(!0),g(null);const x=await Gte({type:s==="all"?void 0:s,search:o||void 0,sort:l});e(x)}catch{g("Failed to load marketplace items")}finally{r(!1)}},[s,o,l]);P.useEffect(()=>{y()},[y]);const b=async x=>{h(x);try{await Wte(x),await y()}catch{}h(null)},p=async x=>{h(x);try{await Vte(x),await y()}catch{}h(null)},m=async x=>{h(x);try{await Xte(x),await y()}catch{}h(null)},v=async()=>{try{await Kte(),await y()}catch{}};return c.jsxs("div",{className:"p-6 max-w-7xl mx-auto",children:[c.jsxs("div",{className:"flex items-center justify-between mb-6",children:[c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx(hP,{className:"w-6 h-6 text-indigo-400"}),c.jsx("h1",{className:"text-2xl font-bold text-white",children:"Marketplace"})]}),c.jsxs("button",{onClick:v,className:"flex items-center gap-2 px-3 py-1.5 text-sm bg-gray-800 hover:bg-gray-700 text-gray-300 rounded-lg transition-colors","aria-label":"Refresh marketplace",children:[c.jsx(Cu,{className:"w-4 h-4"}),"Refresh"]})]}),c.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-6",children:[c.jsx("div",{className:"flex gap-1 bg-gray-900 rounded-lg p-1",role:"tablist","aria-label":"Filter by type",children:Jte.map(x=>c.jsx("button",{onClick:()=>i(x.value),role:"tab","aria-selected":s===x.value,className:`px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${s===x.value?"bg-gray-800 text-white":"text-gray-400 hover:text-white"}`,children:x.label},x.value))}),c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsxs("div",{className:"relative",children:[c.jsx(UC,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500"}),c.jsx("input",{type:"text",placeholder:"Search...",value:o,onChange:x=>a(x.target.value),"aria-label":"Search marketplace",className:"bg-gray-900 border border-gray-700 rounded-lg pl-9 pr-3 py-1.5 text-sm text-gray-200 placeholder:text-gray-600 focus:outline-none focus:border-indigo-500 w-48"})]}),c.jsx("select",{value:l,onChange:x=>u(x.target.value),"aria-label":"Sort by",className:"bg-gray-900 border border-gray-700 rounded-lg px-3 py-1.5 text-sm text-gray-200 focus:outline-none focus:border-indigo-500",children:qte.map(x=>c.jsx("option",{value:x.value,children:x.label},x.value))})]})]}),t?c.jsx("div",{className:"text-center py-16 text-gray-400",role:"status",children:"Loading marketplace..."}):f?c.jsx("div",{className:"text-center py-16 text-red-400",role:"alert",children:f}):n.length===0?c.jsx("div",{className:"text-center py-16 text-gray-400",children:"No items found."}):c.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:n.map(x=>c.jsxs("div",{className:"bg-gray-900 border border-gray-800 rounded-xl p-5 hover:border-gray-700 transition-colors","data-testid":`marketplace-item-${x.id}`,children:[c.jsxs("div",{className:"flex items-start justify-between mb-3",children:[c.jsxs("div",{className:"flex items-center gap-2",children:[c.jsx("span",{className:`px-2 py-0.5 rounded-full text-xs font-medium ${Yte[x.type]}`,children:x.type}),c.jsxs("span",{className:"text-xs text-gray-500",children:["v",x.version]})]}),x.installStatus==="installed"&&c.jsx(La,{className:"w-4 h-4 text-green-400","aria-label":"Installed"}),x.installStatus==="update_available"&&c.jsx(rT,{className:"w-4 h-4 text-yellow-400","aria-label":"Update available"})]}),c.jsx("h3",{className:"text-base font-semibold text-white mb-1",children:x.name}),c.jsx("p",{className:"text-sm text-gray-400 mb-3 line-clamp-2",children:x.description}),c.jsxs("div",{className:"flex items-center justify-between text-xs text-gray-500 mb-4",children:[c.jsxs("span",{children:["by ",x.author]}),c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsxs("span",{className:"flex items-center gap-1",children:[c.jsx(oU,{className:"w-3 h-3 text-yellow-500"}),x.rating.toFixed(1)]}),c.jsxs("span",{className:"flex items-center gap-1",children:[c.jsx(WF,{className:"w-3 h-3"}),$te(x.downloads)]})]})]}),c.jsxs("div",{className:"flex gap-2",children:[x.installStatus==="not_installed"&&c.jsxs("button",{onClick:()=>b(x.id),disabled:d===x.id,className:"flex-1 flex items-center justify-center gap-1 px-3 py-1.5 text-sm bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg disabled:opacity-50 transition-colors",children:[c.jsx(tU,{className:"w-3 h-3"}),d===x.id?"Installing...":"Install"]}),x.installStatus==="installed"&&c.jsx("button",{onClick:()=>p(x.id),disabled:d===x.id,className:"flex-1 px-3 py-1.5 text-sm bg-gray-800 hover:bg-red-900/50 text-gray-300 hover:text-red-300 rounded-lg disabled:opacity-50 transition-colors",children:d===x.id?"Removing...":"Uninstall"}),x.installStatus==="update_available"&&c.jsxs(c.Fragment,{children:[c.jsxs("button",{onClick:()=>m(x.id),disabled:d===x.id,className:"flex-1 flex items-center justify-center gap-1 px-3 py-1.5 text-sm bg-yellow-600 hover:bg-yellow-500 text-white rounded-lg disabled:opacity-50 transition-colors",children:[c.jsx(rT,{className:"w-3 h-3"}),d===x.id?"Updating...":"Update"]}),c.jsx("button",{onClick:()=>p(x.id),disabled:d===x.id,className:"px-3 py-1.5 text-sm bg-gray-800 hover:bg-red-900/50 text-gray-300 hover:text-red-300 rounded-lg disabled:opacity-50 transition-colors",children:"Remove"})]})]})]},x.id))})]})}function Zte({scope:n,onScopeChange:e,projects:t,selectedProjectPath:r,onProjectChange:s}){return c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsxs("div",{className:"flex gap-1 bg-gray-900 rounded-lg p-1",role:"tablist","aria-label":"Document scope",children:[c.jsxs("button",{role:"tab","aria-selected":n==="global",onClick:()=>e("global"),className:`flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${n==="global"?"bg-gray-800 text-white":"text-gray-400 hover:text-white"}`,children:[c.jsx(rP,{className:"w-3.5 h-3.5"}),"Global"]}),c.jsxs("button",{role:"tab","aria-selected":n==="project",onClick:()=>e("project"),className:`flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${n==="project"?"bg-gray-800 text-white":"text-gray-400 hover:text-white"}`,children:[c.jsx(Os,{className:"w-3.5 h-3.5"}),"Project"]})]}),n==="project"&&c.jsxs("select",{value:r||"",onChange:i=>s(i.target.value),"aria-label":"Select project",className:"bg-gray-900 border border-gray-700 rounded-lg px-3 py-1.5 text-sm text-gray-200 focus:outline-none focus:border-indigo-500",children:[c.jsx("option",{value:"",disabled:!0,children:"Select a project..."}),t.map(i=>c.jsx("option",{value:i.path,children:i.name},i.id))]})]})}function ene({categories:n,selectedCategory:e,onCategoryChange:t}){return c.jsxs("div",{className:"space-y-1",role:"listbox","aria-label":"Filter by category",children:[c.jsx("button",{role:"option","aria-selected":e==="",onClick:()=>t(""),className:`w-full text-left px-3 py-2 rounded-lg text-sm transition-colors ${e===""?"bg-indigo-600/20 text-indigo-400 font-medium":"text-gray-400 hover:bg-gray-800 hover:text-gray-200"}`,children:"All"}),n.map(r=>c.jsx("button",{role:"option","aria-selected":e===r,onClick:()=>t(r),className:`w-full text-left px-3 py-2 rounded-lg text-sm transition-colors ${e===r?"bg-indigo-600/20 text-indigo-400 font-medium":"text-gray-400 hover:bg-gray-800 hover:text-gray-200"}`,children:r},r))]})}function tne(n){try{return new Date(n).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}catch{return n}}function nne({documents:n,loading:e,searchQuery:t,onSearchChange:r,selectedDocId:s,onSelectDocument:i}){return c.jsxs("div",{className:"flex flex-col h-full",children:[c.jsxs("div",{className:"relative mb-4",children:[c.jsx(UC,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500"}),c.jsx("input",{type:"text",placeholder:"Search documents...",value:t,onChange:o=>r(o.target.value),"aria-label":"Search documents",className:"w-full bg-gray-900 border border-gray-700 rounded-lg pl-9 pr-3 py-2 text-sm text-gray-200 placeholder:text-gray-600 focus:outline-none focus:border-indigo-500"})]}),e?c.jsx("div",{className:"text-center py-8 text-gray-400",role:"status",children:"Loading documents..."}):n.length===0?c.jsxs("div",{className:"text-center py-8 text-gray-500",children:[c.jsx(Id,{className:"w-8 h-8 mx-auto mb-2 opacity-50"}),c.jsx("p",{children:"No documents found"})]}):c.jsx("div",{className:"space-y-1 overflow-y-auto flex-1",children:n.map(o=>c.jsxs("button",{onClick:()=>i(o.id),className:`w-full text-left px-3 py-3 rounded-lg transition-colors ${s===o.id?"bg-indigo-600/20 border border-indigo-500/30":"hover:bg-gray-800 border border-transparent"}`,children:[c.jsxs("div",{className:"flex items-start justify-between gap-2",children:[c.jsxs("div",{className:"min-w-0 flex-1",children:[c.jsx("h4",{className:"text-sm font-medium text-gray-200 truncate",children:o.title}),c.jsx("p",{className:"text-xs text-gray-500 mt-0.5 line-clamp-1",children:o.preview})]}),c.jsxs("div",{className:"flex flex-col items-end flex-shrink-0",children:[c.jsx("span",{className:"text-xs px-1.5 py-0.5 rounded bg-gray-800 text-gray-400",children:o.category}),c.jsx("span",{className:"text-xs text-gray-600 mt-1",children:tne(o.updatedAt)})]})]}),o.tags.length>0&&c.jsxs("div",{className:"flex gap-1 mt-1.5 flex-wrap",children:[o.tags.slice(0,3).map(a=>c.jsx("span",{className:"text-xs px-1.5 py-0.5 rounded bg-gray-900 text-gray-500",children:a},a)),o.tags.length>3&&c.jsxs("span",{className:"text-xs text-gray-600",children:["+",o.tags.length-3]})]})]},o.id))})]})}function rne(n){try{return new Date(n).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return n}}function sne({document:n,onEdit:e,onDelete:t}){return c.jsxs("div",{className:"h-full overflow-y-auto",children:[c.jsxs("div",{className:"flex items-start justify-between mb-4",children:[c.jsxs("div",{className:"flex-1 min-w-0",children:[c.jsx("h2",{className:"text-xl font-bold text-white mb-2",children:n.title}),c.jsxs("div",{className:"flex items-center gap-4 text-xs text-gray-500",children:[c.jsx("span",{className:"px-2 py-0.5 rounded bg-gray-800 text-gray-300",children:n.category}),c.jsxs("span",{className:"flex items-center gap-1",children:[c.jsx(Yp,{className:"w-3 h-3"}),n.createdBy]}),c.jsxs("span",{className:"flex items-center gap-1",children:[c.jsx(Ha,{className:"w-3 h-3"}),rne(n.updatedAt)]})]}),n.tags.length>0&&c.jsx("div",{className:"flex gap-1.5 mt-2 flex-wrap",children:n.tags.map(r=>c.jsx("span",{className:"text-xs px-2 py-0.5 rounded-full bg-indigo-500/10 text-indigo-400",children:r},r))})]}),c.jsxs("div",{className:"flex gap-2 ml-4",children:[c.jsxs("button",{onClick:e,className:"flex items-center gap-1.5 px-3 py-1.5 text-sm bg-gray-800 hover:bg-gray-700 text-gray-300 rounded-lg transition-colors","aria-label":"Edit document",children:[c.jsx(aP,{className:"w-3.5 h-3.5"}),"Edit"]}),c.jsxs("button",{onClick:t,className:"flex items-center gap-1.5 px-3 py-1.5 text-sm bg-gray-800 hover:bg-red-900/50 text-gray-300 hover:text-red-300 rounded-lg transition-colors","aria-label":"Delete document",children:[c.jsx($p,{className:"w-3.5 h-3.5"}),"Delete"]})]})]}),c.jsx("div",{className:"border-t border-gray-800 pt-4",children:c.jsx("div",{className:"prose prose-invert prose-sm max-w-none whitespace-pre-wrap text-gray-300 leading-relaxed",children:n.content})})]})}const ine=["SOPs","Team Norms","Architecture","Onboarding","Runbooks","General"];function M3({document:n,categories:e,saving:t,onSave:r,onCancel:s}){const[i,o]=P.useState((n==null?void 0:n.title)||""),[a,l]=P.useState((n==null?void 0:n.content)||""),[u,d]=P.useState((n==null?void 0:n.category)||"General"),[h,f]=P.useState((n==null?void 0:n.tags.join(", "))||""),g=[...new Set([...ine,...e])].sort(),y=p=>{p.preventDefault();const m=h.split(",").map(v=>v.trim()).filter(Boolean);r({title:i,content:a,category:u,tags:m})},b=i.trim().length>0&&a.trim().length>0;return c.jsxs("form",{onSubmit:y,className:"h-full flex flex-col",children:[c.jsxs("div",{className:"flex items-center justify-between mb-4",children:[c.jsx("h2",{className:"text-lg font-bold text-white",children:n?"Edit Document":"New Document"}),c.jsxs("div",{className:"flex gap-2",children:[c.jsxs("button",{type:"button",onClick:s,className:"flex items-center gap-1.5 px-3 py-1.5 text-sm bg-gray-800 hover:bg-gray-700 text-gray-300 rounded-lg transition-colors",children:[c.jsx(Br,{className:"w-3.5 h-3.5"}),"Cancel"]}),c.jsxs("button",{type:"submit",disabled:!b||t,className:"flex items-center gap-1.5 px-3 py-1.5 text-sm bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg disabled:opacity-50 transition-colors",children:[c.jsx(FC,{className:"w-3.5 h-3.5"}),t?"Saving...":"Save"]})]})]}),c.jsxs("div",{className:"space-y-4 flex-1 flex flex-col",children:[c.jsxs("div",{children:[c.jsx("label",{htmlFor:"doc-title",className:"block text-sm font-medium text-gray-300 mb-1",children:"Title"}),c.jsx("input",{id:"doc-title",type:"text",value:i,onChange:p=>o(p.target.value),placeholder:"Document title",className:"w-full bg-gray-900 border border-gray-700 rounded-lg px-3 py-2 text-sm text-gray-200 placeholder:text-gray-600 focus:outline-none focus:border-indigo-500",maxLength:200})]}),c.jsxs("div",{className:"flex gap-4",children:[c.jsxs("div",{className:"flex-1",children:[c.jsx("label",{htmlFor:"doc-category",className:"block text-sm font-medium text-gray-300 mb-1",children:"Category"}),c.jsx("select",{id:"doc-category",value:u,onChange:p=>d(p.target.value),className:"w-full bg-gray-900 border border-gray-700 rounded-lg px-3 py-2 text-sm text-gray-200 focus:outline-none focus:border-indigo-500",children:g.map(p=>c.jsx("option",{value:p,children:p},p))})]}),c.jsxs("div",{className:"flex-1",children:[c.jsx("label",{htmlFor:"doc-tags",className:"block text-sm font-medium text-gray-300 mb-1",children:"Tags (comma-separated)"}),c.jsx("input",{id:"doc-tags",type:"text",value:h,onChange:p=>f(p.target.value),placeholder:"api, backend, auth",className:"w-full bg-gray-900 border border-gray-700 rounded-lg px-3 py-2 text-sm text-gray-200 placeholder:text-gray-600 focus:outline-none focus:border-indigo-500"})]})]}),c.jsxs("div",{className:"flex-1 flex flex-col",children:[c.jsx("label",{htmlFor:"doc-content",className:"block text-sm font-medium text-gray-300 mb-1",children:"Content (Markdown)"}),c.jsx("textarea",{id:"doc-content",value:a,onChange:p=>l(p.target.value),placeholder:"Write your document content in Markdown...",className:"flex-1 min-h-[200px] w-full bg-gray-900 border border-gray-700 rounded-lg px-3 py-2 text-sm text-gray-200 placeholder:text-gray-600 focus:outline-none focus:border-indigo-500 font-mono resize-none"})]})]})]})}function one(){const[n,e]=ZI(),[t,r]=P.useState(n.get("project")?"project":"global"),[s,i]=P.useState([]),[o,a]=P.useState(""),[l,u]=P.useState([]),[d,h]=P.useState([]),[f,g]=P.useState(""),[y,b]=P.useState(""),[p,m]=P.useState(!0),[v,x]=P.useState("list"),[w,C]=P.useState(),[M,T]=P.useState(null),[A,E]=P.useState(!1),[R,B]=P.useState(null);P.useEffect(()=>{sn.getProjects().then(i).catch(()=>{})},[]),P.useEffect(()=>{const j=n.get("project");if(j&&s.length>0){const F=s.find(D=>D.id===j);F&&(r("project"),a(F.path))}},[n,s]);const L=P.useCallback(async()=>{try{if(m(!0),B(null),t==="project"&&!o){u([]),h([]),m(!1);return}const[j,F]=await Promise.all([sn.getKnowledgeDocuments(t,o||void 0,f||void 0,y||void 0),sn.getKnowledgeCategories(t,o||void 0)]);u(j),h(F)}catch{B("Failed to load documents")}finally{m(!1)}},[t,o,f,y]);P.useEffect(()=>{L()},[L]);const O=j=>{r(j),C(void 0),T(null),x("list"),j==="global"&&(a(""),e({}))},z=j=>{a(j),C(void 0),T(null),x("list");const F=s.find(D=>D.path===j);F&&e({project:F.id})},q=async j=>{C(j);try{const F=await sn.getKnowledgeDocument(j,t,o||void 0);T(F),x("view")}catch{B("Failed to load document")}},X=()=>{C(void 0),T(null),x("create")},K=async j=>{E(!0);try{if(v==="create"){const F=await sn.createKnowledgeDocument({...j,scope:t,projectPath:o||void 0});await L(),await q(F)}else M&&(await sn.updateKnowledgeDocument(M.id,{...j,scope:t,projectPath:o||void 0}),await L(),await q(M.id))}catch{B("Failed to save document")}finally{E(!1)}},N=async()=>{if(M)try{await sn.deleteKnowledgeDocument(M.id,t,o||void 0),T(null),C(void 0),x("list"),await L()}catch{B("Failed to delete document")}};return c.jsxs("div",{className:"p-6 max-w-7xl mx-auto h-full flex flex-col",children:[c.jsxs("div",{className:"flex items-center justify-between mb-6",children:[c.jsxs("div",{className:"flex items-center gap-3",children:[c.jsx($b,{className:"w-6 h-6 text-indigo-400"}),c.jsx("h1",{className:"text-2xl font-bold text-white",children:"Knowledge"})]}),c.jsx(Zte,{scope:t,onScopeChange:O,projects:s,selectedProjectPath:o,onProjectChange:z})]}),R&&c.jsxs("div",{className:"mb-4 px-4 py-2 bg-red-900/20 border border-red-500/30 rounded-lg text-sm text-red-400",role:"alert",children:[R,c.jsx("button",{onClick:()=>B(null),className:"ml-2 underline",children:"dismiss"})]}),c.jsxs("div",{className:"flex gap-6 flex-1 min-h-0",children:[c.jsxs("div",{className:"w-44 flex-shrink-0",children:[c.jsx("div",{className:"mb-4",children:c.jsxs("button",{onClick:X,className:"w-full flex items-center justify-center gap-1.5 px-3 py-2 text-sm bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg transition-colors",children:[c.jsx(Ps,{className:"w-4 h-4"}),"New Document"]})}),c.jsx(ene,{categories:d,selectedCategory:f,onCategoryChange:g})]}),c.jsxs("div",{className:"flex-1 min-w-0 flex gap-6",children:[c.jsx("div",{className:`w-80 flex-shrink-0 ${v==="create"||v==="edit"?"hidden lg:block":""}`,children:c.jsx(nne,{documents:l,loading:p,searchQuery:y,onSearchChange:b,selectedDocId:w,onSelectDocument:q})}),c.jsxs("div",{className:"flex-1 min-w-0",children:[v==="view"&&M&&c.jsx(sne,{document:M,onEdit:()=>x("edit"),onDelete:N}),v==="edit"&&M&&c.jsx(M3,{document:M,categories:d,saving:A,onSave:K,onCancel:()=>x("view")}),v==="create"&&c.jsx(M3,{document:null,categories:d,saving:A,onSave:K,onCancel:()=>x("list")}),v==="list"&&!p&&c.jsx("div",{className:"flex items-center justify-center h-full text-gray-500",children:c.jsxs("div",{className:"text-center",children:[c.jsx($b,{className:"w-12 h-12 mx-auto mb-3 opacity-30"}),c.jsx("p",{children:"Select a document to view"}),c.jsx("p",{className:"text-sm mt-1",children:"or create a new one"})]})})]})]})]})]})}function ane(){return c.jsx(S8,{children:c.jsx(fU,{children:c.jsx(EF,{children:c.jsx(vF,{children:c.jsxs(Ks,{path:"/",element:c.jsx(kH,{}),children:[c.jsx(Ks,{index:!0,element:c.jsx(IH,{})}),c.jsx(Ks,{path:"projects",element:c.jsx(BH,{})}),c.jsx(Ks,{path:"projects/:id",element:c.jsx(WH,{})}),c.jsx(Ks,{path:"teams",element:c.jsx(tz,{})}),c.jsx(Ks,{path:"teams/:id",element:c.jsx(cz,{})}),c.jsx(Ks,{path:"assignments",element:c.jsx(gz,{})}),c.jsx(Ks,{path:"scheduled-checkins",element:c.jsx(bz,{})}),c.jsx(Ks,{path:"factory",element:c.jsx(nte,{})}),c.jsx(Ks,{path:"marketplace",element:c.jsx(Qte,{})}),c.jsx(Ks,{path:"knowledge",element:c.jsx(one,{})}),c.jsx(Ks,{path:"settings",element:c.jsx(Cte,{})}),c.jsx(Ks,{path:"chat",element:c.jsx(Mte,{children:c.jsx(zte,{})})})]})})})})})}ZS.createRoot(document.getElementById("root")).render(c.jsx(Cn.StrictMode,{children:c.jsx(ane,{})}));
|
|
4919
|
-
//# sourceMappingURL=index-
|
|
4919
|
+
//# sourceMappingURL=index-419da091.js.map
|