prime-dev-cli 1.0.16 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/server/.next/BUILD_ID +1 -1
  2. package/dist/server/.next/app-build-manifest.json +2 -2
  3. package/dist/server/.next/build-manifest.json +2 -2
  4. package/dist/server/.next/cache/.rscinfo +1 -1
  5. package/dist/server/.next/cache/.tsbuildinfo +1 -1
  6. package/dist/server/.next/cache/eslint/.cache_1qa5vxt +1 -1
  7. package/dist/server/.next/fallback-build-manifest.json +2 -2
  8. package/dist/server/.next/next-minimal-server.js.nft.json +1 -1
  9. package/dist/server/.next/next-server.js.nft.json +1 -1
  10. package/dist/server/.next/prerender-manifest.json +9 -9
  11. package/dist/server/.next/server/app/_not-found.html +1 -1
  12. package/dist/server/.next/server/app/_not-found.rsc +1 -1
  13. package/dist/server/.next/server/app/configuration/page/app-build-manifest.json +1 -1
  14. package/dist/server/.next/server/app/configuration/page_client-reference-manifest.js +1 -1
  15. package/dist/server/.next/server/app/configuration.html +1 -1
  16. package/dist/server/.next/server/app/configuration.rsc +2 -2
  17. package/dist/server/.next/server/app/index.html +1 -1
  18. package/dist/server/.next/server/app/index.rsc +1 -1
  19. package/dist/server/.next/server/app/initialization/page/app-build-manifest.json +1 -1
  20. package/dist/server/.next/server/app/initialization/page_client-reference-manifest.js +1 -1
  21. package/dist/server/.next/server/app/initialization.html +1 -1
  22. package/dist/server/.next/server/app/initialization.rsc +2 -2
  23. package/dist/server/.next/server/chunks/[root-of-the-server]__072f5c45._.js +7 -7
  24. package/dist/server/.next/server/chunks/[root-of-the-server]__072f5c45._.js.map +1 -1
  25. package/dist/server/.next/server/chunks/[root-of-the-server]__7fc974c9._.js +10 -10
  26. package/dist/server/.next/server/chunks/[root-of-the-server]__7fc974c9._.js.map +1 -1
  27. package/dist/server/.next/server/chunks/[root-of-the-server]__899d82eb._.js +6 -6
  28. package/dist/server/.next/server/chunks/[root-of-the-server]__899d82eb._.js.map +1 -1
  29. package/dist/server/.next/server/chunks/[root-of-the-server]__f6d4fb58._.js +6 -6
  30. package/dist/server/.next/server/chunks/[root-of-the-server]__f6d4fb58._.js.map +1 -1
  31. package/dist/server/.next/server/chunks/ssr/_5d353cf8._.js +1 -1
  32. package/dist/server/.next/server/chunks/ssr/_5d353cf8._.js.map +1 -1
  33. package/dist/server/.next/server/chunks/ssr/packages_server_src_7cef6dbd._.js +1 -1
  34. package/dist/server/.next/server/chunks/ssr/packages_server_src_7cef6dbd._.js.map +1 -1
  35. package/dist/server/.next/server/pages/404.html +1 -1
  36. package/dist/server/.next/server/pages/500.html +1 -1
  37. package/dist/server/.next/server/server-reference-manifest.js +1 -1
  38. package/dist/server/.next/server/server-reference-manifest.json +1 -1
  39. package/dist/server/.next/static/chunks/{684226c5a0f22bc1.js → 5f8beee58a024d75.js} +2 -2
  40. package/dist/server/.next/static/chunks/{765c1fd313250591.js.map → 7e0a49ac2b139df9.js.map} +1 -1
  41. package/dist/server/.next/static/chunks/{2c0e57fbc9520adc.js → 9650e7136a9bfc30.js} +2 -2
  42. package/dist/server/.next/static/chunks/f31695470ae3a484.js.map +1 -0
  43. package/dist/server/.next/trace +1 -1
  44. package/package.json +1 -1
  45. package/dist/server/.next/static/chunks/2c669537f498f2db.js.map +0 -1
  46. /package/dist/server/.next/static/{bC3bTGQyq6cbRR_M7T8N6 → Xoig0sIWc0oIgbMH6U6Ew}/_buildManifest.js +0 -0
  47. /package/dist/server/.next/static/{bC3bTGQyq6cbRR_M7T8N6 → Xoig0sIWc0oIgbMH6U6Ew}/_clientMiddlewareManifest.json +0 -0
  48. /package/dist/server/.next/static/{bC3bTGQyq6cbRR_M7T8N6 → Xoig0sIWc0oIgbMH6U6Ew}/_ssgManifest.js +0 -0
@@ -1,3 +1,3 @@
1
- module.exports={67450:a=>{"use strict";var{g:b,__dirname:c}=a;{a.s({PROJECT_CONFIG_PATH:()=>c,ProjectStatus:()=>f,WORKSPACE_CONFIG:()=>b});var d=a.i(13442),e=a.i(30331);let b={WORKSPACE_ROOT:(0,e.join)((0,d.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,d.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},c=(0,e.join)((0,d.homedir)(),".prime-projects.json");var f=function(a){return a.PENDING="pending",a.EXISTING="existing",a.CLONING="cloning",a.SUCCESS="success",a.FAILED="failed",a.RETRYING="retrying",a.INCOMPLETE="incomplete",a}({})}},90250:a=>{"use strict";var{g:b,__dirname:c}=a;{a.s({default:()=>b});var d=a.i(99559),e=a.i(57560),f=a.i(40490),g=a.i(50923),h=a.i(67450);let b=()=>{let a=(0,f.useRouter)(),[b,c]=(0,e.useState)({isInitializing:!1,isCompleted:!1,isLoading:!0,hasCompleted:!1,globalProgress:0,globalMessage:"正在检查工作空间状态...",projects:{}}),[i,j]=(0,e.useState)({});(0,e.useEffect)(()=>{k()},[]);let k=async()=>{try{c(a=>({...a,isLoading:!0,globalMessage:"正在检查工作空间状态..."}));let a=await fetch("/api/check-workspace"),b=await a.json();if(b.success){let a={};b.projects.forEach(b=>{a[b.name]={name:b.name,status:b.status,progress:100*(b.status===h.ProjectStatus.EXISTING),message:b.message,canRetry:!1,needsCleanup:b.needsCleanup||!1}}),c(c=>({...c,isLoading:!1,projects:a,globalMessage:b.message||"检查完成"}))}else c(a=>({...a,isLoading:!1,globalMessage:b.error||"检查工作空间状态失败"}))}catch(a){c(a=>({...a,isLoading:!1,globalMessage:"无法连接到服务器,请刷新页面重试"})),console.error("检查工作空间状态失败:",a)}},l=a=>{switch(a.type){case"initialization":case"workspace_created":case"projects_loaded":if(c(b=>({...b,globalProgress:a.progress||0,globalMessage:a.message||""})),a.projects&&Array.isArray(a.projects)){let b={};a.projects.forEach(a=>{b[a]={name:a,status:h.ProjectStatus.PENDING,progress:0,message:"等待开始...",canRetry:!1}}),c(a=>({...a,projects:b}))}break;case"project_existing":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,globalMessage:a.message??"",projects:{...c.projects,[b]:{...c.projects[b],status:h.ProjectStatus.EXISTING,message:"项目已存在",progress:100,canRetry:!1}}}))}break;case"project_start":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,globalMessage:a.message??"",projects:{...c.projects,[b]:{...c.projects[b],status:h.ProjectStatus.CLONING,message:"开始克隆...",progress:0}}}))}break;case"project_progress":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,projects:{...c.projects,[b]:{...c.projects[b],message:a.message??"",progress:Math.min(a.progress??0,100)}}}))}break;case"project_success":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,projects:{...c.projects,[b]:{...c.projects[b],status:h.ProjectStatus.SUCCESS,message:"克隆成功",progress:100,canRetry:!1}}}))}break;case"project_failed":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,projects:{...c.projects,[b]:{...c.projects[b],status:h.ProjectStatus.FAILED,message:"克隆失败",error:a.error,canRetry:!0}}}))}break;case"command_log":if(a.projectName&&a.logType&&void 0!==a.content&&a.timestamp){let b=a.projectName,d=a.logType,e=a.content,f=a.timestamp;c(a=>({...a,projects:{...a.projects,[b]:{...a.projects[b],logs:[...a.projects[b]?.logs||[],{type:d,content:e,timestamp:f}].slice(-1e3)}}}))}break;case"completion":c(b=>({...b,isInitializing:!1,isCompleted:!0,hasCompleted:!0,globalProgress:100,globalMessage:a.message??"初始化完成",completionSummary:a.result?{success:a.result.success,totalProjects:a.result.totalProjects,successCount:a.result.successCount,failedCount:a.result.failedCount,duration:a.result.duration}:void 0}));break;case"error":c(b=>({...b,isInitializing:!1,hasCompleted:!0,globalMessage:a.message??"发生错误",globalProgress:a.progress??b.globalProgress}))}},m=async a=>{c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isOpening:!0}}}));try{let b=await fetch("/api/open-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:a})}),d=await b.json();c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isOpening:!1}}})),d.success||console.error("打开项目失败:",d.error)}catch(b){c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isOpening:!1}}})),console.error("打开项目失败:",b)}},n=async a=>{c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isCleaningUp:!0}}}));try{let b=await fetch("/api/cleanup-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:a})}),d=await b.json();d.success?c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],status:h.ProjectStatus.PENDING,message:"已清理,待克隆",isCleaningUp:!1,needsCleanup:!1}}})):c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isCleaningUp:!1,error:d.error}}}))}catch(b){c(c=>({...c,projects:{...c.projects,[a]:{...c.projects[a],isCleaningUp:!1,error:b instanceof Error?b.message:String(b)}}}))}},o=async a=>{c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],status:h.ProjectStatus.RETRYING,message:"正在重试...",progress:0,canRetry:!1}}}));try{let b=await fetch("/api/retry-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:a})}),d=await b.json();c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],status:d.success?h.ProjectStatus.SUCCESS:h.ProjectStatus.FAILED,message:d.message,error:d.error,progress:d.success?100:b.projects[a].progress,canRetry:!d.success}}}))}catch(b){c(c=>({...c,projects:{...c.projects,[a]:{...c.projects[a],status:h.ProjectStatus.FAILED,message:"重试失败",error:b instanceof Error?b.message:String(b),canRetry:!0}}}))}},p=a=>{switch(a){case h.ProjectStatus.EXISTING:case h.ProjectStatus.SUCCESS:return"text-green-600 bg-green-50 border-green-200";case h.ProjectStatus.FAILED:return"text-red-600 bg-red-50 border-red-200";case h.ProjectStatus.INCOMPLETE:return"text-orange-600 bg-orange-50 border-orange-200";case h.ProjectStatus.CLONING:case h.ProjectStatus.RETRYING:return"text-blue-600 bg-blue-50 border-blue-200";case h.ProjectStatus.PENDING:default:return"text-gray-600 bg-gray-50 border-gray-200"}},q=a=>{switch(a){case h.ProjectStatus.PENDING:return"待克隆";case h.ProjectStatus.EXISTING:return"已存在";case h.ProjectStatus.CLONING:return"克隆中";case h.ProjectStatus.SUCCESS:return"成功";case h.ProjectStatus.FAILED:return"失败";case h.ProjectStatus.INCOMPLETE:return"不完整";case h.ProjectStatus.RETRYING:return"重试中";default:return"未知"}},r=()=>{let a=Object.values(b.projects);return a.length>0&&a.every(a=>a.status===h.ProjectStatus.EXISTING)},s=b=>{a.push(`/configuration?project=${encodeURIComponent(b)}`)};return(0,d.jsxs)("div",{className:"container mx-auto p-4 sm:p-6 md:p-8",children:[(0,d.jsxs)("div",{className:"flex justify-between items-center mb-6",children:[(0,d.jsx)("h1",{className:"text-2xl font-bold",children:"项目初始化"}),b.isLoading?(0,d.jsx)(g.Button,{disabled:!0,children:"检查中..."}):(0,d.jsx)(g.Button,{onClick:()=>{c(a=>({...a,isInitializing:!0,isCompleted:!1,hasCompleted:!1,globalProgress:0,globalMessage:"正在连接服务器...",projects:{},completionSummary:void 0}));let a=new EventSource("/api/initialize-workspace");a.onmessage=a=>{try{let b=JSON.parse(a.data);l(b)}catch(a){console.error("解析 SSE 消息失败:",a)}},a.onerror=()=>{c(a=>a.hasCompleted?a:{...a,isInitializing:!1,globalMessage:"连接服务器失败,请重试"}),a.close()},a.addEventListener("error",()=>{a.close()})},disabled:b.isInitializing,children:b.isInitializing?"初始化中...":"创建项目空间"})]}),(b.isInitializing||b.isCompleted)&&!r()&&(0,d.jsxs)("div",{className:"mb-6 p-4 bg-gray-50 rounded-lg",children:[(0,d.jsxs)("div",{className:"flex justify-between items-center mb-2",children:[(0,d.jsx)("span",{className:"text-sm font-medium",children:b.globalMessage}),(0,d.jsxs)("span",{className:"text-sm text-gray-600",children:[b.globalProgress,"%"]})]}),(0,d.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-2",children:(0,d.jsx)("div",{className:"bg-blue-600 h-2 rounded-full transition-all duration-300",style:{width:`${b.globalProgress}%`}})})]}),b.completionSummary&&!r()&&(0,d.jsxs)("div",{className:`mb-6 p-4 rounded-lg border ${b.completionSummary.success?"bg-green-50 border-green-200":"bg-yellow-50 border-yellow-200"}`,children:[(0,d.jsx)("h3",{className:"font-semibold mb-2",children:"初始化完成"}),(0,d.jsxs)("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-sm",children:[(0,d.jsxs)("div",{children:["总项目数: ",b.completionSummary.totalProjects]}),(0,d.jsxs)("div",{className:"text-green-600",children:["成功: ",b.completionSummary.successCount]}),(0,d.jsxs)("div",{className:"text-red-600",children:["失败: ",b.completionSummary.failedCount]}),(0,d.jsxs)("div",{children:["耗时: ",Math.round(b.completionSummary.duration/1e3),"s"]})]})]}),(0,d.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",children:Object.keys(b.projects).length>0?Object.values(b.projects).map(a=>(0,d.jsxs)("div",{className:`border rounded-lg p-4 ${p(a.status)}`,children:[(0,d.jsxs)("div",{className:"flex justify-between items-start mb-2",children:[(0,d.jsx)("h2",{className:"font-semibold cursor-pointer hover:text-blue-600 transition-colors",onClick:()=>s(a.name),title:"点击进入项目配置",children:a.name}),(0,d.jsx)("span",{className:"text-xs px-2 py-1 rounded-full bg-white",children:q(a.status)})]}),(0,d.jsx)("p",{className:"text-sm mb-2",children:a.message}),a.status===h.ProjectStatus.CLONING||a.status===h.ProjectStatus.RETRYING?(0,d.jsxs)("div",{className:"mb-2",children:[(0,d.jsx)("div",{className:"w-full bg-white rounded-full h-1",children:(0,d.jsx)("div",{className:"bg-current h-1 rounded-full transition-all duration-300",style:{width:`${a.progress}%`}})}),(0,d.jsxs)("span",{className:"text-xs",children:[a.progress,"%"]})]}):null,a.error&&(0,d.jsx)("p",{className:"text-xs text-red-600 mb-2",children:a.error}),(0,d.jsxs)("div",{className:"space-y-2",children:[a.canRetry&&(0,d.jsx)(g.Button,{size:"sm",variant:"outline",onClick:()=>o(a.name),className:"w-full",children:"重试"}),a.needsCleanup&&a.status===h.ProjectStatus.INCOMPLETE&&(0,d.jsx)(g.Button,{size:"sm",variant:"destructive",onClick:()=>n(a.name),disabled:a.isCleaningUp,className:"w-full",children:a.isCleaningUp?"清理中...":"清理项目"}),(a.status===h.ProjectStatus.EXISTING||a.status===h.ProjectStatus.SUCCESS)&&(0,d.jsx)(g.Button,{size:"sm",variant:"default",onClick:()=>m(a.name),disabled:a.isOpening,className:"w-full",children:a.isOpening?"打开中...":"在 Cursor 中打开"}),a.logs&&a.logs.length>0&&(0,d.jsx)(g.Button,{size:"sm",variant:"outline",onClick:()=>j(b=>({...b,[a.name]:!b[a.name]})),className:"w-full",children:i[a.name]?"隐藏日志":`查看日志 (${a.logs.length})`})]}),i[a.name]&&a.logs&&a.logs.length>0&&(0,d.jsx)("div",{className:"mt-3 border-t pt-3",children:(0,d.jsx)("div",{className:"bg-black text-white rounded text-xs font-mono p-2 max-h-48 overflow-y-auto",children:a.logs.map((a,b)=>(0,d.jsxs)("div",{className:`mb-1 ${"stderr"===a.type?"text-red-400":"progress"===a.type?"text-yellow-400":"text-green-400"}`,children:[(0,d.jsx)("span",{className:"text-gray-500 mr-2",children:new Date(a.timestamp).toLocaleTimeString()}),(0,d.jsxs)("span",{className:"text-blue-400 mr-2",children:["[",a.type,"]"]}),(0,d.jsx)("span",{className:"whitespace-pre-wrap",children:a.content})]},b))})})]},a.name)):(0,d.jsx)("div",{className:"col-span-full text-center text-gray-500 py-8",children:b.isLoading?"正在检查项目状态...":b.isInitializing?"正在加载项目...":'点击"创建项目空间"开始初始化'})})]})}}}};
1
+ module.exports={67450:a=>{"use strict";var{g:b,__dirname:c}=a;{a.s({PROJECT_CONFIG_PATH:()=>c,ProjectStatus:()=>f,WORKSPACE_CONFIG:()=>b});var d=a.i(13442),e=a.i(30331);let b={WORKSPACE_ROOT:(0,e.join)((0,d.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,d.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},c=(0,e.join)((0,d.homedir)(),".prime-projects.json");var f=function(a){return a.PENDING="pending",a.EXISTING="existing",a.CLONING="cloning",a.SUCCESS="success",a.FAILED="failed",a.RETRYING="retrying",a.INCOMPLETE="incomplete",a}({})}},90250:a=>{"use strict";var{g:b,__dirname:c}=a;{a.s({default:()=>b});var d=a.i(99559),e=a.i(57560),f=a.i(40490),g=a.i(50923),h=a.i(67450);let b=()=>{let a=(0,f.useRouter)(),[b,c]=(0,e.useState)({isInitializing:!1,isCompleted:!1,isLoading:!0,hasCompleted:!1,globalProgress:0,globalMessage:"正在检查工作空间状态...",projects:{}}),[i,j]=(0,e.useState)({});(0,e.useEffect)(()=>{k()},[]);let k=async()=>{try{c(a=>({...a,isLoading:!0,globalMessage:"正在检查工作空间状态..."}));let a=await fetch("/api/check-workspace"),b=await a.json();if(b.success){let a={};b.projects.forEach(b=>{a[b.name]={name:b.name,status:b.status,progress:100*(b.status===h.ProjectStatus.EXISTING),message:b.message,canRetry:!1,needsCleanup:b.needsCleanup||!1}}),c(c=>({...c,isLoading:!1,projects:a,globalMessage:b.message||"检查完成"}))}else c(a=>({...a,isLoading:!1,globalMessage:b.error||"检查工作空间状态失败"}))}catch(a){c(a=>({...a,isLoading:!1,globalMessage:"无法连接到服务器,请刷新页面重试"})),console.error("检查工作空间状态失败:",a)}},l=a=>{switch(a.type){case"initialization":case"workspace_created":case"projects_loaded":if(c(b=>({...b,globalProgress:a.progress||0,globalMessage:a.message||""})),a.projects&&Array.isArray(a.projects)){let b={};a.projects.forEach(a=>{b[a]={name:a,status:h.ProjectStatus.PENDING,progress:0,message:"等待开始...",canRetry:!1}}),c(a=>({...a,projects:b}))}break;case"project_existing":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,globalMessage:a.message??"",projects:{...c.projects,[b]:{...c.projects[b],status:h.ProjectStatus.EXISTING,message:"项目已存在",progress:100,canRetry:!1}}}))}break;case"project_start":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,globalMessage:a.message??"",projects:{...c.projects,[b]:{...c.projects[b],status:h.ProjectStatus.CLONING,message:"开始克隆...",progress:0}}}))}break;case"project_progress":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,projects:{...c.projects,[b]:{...c.projects[b],message:a.message??"",progress:Math.min(a.progress??0,100)}}}))}break;case"project_success":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,projects:{...c.projects,[b]:{...c.projects[b],status:h.ProjectStatus.SUCCESS,message:"克隆成功",progress:100,canRetry:!1}}}))}break;case"project_failed":if(a.projectName){let b=a.projectName;c(c=>({...c,globalProgress:a.progress??c.globalProgress,projects:{...c.projects,[b]:{...c.projects[b],status:h.ProjectStatus.FAILED,message:"克隆失败",error:a.error,canRetry:!0}}}))}break;case"command_log":if(a.projectName&&a.logType&&void 0!==a.content&&a.timestamp){let b=a.projectName,d=a.logType,e=a.content,f=a.timestamp;c(a=>({...a,projects:{...a.projects,[b]:{...a.projects[b],logs:[...a.projects[b]?.logs||[],{type:d,content:e,timestamp:f}].slice(-1e3)}}}))}break;case"completion":c(b=>({...b,isInitializing:!1,isCompleted:!0,hasCompleted:!0,globalProgress:100,globalMessage:a.message??"初始化完成",completionSummary:a.result?{success:a.result.success,totalProjects:a.result.totalProjects,successCount:a.result.successCount,failedCount:a.result.failedCount,duration:a.result.duration}:void 0}));break;case"error":c(b=>({...b,isInitializing:!1,hasCompleted:!0,globalMessage:a.message??"发生错误",globalProgress:a.progress??b.globalProgress}))}},m=async a=>{c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isOpening:!0}}}));try{let b=await fetch("/api/open-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:a})}),d=await b.json();if(d.success&&d.cursorUrl){let a=document.createElement("a");a.href=d.cursorUrl,a.style.display="none",document.body.appendChild(a),a.click(),document.body.removeChild(a)}else console.error("打开项目失败:",d.error);c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isOpening:!1}}}))}catch(b){c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isOpening:!1}}})),console.error("打开项目失败:",b)}},n=async a=>{c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isCleaningUp:!0}}}));try{let b=await fetch("/api/cleanup-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:a})}),d=await b.json();d.success?c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],status:h.ProjectStatus.PENDING,message:"已清理,待克隆",isCleaningUp:!1,needsCleanup:!1}}})):c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],isCleaningUp:!1,error:d.error}}}))}catch(b){c(c=>({...c,projects:{...c.projects,[a]:{...c.projects[a],isCleaningUp:!1,error:b instanceof Error?b.message:String(b)}}}))}},o=async a=>{c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],status:h.ProjectStatus.RETRYING,message:"正在重试...",progress:0,canRetry:!1}}}));try{let b=await fetch("/api/retry-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:a})}),d=await b.json();c(b=>({...b,projects:{...b.projects,[a]:{...b.projects[a],status:d.success?h.ProjectStatus.SUCCESS:h.ProjectStatus.FAILED,message:d.message,error:d.error,progress:d.success?100:b.projects[a].progress,canRetry:!d.success}}}))}catch(b){c(c=>({...c,projects:{...c.projects,[a]:{...c.projects[a],status:h.ProjectStatus.FAILED,message:"重试失败",error:b instanceof Error?b.message:String(b),canRetry:!0}}}))}},p=a=>{switch(a){case h.ProjectStatus.EXISTING:case h.ProjectStatus.SUCCESS:return"text-green-600 bg-green-50 border-green-200";case h.ProjectStatus.FAILED:return"text-red-600 bg-red-50 border-red-200";case h.ProjectStatus.INCOMPLETE:return"text-orange-600 bg-orange-50 border-orange-200";case h.ProjectStatus.CLONING:case h.ProjectStatus.RETRYING:return"text-blue-600 bg-blue-50 border-blue-200";case h.ProjectStatus.PENDING:default:return"text-gray-600 bg-gray-50 border-gray-200"}},q=a=>{switch(a){case h.ProjectStatus.PENDING:return"待克隆";case h.ProjectStatus.EXISTING:return"已存在";case h.ProjectStatus.CLONING:return"克隆中";case h.ProjectStatus.SUCCESS:return"成功";case h.ProjectStatus.FAILED:return"失败";case h.ProjectStatus.INCOMPLETE:return"不完整";case h.ProjectStatus.RETRYING:return"重试中";default:return"未知"}},r=()=>{let a=Object.values(b.projects);return a.length>0&&a.every(a=>a.status===h.ProjectStatus.EXISTING)},s=b=>{a.push(`/configuration?project=${encodeURIComponent(b)}`)};return(0,d.jsxs)("div",{className:"container mx-auto p-4 sm:p-6 md:p-8",children:[(0,d.jsxs)("div",{className:"flex justify-between items-center mb-6",children:[(0,d.jsx)("h1",{className:"text-2xl font-bold",children:"项目初始化"}),b.isLoading?(0,d.jsx)(g.Button,{disabled:!0,children:"检查中..."}):(0,d.jsx)(g.Button,{onClick:()=>{c(a=>({...a,isInitializing:!0,isCompleted:!1,hasCompleted:!1,globalProgress:0,globalMessage:"正在连接服务器...",projects:{},completionSummary:void 0}));let a=new EventSource("/api/initialize-workspace");a.onmessage=a=>{try{let b=JSON.parse(a.data);l(b)}catch(a){console.error("解析 SSE 消息失败:",a)}},a.onerror=()=>{c(a=>a.hasCompleted?a:{...a,isInitializing:!1,globalMessage:"连接服务器失败,请重试"}),a.close()},a.addEventListener("error",()=>{a.close()})},disabled:b.isInitializing,children:b.isInitializing?"初始化中...":"创建项目空间"})]}),(b.isInitializing||b.isCompleted)&&!r()&&(0,d.jsxs)("div",{className:"mb-6 p-4 bg-gray-50 rounded-lg",children:[(0,d.jsxs)("div",{className:"flex justify-between items-center mb-2",children:[(0,d.jsx)("span",{className:"text-sm font-medium",children:b.globalMessage}),(0,d.jsxs)("span",{className:"text-sm text-gray-600",children:[b.globalProgress,"%"]})]}),(0,d.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-2",children:(0,d.jsx)("div",{className:"bg-blue-600 h-2 rounded-full transition-all duration-300",style:{width:`${b.globalProgress}%`}})})]}),b.completionSummary&&!r()&&(0,d.jsxs)("div",{className:`mb-6 p-4 rounded-lg border ${b.completionSummary.success?"bg-green-50 border-green-200":"bg-yellow-50 border-yellow-200"}`,children:[(0,d.jsx)("h3",{className:"font-semibold mb-2",children:"初始化完成"}),(0,d.jsxs)("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-sm",children:[(0,d.jsxs)("div",{children:["总项目数: ",b.completionSummary.totalProjects]}),(0,d.jsxs)("div",{className:"text-green-600",children:["成功: ",b.completionSummary.successCount]}),(0,d.jsxs)("div",{className:"text-red-600",children:["失败: ",b.completionSummary.failedCount]}),(0,d.jsxs)("div",{children:["耗时: ",Math.round(b.completionSummary.duration/1e3),"s"]})]})]}),(0,d.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",children:Object.keys(b.projects).length>0?Object.values(b.projects).map(a=>(0,d.jsxs)("div",{className:`border rounded-lg p-4 ${p(a.status)}`,children:[(0,d.jsxs)("div",{className:"flex justify-between items-start mb-2",children:[(0,d.jsx)("h2",{className:"font-semibold cursor-pointer hover:text-blue-600 transition-colors",onClick:()=>s(a.name),title:"点击进入项目配置",children:a.name}),(0,d.jsx)("span",{className:"text-xs px-2 py-1 rounded-full bg-white",children:q(a.status)})]}),(0,d.jsx)("p",{className:"text-sm mb-2",children:a.message}),a.status===h.ProjectStatus.CLONING||a.status===h.ProjectStatus.RETRYING?(0,d.jsxs)("div",{className:"mb-2",children:[(0,d.jsx)("div",{className:"w-full bg-white rounded-full h-1",children:(0,d.jsx)("div",{className:"bg-current h-1 rounded-full transition-all duration-300",style:{width:`${a.progress}%`}})}),(0,d.jsxs)("span",{className:"text-xs",children:[a.progress,"%"]})]}):null,a.error&&(0,d.jsx)("p",{className:"text-xs text-red-600 mb-2",children:a.error}),(0,d.jsxs)("div",{className:"space-y-2",children:[a.canRetry&&(0,d.jsx)(g.Button,{size:"sm",variant:"outline",onClick:()=>o(a.name),className:"w-full",children:"重试"}),a.needsCleanup&&a.status===h.ProjectStatus.INCOMPLETE&&(0,d.jsx)(g.Button,{size:"sm",variant:"destructive",onClick:()=>n(a.name),disabled:a.isCleaningUp,className:"w-full",children:a.isCleaningUp?"清理中...":"清理项目"}),(a.status===h.ProjectStatus.EXISTING||a.status===h.ProjectStatus.SUCCESS)&&(0,d.jsx)(g.Button,{size:"sm",variant:"default",onClick:()=>m(a.name),disabled:a.isOpening,className:"w-full",children:a.isOpening?"打开中...":"在 Cursor 中打开"}),a.logs&&a.logs.length>0&&(0,d.jsx)(g.Button,{size:"sm",variant:"outline",onClick:()=>j(b=>({...b,[a.name]:!b[a.name]})),className:"w-full",children:i[a.name]?"隐藏日志":`查看日志 (${a.logs.length})`})]}),i[a.name]&&a.logs&&a.logs.length>0&&(0,d.jsx)("div",{className:"mt-3 border-t pt-3",children:(0,d.jsx)("div",{className:"bg-black text-white rounded text-xs font-mono p-2 max-h-48 overflow-y-auto",children:a.logs.map((a,b)=>(0,d.jsxs)("div",{className:`mb-1 ${"stderr"===a.type?"text-red-400":"progress"===a.type?"text-yellow-400":"text-green-400"}`,children:[(0,d.jsx)("span",{className:"text-gray-500 mr-2",children:new Date(a.timestamp).toLocaleTimeString()}),(0,d.jsxs)("span",{className:"text-blue-400 mr-2",children:["[",a.type,"]"]}),(0,d.jsx)("span",{className:"whitespace-pre-wrap",children:a.content})]},b))})})]},a.name)):(0,d.jsx)("div",{className:"col-span-full text-center text-gray-500 py-8",children:b.isLoading?"正在检查项目状态...":b.isInitializing?"正在加载项目...":'点击"创建项目空间"开始初始化'})})]})}}}};
2
2
 
3
3
  //# sourceMappingURL=packages_server_src_7cef6dbd._.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["turbopack:///[project]/packages/server/src/lib/workspace-types.ts","turbopack:///[project]/packages/server/src/components/project-initializer.tsx"],"sourcesContent":["import { homedir, cpus } from 'os';\nimport { join } from 'path';\n\n/**\n * 工作空间配置常量\n */\nexport const WORKSPACE_CONFIG = {\n // 工作空间根目录路径\n WORKSPACE_ROOT: join(homedir(), 'Documents', 'prime-workspace'),\n\n // Git 操作超时时间 (毫秒)\n GIT_TIMEOUT: 300000, // 5分钟\n\n // 最大并发克隆数量(基于CPU核心数,最小2个,最大8个)\n MAX_CONCURRENT_CLONES: Math.max(2, Math.min(cpus().length, 8)),\n\n // 重试次数限制\n MAX_RETRY_ATTEMPTS: 3,\n} as const;\n\nexport const PROJECT_CONFIG_PATH = join(homedir(), '.prime-projects.json');\n\nexport interface ProjectConfig {\n repo: string;\n mockingIntercept?: boolean;\n mockOpen?: boolean;\n envs: {\n [envName: string]: {\n host: string;\n currentProxy: string;\n proxyEnv: {\n [key: string]: string;\n };\n envFileName: string;\n proxyKey: string;\n subApps?: string[];\n };\n };\n}\n\nexport interface ProjectsConfig {\n [projectName: string]: ProjectConfig;\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n INCOMPLETE = 'incomplete', // 不完整的项目,需要清理\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n onLog?: (projectName: string, logType: 'stdout' | 'stderr' | 'progress', content: string) => void;\n} ","\"use client\";\n\nimport { useEffect, useState } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { Button } from '@/components/ui/button';\nimport { ProjectStatus } from '@/lib/workspace-types';\n\ninterface ProjectState {\n name: string;\n status: ProjectStatus;\n progress: number;\n message: string;\n error?: string;\n canRetry: boolean;\n isOpening?: boolean;\n isCleaningUp?: boolean;\n needsCleanup?: boolean;\n logs?: Array<{type: 'stdout' | 'stderr' | 'progress', content: string, timestamp: number}>;\n}\n\ninterface InitializationState {\n isInitializing: boolean;\n isCompleted: boolean;\n isLoading: boolean;\n hasCompleted: boolean;\n globalProgress: number;\n globalMessage: string;\n projects: Record<string, ProjectState>;\n completionSummary?: {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n duration: number;\n };\n}\n\nconst ProjectInitializer = () => {\n const router = useRouter();\n const [state, setState] = useState<InitializationState>({\n isInitializing: false,\n isCompleted: false,\n isLoading: true,\n hasCompleted: false,\n globalProgress: 0,\n globalMessage: '正在检查工作空间状态...',\n projects: {},\n });\n \n const [expandedLogs, setExpandedLogs] = useState<Record<string, boolean>>({});\n\n // 页面加载时检查工作空间状态\n useEffect(() => {\n checkWorkspaceStatus();\n }, []);\n\n // 检查工作空间状态\n const checkWorkspaceStatus = async () => {\n try {\n setState(prev => ({\n ...prev,\n isLoading: true,\n globalMessage: '正在检查工作空间状态...',\n }));\n\n const response = await fetch('/api/check-workspace');\n const data = await response.json();\n\n if (data.success) {\n const projectStates: Record<string, ProjectState> = {};\n data.projects.forEach((project: { name: string; status: ProjectStatus; message: string; needsCleanup?: boolean }) => {\n projectStates[project.name] = {\n name: project.name,\n status: project.status,\n progress: project.status === ProjectStatus.EXISTING ? 100 : 0,\n message: project.message,\n canRetry: false,\n needsCleanup: project.needsCleanup || false,\n };\n });\n\n setState(prev => ({\n ...prev,\n isLoading: false,\n projects: projectStates,\n globalMessage: data.message || '检查完成',\n }));\n } else {\n setState(prev => ({\n ...prev,\n isLoading: false,\n globalMessage: data.error || '检查工作空间状态失败',\n }));\n }\n } catch (error) {\n setState(prev => ({\n ...prev,\n isLoading: false,\n globalMessage: '无法连接到服务器,请刷新页面重试',\n }));\n console.error('检查工作空间状态失败:', error);\n }\n };\n\n // 开始初始化工作空间\n const startInitialization = () => {\n setState(prev => ({\n ...prev,\n isInitializing: true,\n isCompleted: false,\n hasCompleted: false,\n globalProgress: 0,\n globalMessage: '正在连接服务器...',\n projects: {},\n completionSummary: undefined,\n }));\n\n // 创建 EventSource 连接\n const eventSource = new EventSource('/api/initialize-workspace');\n\n eventSource.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n handleSSEMessage(data);\n } catch (error) {\n console.error('解析 SSE 消息失败:', error);\n }\n };\n\n eventSource.onerror = () => {\n setState(prev => {\n // 如果已经收到完成消息,则不显示错误(这是正常的连接关闭)\n if (prev.hasCompleted) {\n return prev;\n }\n \n return {\n ...prev,\n isInitializing: false,\n globalMessage: '连接服务器失败,请重试',\n };\n });\n eventSource.close();\n };\n\n // 监听连接关闭\n eventSource.addEventListener('error', () => {\n eventSource.close();\n });\n };\n\n // 处理 SSE 消息\n const handleSSEMessage = (data: {\n type: string;\n progress?: number;\n message?: string;\n projects?: string[];\n projectName?: string;\n error?: string;\n logType?: 'stdout' | 'stderr' | 'progress';\n content?: string;\n timestamp?: number;\n result?: {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n duration: number;\n };\n }) => {\n switch (data.type) {\n case 'initialization':\n case 'workspace_created':\n case 'projects_loaded':\n setState(prev => ({\n ...prev,\n globalProgress: (data.progress as number) || 0,\n globalMessage: (data.message as string) || '',\n }));\n \n // 如果收到项目列表,初始化项目状态\n if (data.projects && Array.isArray(data.projects)) {\n const projectStates: Record<string, ProjectState> = {};\n data.projects.forEach((projectName: string) => {\n projectStates[projectName] = {\n name: projectName,\n status: ProjectStatus.PENDING,\n progress: 0,\n message: '等待开始...',\n canRetry: false,\n };\n });\n setState(prev => ({ ...prev, projects: projectStates }));\n }\n break;\n\n case 'project_existing':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n globalMessage: data.message ?? '',\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.EXISTING,\n message: '项目已存在',\n progress: 100,\n canRetry: false,\n },\n },\n }));\n }\n break;\n\n case 'project_start':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n globalMessage: data.message ?? '',\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.CLONING,\n message: '开始克隆...',\n progress: 0,\n },\n },\n }));\n }\n break;\n\n case 'project_progress':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n message: data.message ?? '',\n progress: Math.min(data.progress ?? 0, 100),\n },\n },\n }));\n }\n break;\n\n case 'project_success':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.SUCCESS,\n message: '克隆成功',\n progress: 100,\n canRetry: false,\n },\n },\n }));\n }\n break;\n\n case 'project_failed':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.FAILED,\n message: '克隆失败',\n error: data.error,\n canRetry: true,\n },\n },\n }));\n }\n break;\n\n case 'command_log':\n if (data.projectName && data.logType && data.content !== undefined && data.timestamp) {\n const projectName = data.projectName;\n const logType = data.logType as 'stdout' | 'stderr' | 'progress';\n const content = data.content as string;\n const timestamp = data.timestamp as number;\n \n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n logs: [\n ...(prev.projects[projectName]?.logs || []),\n {\n type: logType,\n content: content,\n timestamp: timestamp,\n }\n ].slice(-1000), // 保留最新的1000条日志\n },\n },\n }));\n }\n break;\n\n case 'completion':\n setState(prev => ({\n ...prev,\n isInitializing: false,\n isCompleted: true,\n hasCompleted: true,\n globalProgress: 100,\n globalMessage: data.message ?? '初始化完成',\n completionSummary: data.result ? {\n success: data.result.success,\n totalProjects: data.result.totalProjects,\n successCount: data.result.successCount,\n failedCount: data.result.failedCount,\n duration: data.result.duration,\n } : undefined,\n }));\n break;\n\n case 'error':\n setState(prev => ({\n ...prev,\n isInitializing: false,\n hasCompleted: true,\n globalMessage: data.message ?? '发生错误',\n globalProgress: data.progress ?? prev.globalProgress,\n }));\n break;\n }\n };\n\n // 在 Cursor 中打开项目\n const openProject = async (projectName: string) => {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isOpening: true,\n },\n },\n }));\n\n try {\n const response = await fetch('/api/open-project', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ projectName }),\n });\n\n const result = await response.json();\n\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isOpening: false,\n },\n },\n }));\n\n // 可以添加成功/失败的toast提示\n if (!result.success) {\n console.error('打开项目失败:', result.error);\n // 这里可以添加用户友好的错误提示\n }\n } catch (error) {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isOpening: false,\n },\n },\n }));\n console.error('打开项目失败:', error);\n }\n };\n\n // 清理不完整的项目\n const cleanupProject = async (projectName: string) => {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isCleaningUp: true,\n },\n },\n }));\n\n try {\n const response = await fetch('/api/cleanup-project', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ projectName }),\n });\n\n const result = await response.json();\n\n if (result.success) {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.PENDING,\n message: '已清理,待克隆',\n isCleaningUp: false,\n needsCleanup: false,\n },\n },\n }));\n } else {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isCleaningUp: false,\n error: result.error,\n },\n },\n }));\n }\n } catch (error) {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isCleaningUp: false,\n error: error instanceof Error ? error.message : String(error),\n },\n },\n }));\n }\n };\n\n // 重试单个项目\n const retryProject = async (projectName: string) => {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.RETRYING,\n message: '正在重试...',\n progress: 0,\n canRetry: false,\n },\n },\n }));\n\n try {\n const response = await fetch('/api/retry-project', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ projectName }),\n });\n\n const result = await response.json();\n\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: result.success ? ProjectStatus.SUCCESS : ProjectStatus.FAILED,\n message: result.message,\n error: result.error,\n progress: result.success ? 100 : prev.projects[projectName].progress,\n canRetry: !result.success,\n },\n },\n }));\n } catch (error) {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.FAILED,\n message: '重试失败',\n error: error instanceof Error ? error.message : String(error),\n canRetry: true,\n },\n },\n }));\n }\n };\n\n // 获取状态样式\n const getStatusColor = (status: ProjectStatus) => {\n switch (status) {\n case ProjectStatus.EXISTING:\n return 'text-green-600 bg-green-50 border-green-200';\n case ProjectStatus.SUCCESS:\n return 'text-green-600 bg-green-50 border-green-200';\n case ProjectStatus.FAILED:\n return 'text-red-600 bg-red-50 border-red-200';\n case ProjectStatus.INCOMPLETE:\n return 'text-orange-600 bg-orange-50 border-orange-200';\n case ProjectStatus.CLONING:\n case ProjectStatus.RETRYING:\n return 'text-blue-600 bg-blue-50 border-blue-200';\n case ProjectStatus.PENDING:\n return 'text-gray-600 bg-gray-50 border-gray-200';\n default:\n return 'text-gray-600 bg-gray-50 border-gray-200';\n }\n };\n\n const getStatusText = (status: ProjectStatus) => {\n switch (status) {\n case ProjectStatus.PENDING:\n return '待克隆';\n case ProjectStatus.EXISTING:\n return '已存在';\n case ProjectStatus.CLONING:\n return '克隆中';\n case ProjectStatus.SUCCESS:\n return '成功';\n case ProjectStatus.FAILED:\n return '失败';\n case ProjectStatus.INCOMPLETE:\n return '不完整';\n case ProjectStatus.RETRYING:\n return '重试中';\n default:\n return '未知';\n }\n };\n\n // 判断是否所有项目都已存在\n const isAllProjectsExisting = () => {\n const projectValues = Object.values(state.projects);\n return projectValues.length > 0 && \n projectValues.every(project => project.status === ProjectStatus.EXISTING);\n };\n\n // 导航到项目配置页面\n const navigateToProjectConfig = (projectName: string) => {\n router.push(`/configuration?project=${encodeURIComponent(projectName)}`);\n };\n\n return (\n <div className=\"container mx-auto p-4 sm:p-6 md:p-8\">\n <div className=\"flex justify-between items-center mb-6\">\n <h1 className=\"text-2xl font-bold\">项目初始化</h1>\n {state.isLoading ? (\n <Button disabled>检查中...</Button>\n ) : (\n <Button \n onClick={startInitialization}\n disabled={state.isInitializing}\n >\n {state.isInitializing ? '初始化中...' : '创建项目空间'}\n </Button>\n )}\n </div>\n\n {/* 全局进度 */}\n {(state.isInitializing || state.isCompleted) && !isAllProjectsExisting() && (\n <div className=\"mb-6 p-4 bg-gray-50 rounded-lg\">\n <div className=\"flex justify-between items-center mb-2\">\n <span className=\"text-sm font-medium\">{state.globalMessage}</span>\n <span className=\"text-sm text-gray-600\">{state.globalProgress}%</span>\n </div>\n <div className=\"w-full bg-gray-200 rounded-full h-2\">\n <div \n className=\"bg-blue-600 h-2 rounded-full transition-all duration-300\"\n style={{ width: `${state.globalProgress}%` }}\n />\n </div>\n </div>\n )}\n\n {/* 完成总结 */}\n {state.completionSummary && !isAllProjectsExisting() && (\n <div className={`mb-6 p-4 rounded-lg border ${\n state.completionSummary.success \n ? 'bg-green-50 border-green-200' \n : 'bg-yellow-50 border-yellow-200'\n }`}>\n <h3 className=\"font-semibold mb-2\">初始化完成</h3>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4 text-sm\">\n <div>总项目数: {state.completionSummary.totalProjects}</div>\n <div className=\"text-green-600\">成功: {state.completionSummary.successCount}</div>\n <div className=\"text-red-600\">失败: {state.completionSummary.failedCount}</div>\n <div>耗时: {Math.round(state.completionSummary.duration / 1000)}s</div>\n </div>\n </div>\n )}\n\n {/* 项目列表 */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4\">\n {Object.keys(state.projects).length > 0 ? (\n Object.values(state.projects).map((project) => (\n <div \n key={project.name} \n className={`border rounded-lg p-4 ${getStatusColor(project.status)}`}\n >\n <div className=\"flex justify-between items-start mb-2\">\n <h2 \n className=\"font-semibold cursor-pointer hover:text-blue-600 transition-colors\"\n onClick={() => navigateToProjectConfig(project.name)}\n title=\"点击进入项目配置\"\n >\n {project.name}\n </h2>\n <span className=\"text-xs px-2 py-1 rounded-full bg-white\">\n {getStatusText(project.status)}\n </span>\n </div>\n \n <p className=\"text-sm mb-2\">{project.message}</p>\n \n {project.status === ProjectStatus.CLONING || project.status === ProjectStatus.RETRYING ? (\n <div className=\"mb-2\">\n <div className=\"w-full bg-white rounded-full h-1\">\n <div \n className=\"bg-current h-1 rounded-full transition-all duration-300\"\n style={{ width: `${project.progress}%` }}\n />\n </div>\n <span className=\"text-xs\">{project.progress}%</span>\n </div>\n ) : null}\n\n {project.error && (\n <p className=\"text-xs text-red-600 mb-2\">{project.error}</p>\n )}\n\n <div className=\"space-y-2\">\n {project.canRetry && (\n <Button \n size=\"sm\"\n variant=\"outline\"\n onClick={() => retryProject(project.name)}\n className=\"w-full\"\n >\n 重试\n </Button>\n )}\n \n {project.needsCleanup && project.status === ProjectStatus.INCOMPLETE && (\n <Button \n size=\"sm\"\n variant=\"destructive\"\n onClick={() => cleanupProject(project.name)}\n disabled={project.isCleaningUp}\n className=\"w-full\"\n >\n {project.isCleaningUp ? '清理中...' : '清理项目'}\n </Button>\n )}\n \n {(project.status === ProjectStatus.EXISTING || project.status === ProjectStatus.SUCCESS) && (\n <Button \n size=\"sm\"\n variant=\"default\"\n onClick={() => openProject(project.name)}\n disabled={project.isOpening}\n className=\"w-full\"\n >\n {project.isOpening ? '打开中...' : '在 Cursor 中打开'}\n </Button>\n )}\n \n {project.logs && project.logs.length > 0 && (\n <Button \n size=\"sm\"\n variant=\"outline\"\n onClick={() => setExpandedLogs(prev => ({\n ...prev,\n [project.name]: !prev[project.name]\n }))}\n className=\"w-full\"\n >\n {expandedLogs[project.name] ? '隐藏日志' : `查看日志 (${project.logs.length})`}\n </Button>\n )}\n </div>\n\n {/* 日志显示区域 */}\n {expandedLogs[project.name] && project.logs && project.logs.length > 0 && (\n <div className=\"mt-3 border-t pt-3\">\n <div className=\"bg-black text-white rounded text-xs font-mono p-2 max-h-48 overflow-y-auto\">\n {project.logs.map((log, index) => (\n <div key={index} className={`mb-1 ${\n log.type === 'stderr' \n ? 'text-red-400' \n : log.type === 'progress' \n ? 'text-yellow-400' \n : 'text-green-400'\n }`}>\n <span className=\"text-gray-500 mr-2\">\n {new Date(log.timestamp).toLocaleTimeString()}\n </span>\n <span className=\"text-blue-400 mr-2\">[{log.type}]</span>\n <span className=\"whitespace-pre-wrap\">{log.content}</span>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n ))\n ) : (\n <div className=\"col-span-full text-center text-gray-500 py-8\">\n {state.isLoading ? '正在检查项目状态...' : \n state.isInitializing ? '正在加载项目...' : \n '点击\"创建项目空间\"开始初始化'}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default ProjectInitializer;"],"names":[],"mappings":"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"}
1
+ {"version":3,"sources":["turbopack:///[project]/packages/server/src/lib/workspace-types.ts","turbopack:///[project]/packages/server/src/components/project-initializer.tsx"],"sourcesContent":["import { homedir, cpus } from 'os';\nimport { join } from 'path';\n\n/**\n * 工作空间配置常量\n */\nexport const WORKSPACE_CONFIG = {\n // 工作空间根目录路径\n WORKSPACE_ROOT: join(homedir(), 'Documents', 'prime-workspace'),\n\n // Git 操作超时时间 (毫秒)\n GIT_TIMEOUT: 300000, // 5分钟\n\n // 最大并发克隆数量(基于CPU核心数,最小2个,最大8个)\n MAX_CONCURRENT_CLONES: Math.max(2, Math.min(cpus().length, 8)),\n\n // 重试次数限制\n MAX_RETRY_ATTEMPTS: 3,\n} as const;\n\nexport const PROJECT_CONFIG_PATH = join(homedir(), '.prime-projects.json');\n\nexport interface ProjectConfig {\n repo: string;\n mockingIntercept?: boolean;\n mockOpen?: boolean;\n envs: {\n [envName: string]: {\n host: string;\n currentProxy: string;\n proxyEnv: {\n [key: string]: string;\n };\n envFileName: string;\n proxyKey: string;\n subApps?: string[];\n };\n };\n}\n\nexport interface ProjectsConfig {\n [projectName: string]: ProjectConfig;\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n INCOMPLETE = 'incomplete', // 不完整的项目,需要清理\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n onLog?: (projectName: string, logType: 'stdout' | 'stderr' | 'progress', content: string) => void;\n} ","\"use client\";\n\nimport { useEffect, useState } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { Button } from '@/components/ui/button';\nimport { ProjectStatus } from '@/lib/workspace-types';\n\ninterface ProjectState {\n name: string;\n status: ProjectStatus;\n progress: number;\n message: string;\n error?: string;\n canRetry: boolean;\n isOpening?: boolean;\n isCleaningUp?: boolean;\n needsCleanup?: boolean;\n logs?: Array<{type: 'stdout' | 'stderr' | 'progress', content: string, timestamp: number}>;\n}\n\ninterface InitializationState {\n isInitializing: boolean;\n isCompleted: boolean;\n isLoading: boolean;\n hasCompleted: boolean;\n globalProgress: number;\n globalMessage: string;\n projects: Record<string, ProjectState>;\n completionSummary?: {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n duration: number;\n };\n}\n\nconst ProjectInitializer = () => {\n const router = useRouter();\n const [state, setState] = useState<InitializationState>({\n isInitializing: false,\n isCompleted: false,\n isLoading: true,\n hasCompleted: false,\n globalProgress: 0,\n globalMessage: '正在检查工作空间状态...',\n projects: {},\n });\n \n const [expandedLogs, setExpandedLogs] = useState<Record<string, boolean>>({});\n\n // 页面加载时检查工作空间状态\n useEffect(() => {\n checkWorkspaceStatus();\n }, []);\n\n // 检查工作空间状态\n const checkWorkspaceStatus = async () => {\n try {\n setState(prev => ({\n ...prev,\n isLoading: true,\n globalMessage: '正在检查工作空间状态...',\n }));\n\n const response = await fetch('/api/check-workspace');\n const data = await response.json();\n\n if (data.success) {\n const projectStates: Record<string, ProjectState> = {};\n data.projects.forEach((project: { name: string; status: ProjectStatus; message: string; needsCleanup?: boolean }) => {\n projectStates[project.name] = {\n name: project.name,\n status: project.status,\n progress: project.status === ProjectStatus.EXISTING ? 100 : 0,\n message: project.message,\n canRetry: false,\n needsCleanup: project.needsCleanup || false,\n };\n });\n\n setState(prev => ({\n ...prev,\n isLoading: false,\n projects: projectStates,\n globalMessage: data.message || '检查完成',\n }));\n } else {\n setState(prev => ({\n ...prev,\n isLoading: false,\n globalMessage: data.error || '检查工作空间状态失败',\n }));\n }\n } catch (error) {\n setState(prev => ({\n ...prev,\n isLoading: false,\n globalMessage: '无法连接到服务器,请刷新页面重试',\n }));\n console.error('检查工作空间状态失败:', error);\n }\n };\n\n // 开始初始化工作空间\n const startInitialization = () => {\n setState(prev => ({\n ...prev,\n isInitializing: true,\n isCompleted: false,\n hasCompleted: false,\n globalProgress: 0,\n globalMessage: '正在连接服务器...',\n projects: {},\n completionSummary: undefined,\n }));\n\n // 创建 EventSource 连接\n const eventSource = new EventSource('/api/initialize-workspace');\n\n eventSource.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n handleSSEMessage(data);\n } catch (error) {\n console.error('解析 SSE 消息失败:', error);\n }\n };\n\n eventSource.onerror = () => {\n setState(prev => {\n // 如果已经收到完成消息,则不显示错误(这是正常的连接关闭)\n if (prev.hasCompleted) {\n return prev;\n }\n \n return {\n ...prev,\n isInitializing: false,\n globalMessage: '连接服务器失败,请重试',\n };\n });\n eventSource.close();\n };\n\n // 监听连接关闭\n eventSource.addEventListener('error', () => {\n eventSource.close();\n });\n };\n\n // 处理 SSE 消息\n const handleSSEMessage = (data: {\n type: string;\n progress?: number;\n message?: string;\n projects?: string[];\n projectName?: string;\n error?: string;\n logType?: 'stdout' | 'stderr' | 'progress';\n content?: string;\n timestamp?: number;\n result?: {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n duration: number;\n };\n }) => {\n switch (data.type) {\n case 'initialization':\n case 'workspace_created':\n case 'projects_loaded':\n setState(prev => ({\n ...prev,\n globalProgress: (data.progress as number) || 0,\n globalMessage: (data.message as string) || '',\n }));\n \n // 如果收到项目列表,初始化项目状态\n if (data.projects && Array.isArray(data.projects)) {\n const projectStates: Record<string, ProjectState> = {};\n data.projects.forEach((projectName: string) => {\n projectStates[projectName] = {\n name: projectName,\n status: ProjectStatus.PENDING,\n progress: 0,\n message: '等待开始...',\n canRetry: false,\n };\n });\n setState(prev => ({ ...prev, projects: projectStates }));\n }\n break;\n\n case 'project_existing':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n globalMessage: data.message ?? '',\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.EXISTING,\n message: '项目已存在',\n progress: 100,\n canRetry: false,\n },\n },\n }));\n }\n break;\n\n case 'project_start':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n globalMessage: data.message ?? '',\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.CLONING,\n message: '开始克隆...',\n progress: 0,\n },\n },\n }));\n }\n break;\n\n case 'project_progress':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n message: data.message ?? '',\n progress: Math.min(data.progress ?? 0, 100),\n },\n },\n }));\n }\n break;\n\n case 'project_success':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.SUCCESS,\n message: '克隆成功',\n progress: 100,\n canRetry: false,\n },\n },\n }));\n }\n break;\n\n case 'project_failed':\n if (data.projectName) {\n const projectName = data.projectName;\n setState(prev => ({\n ...prev,\n globalProgress: data.progress ?? prev.globalProgress,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.FAILED,\n message: '克隆失败',\n error: data.error,\n canRetry: true,\n },\n },\n }));\n }\n break;\n\n case 'command_log':\n if (data.projectName && data.logType && data.content !== undefined && data.timestamp) {\n const projectName = data.projectName;\n const logType = data.logType as 'stdout' | 'stderr' | 'progress';\n const content = data.content as string;\n const timestamp = data.timestamp as number;\n \n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n logs: [\n ...(prev.projects[projectName]?.logs || []),\n {\n type: logType,\n content: content,\n timestamp: timestamp,\n }\n ].slice(-1000), // 保留最新的1000条日志\n },\n },\n }));\n }\n break;\n\n case 'completion':\n setState(prev => ({\n ...prev,\n isInitializing: false,\n isCompleted: true,\n hasCompleted: true,\n globalProgress: 100,\n globalMessage: data.message ?? '初始化完成',\n completionSummary: data.result ? {\n success: data.result.success,\n totalProjects: data.result.totalProjects,\n successCount: data.result.successCount,\n failedCount: data.result.failedCount,\n duration: data.result.duration,\n } : undefined,\n }));\n break;\n\n case 'error':\n setState(prev => ({\n ...prev,\n isInitializing: false,\n hasCompleted: true,\n globalMessage: data.message ?? '发生错误',\n globalProgress: data.progress ?? prev.globalProgress,\n }));\n break;\n }\n };\n\n // 在 Cursor 中打开项目(使用 cursor:// schema 协议)\n const openProject = async (projectName: string) => {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isOpening: true,\n },\n },\n }));\n\n try {\n const response = await fetch('/api/open-project', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ projectName }),\n });\n\n const result = await response.json();\n\n if (result.success && result.cursorUrl) {\n // 使用 cursor:// schema 协议打开项目\n // 创建临时链接并点击,这样可以触发系统调用 Cursor 应用程序\n const link = document.createElement('a');\n link.href = result.cursorUrl;\n link.style.display = 'none';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n } else {\n console.error('打开项目失败:', result.error);\n }\n\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isOpening: false,\n },\n },\n }));\n } catch (error) {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isOpening: false,\n },\n },\n }));\n console.error('打开项目失败:', error);\n }\n };\n\n // 清理不完整的项目\n const cleanupProject = async (projectName: string) => {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isCleaningUp: true,\n },\n },\n }));\n\n try {\n const response = await fetch('/api/cleanup-project', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ projectName }),\n });\n\n const result = await response.json();\n\n if (result.success) {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.PENDING,\n message: '已清理,待克隆',\n isCleaningUp: false,\n needsCleanup: false,\n },\n },\n }));\n } else {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isCleaningUp: false,\n error: result.error,\n },\n },\n }));\n }\n } catch (error) {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n isCleaningUp: false,\n error: error instanceof Error ? error.message : String(error),\n },\n },\n }));\n }\n };\n\n // 重试单个项目\n const retryProject = async (projectName: string) => {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.RETRYING,\n message: '正在重试...',\n progress: 0,\n canRetry: false,\n },\n },\n }));\n\n try {\n const response = await fetch('/api/retry-project', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ projectName }),\n });\n\n const result = await response.json();\n\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: result.success ? ProjectStatus.SUCCESS : ProjectStatus.FAILED,\n message: result.message,\n error: result.error,\n progress: result.success ? 100 : prev.projects[projectName].progress,\n canRetry: !result.success,\n },\n },\n }));\n } catch (error) {\n setState(prev => ({\n ...prev,\n projects: {\n ...prev.projects,\n [projectName]: {\n ...prev.projects[projectName],\n status: ProjectStatus.FAILED,\n message: '重试失败',\n error: error instanceof Error ? error.message : String(error),\n canRetry: true,\n },\n },\n }));\n }\n };\n\n // 获取状态样式\n const getStatusColor = (status: ProjectStatus) => {\n switch (status) {\n case ProjectStatus.EXISTING:\n return 'text-green-600 bg-green-50 border-green-200';\n case ProjectStatus.SUCCESS:\n return 'text-green-600 bg-green-50 border-green-200';\n case ProjectStatus.FAILED:\n return 'text-red-600 bg-red-50 border-red-200';\n case ProjectStatus.INCOMPLETE:\n return 'text-orange-600 bg-orange-50 border-orange-200';\n case ProjectStatus.CLONING:\n case ProjectStatus.RETRYING:\n return 'text-blue-600 bg-blue-50 border-blue-200';\n case ProjectStatus.PENDING:\n return 'text-gray-600 bg-gray-50 border-gray-200';\n default:\n return 'text-gray-600 bg-gray-50 border-gray-200';\n }\n };\n\n const getStatusText = (status: ProjectStatus) => {\n switch (status) {\n case ProjectStatus.PENDING:\n return '待克隆';\n case ProjectStatus.EXISTING:\n return '已存在';\n case ProjectStatus.CLONING:\n return '克隆中';\n case ProjectStatus.SUCCESS:\n return '成功';\n case ProjectStatus.FAILED:\n return '失败';\n case ProjectStatus.INCOMPLETE:\n return '不完整';\n case ProjectStatus.RETRYING:\n return '重试中';\n default:\n return '未知';\n }\n };\n\n // 判断是否所有项目都已存在\n const isAllProjectsExisting = () => {\n const projectValues = Object.values(state.projects);\n return projectValues.length > 0 && \n projectValues.every(project => project.status === ProjectStatus.EXISTING);\n };\n\n // 导航到项目配置页面\n const navigateToProjectConfig = (projectName: string) => {\n router.push(`/configuration?project=${encodeURIComponent(projectName)}`);\n };\n\n return (\n <div className=\"container mx-auto p-4 sm:p-6 md:p-8\">\n <div className=\"flex justify-between items-center mb-6\">\n <h1 className=\"text-2xl font-bold\">项目初始化</h1>\n {state.isLoading ? (\n <Button disabled>检查中...</Button>\n ) : (\n <Button \n onClick={startInitialization}\n disabled={state.isInitializing}\n >\n {state.isInitializing ? '初始化中...' : '创建项目空间'}\n </Button>\n )}\n </div>\n\n {/* 全局进度 */}\n {(state.isInitializing || state.isCompleted) && !isAllProjectsExisting() && (\n <div className=\"mb-6 p-4 bg-gray-50 rounded-lg\">\n <div className=\"flex justify-between items-center mb-2\">\n <span className=\"text-sm font-medium\">{state.globalMessage}</span>\n <span className=\"text-sm text-gray-600\">{state.globalProgress}%</span>\n </div>\n <div className=\"w-full bg-gray-200 rounded-full h-2\">\n <div \n className=\"bg-blue-600 h-2 rounded-full transition-all duration-300\"\n style={{ width: `${state.globalProgress}%` }}\n />\n </div>\n </div>\n )}\n\n {/* 完成总结 */}\n {state.completionSummary && !isAllProjectsExisting() && (\n <div className={`mb-6 p-4 rounded-lg border ${\n state.completionSummary.success \n ? 'bg-green-50 border-green-200' \n : 'bg-yellow-50 border-yellow-200'\n }`}>\n <h3 className=\"font-semibold mb-2\">初始化完成</h3>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4 text-sm\">\n <div>总项目数: {state.completionSummary.totalProjects}</div>\n <div className=\"text-green-600\">成功: {state.completionSummary.successCount}</div>\n <div className=\"text-red-600\">失败: {state.completionSummary.failedCount}</div>\n <div>耗时: {Math.round(state.completionSummary.duration / 1000)}s</div>\n </div>\n </div>\n )}\n\n {/* 项目列表 */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4\">\n {Object.keys(state.projects).length > 0 ? (\n Object.values(state.projects).map((project) => (\n <div \n key={project.name} \n className={`border rounded-lg p-4 ${getStatusColor(project.status)}`}\n >\n <div className=\"flex justify-between items-start mb-2\">\n <h2 \n className=\"font-semibold cursor-pointer hover:text-blue-600 transition-colors\"\n onClick={() => navigateToProjectConfig(project.name)}\n title=\"点击进入项目配置\"\n >\n {project.name}\n </h2>\n <span className=\"text-xs px-2 py-1 rounded-full bg-white\">\n {getStatusText(project.status)}\n </span>\n </div>\n \n <p className=\"text-sm mb-2\">{project.message}</p>\n \n {project.status === ProjectStatus.CLONING || project.status === ProjectStatus.RETRYING ? (\n <div className=\"mb-2\">\n <div className=\"w-full bg-white rounded-full h-1\">\n <div \n className=\"bg-current h-1 rounded-full transition-all duration-300\"\n style={{ width: `${project.progress}%` }}\n />\n </div>\n <span className=\"text-xs\">{project.progress}%</span>\n </div>\n ) : null}\n\n {project.error && (\n <p className=\"text-xs text-red-600 mb-2\">{project.error}</p>\n )}\n\n <div className=\"space-y-2\">\n {project.canRetry && (\n <Button \n size=\"sm\"\n variant=\"outline\"\n onClick={() => retryProject(project.name)}\n className=\"w-full\"\n >\n 重试\n </Button>\n )}\n \n {project.needsCleanup && project.status === ProjectStatus.INCOMPLETE && (\n <Button \n size=\"sm\"\n variant=\"destructive\"\n onClick={() => cleanupProject(project.name)}\n disabled={project.isCleaningUp}\n className=\"w-full\"\n >\n {project.isCleaningUp ? '清理中...' : '清理项目'}\n </Button>\n )}\n \n {(project.status === ProjectStatus.EXISTING || project.status === ProjectStatus.SUCCESS) && (\n <Button \n size=\"sm\"\n variant=\"default\"\n onClick={() => openProject(project.name)}\n disabled={project.isOpening}\n className=\"w-full\"\n >\n {project.isOpening ? '打开中...' : '在 Cursor 中打开'}\n </Button>\n )}\n \n {project.logs && project.logs.length > 0 && (\n <Button \n size=\"sm\"\n variant=\"outline\"\n onClick={() => setExpandedLogs(prev => ({\n ...prev,\n [project.name]: !prev[project.name]\n }))}\n className=\"w-full\"\n >\n {expandedLogs[project.name] ? '隐藏日志' : `查看日志 (${project.logs.length})`}\n </Button>\n )}\n </div>\n\n {/* 日志显示区域 */}\n {expandedLogs[project.name] && project.logs && project.logs.length > 0 && (\n <div className=\"mt-3 border-t pt-3\">\n <div className=\"bg-black text-white rounded text-xs font-mono p-2 max-h-48 overflow-y-auto\">\n {project.logs.map((log, index) => (\n <div key={index} className={`mb-1 ${\n log.type === 'stderr' \n ? 'text-red-400' \n : log.type === 'progress' \n ? 'text-yellow-400' \n : 'text-green-400'\n }`}>\n <span className=\"text-gray-500 mr-2\">\n {new Date(log.timestamp).toLocaleTimeString()}\n </span>\n <span className=\"text-blue-400 mr-2\">[{log.type}]</span>\n <span className=\"whitespace-pre-wrap\">{log.content}</span>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n ))\n ) : (\n <div className=\"col-span-full text-center text-gray-500 py-8\">\n {state.isLoading ? '正在检查项目状态...' : \n state.isInitializing ? '正在加载项目...' : \n '点击\"创建项目空间\"开始初始化'}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default ProjectInitializer;"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/1ad898191df92f90.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/0dfafa95d29e5c79.js"/><script src="/_next/static/chunks/a7b45611d4ad55fe.js" async=""></script><script src="/_next/static/chunks/0e57f1354cda05d5.js" async=""></script><script src="/_next/static/chunks/1923d6510bea25be.js" async=""></script><script src="/_next/static/chunks/a9cba6096fe97a30.js" async=""></script><script src="/_next/static/chunks/ecfccf4677b4777a.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Prime Dev CLI - 项目管理工具</title><meta name="description" content="管理多个前端项目的开发环境和配置"/><link rel="icon" href="/favicon.ico?favicon.45db1c09.ico" sizes="256x256" type="image/x-icon"/><script>document.querySelectorAll('body link[rel="icon"], body link[rel="apple-touch-icon"]').forEach(el => document.head.appendChild(el))</script><script src="/_next/static/chunks/ec548c7ce307cf6d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/0dfafa95d29e5c79.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[55889,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"default\"]\n3:I[54799,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"default\"]\n4:I[67903,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"OutletBoundary\"]\n7:I[73794,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"AsyncMetadataOutlet\"]\n9:I[67903,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"ViewportBoundary\"]\nb:I[67903,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"MetadataBoundary\"]\nd:I[71163,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"default\"]\n:HL[\"/_next/static/chunks/1ad898191df92f90.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"bC3bTGQyq6cbRR_M7T8N6\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/1ad898191df92f90.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L4\",null,{\"children\":[\"$L5\",\"$L6\",[\"$\",\"$L7\",null,{\"promise\":\"$@8\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$1\",\"btGWyDsOA47IIEfOqsLy3v\",{\"children\":[[\"$\",\"$L9\",null,{\"children\":\"$La\"}],null]}],[\"$\",\"$Lb\",null,{\"children\":\"$Lc\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",\"$undefined\"],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"e:\"$Sreact.suspense\"\nf:I[73794,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"AsyncMetadata\"]\nc:[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$e\",null,{\"fallback\":null,\"children\":[\"$\",\"$Lf\",null,{\"promise\":\"$@10\"}]}]}]\n6:null\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,"8:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Prime Dev CLI - 项目管理工具\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"管理多个前端项目的开发环境和配置\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.45db1c09.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}]],\"error\":null,\"digest\":\"$undefined\"}\n10:{\"metadata\":\"$8:metadata\",\"error\":null,\"digest\":\"$undefined\"}\n"])</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/1ad898191df92f90.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/0dfafa95d29e5c79.js"/><script src="/_next/static/chunks/a7b45611d4ad55fe.js" async=""></script><script src="/_next/static/chunks/0e57f1354cda05d5.js" async=""></script><script src="/_next/static/chunks/1923d6510bea25be.js" async=""></script><script src="/_next/static/chunks/a9cba6096fe97a30.js" async=""></script><script src="/_next/static/chunks/ecfccf4677b4777a.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Prime Dev CLI - 项目管理工具</title><meta name="description" content="管理多个前端项目的开发环境和配置"/><link rel="icon" href="/favicon.ico?favicon.45db1c09.ico" sizes="256x256" type="image/x-icon"/><script>document.querySelectorAll('body link[rel="icon"], body link[rel="apple-touch-icon"]').forEach(el => document.head.appendChild(el))</script><script src="/_next/static/chunks/ec548c7ce307cf6d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/0dfafa95d29e5c79.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[55889,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"default\"]\n3:I[54799,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"default\"]\n4:I[67903,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"OutletBoundary\"]\n7:I[73794,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"AsyncMetadataOutlet\"]\n9:I[67903,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"ViewportBoundary\"]\nb:I[67903,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"MetadataBoundary\"]\nd:I[71163,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"default\"]\n:HL[\"/_next/static/chunks/1ad898191df92f90.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"Xoig0sIWc0oIgbMH6U6Ew\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/1ad898191df92f90.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L4\",null,{\"children\":[\"$L5\",\"$L6\",[\"$\",\"$L7\",null,{\"promise\":\"$@8\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$1\",\"tDlTVV-_vbchUpI6uRTWRv\",{\"children\":[[\"$\",\"$L9\",null,{\"children\":\"$La\"}],null]}],[\"$\",\"$Lb\",null,{\"children\":\"$Lc\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",\"$undefined\"],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"e:\"$Sreact.suspense\"\nf:I[73794,[\"/_next/static/chunks/ecfccf4677b4777a.js\"],\"AsyncMetadata\"]\nc:[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$e\",null,{\"fallback\":null,\"children\":[\"$\",\"$Lf\",null,{\"promise\":\"$@10\"}]}]}]\n6:null\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,"8:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Prime Dev CLI - 项目管理工具\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"管理多个前端项目的开发环境和配置\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.45db1c09.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}]],\"error\":null,\"digest\":\"$undefined\"}\n10:{\"metadata\":\"$8:metadata\",\"error\":null,\"digest\":\"$undefined\"}\n"])</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><title data-next-head="">500: Internal Server Error</title><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/ec548c7ce307cf6d.js"></script><script src="/_next/static/chunks/7d7379cdf8fe9ec5.js" defer=""></script><script src="/_next/static/chunks/f9ef1d12f3c1646a.js" defer=""></script><script src="/_next/static/chunks/d65b8ba84ba3d819.js" defer=""></script><script src="/_next/static/chunks/cf6e515377591a1f.js" defer=""></script><script src="/_next/static/chunks/294d677a4838a994.js" defer=""></script><script src="/_next/static/bC3bTGQyq6cbRR_M7T8N6/_ssgManifest.js" defer=""></script><script src="/_next/static/bC3bTGQyq6cbRR_M7T8N6/_buildManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{},"buildId":"bC3bTGQyq6cbRR_M7T8N6","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><title data-next-head="">500: Internal Server Error</title><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/ec548c7ce307cf6d.js"></script><script src="/_next/static/chunks/7d7379cdf8fe9ec5.js" defer=""></script><script src="/_next/static/chunks/f9ef1d12f3c1646a.js" defer=""></script><script src="/_next/static/chunks/d65b8ba84ba3d819.js" defer=""></script><script src="/_next/static/chunks/cf6e515377591a1f.js" defer=""></script><script src="/_next/static/chunks/294d677a4838a994.js" defer=""></script><script src="/_next/static/Xoig0sIWc0oIgbMH6U6Ew/_ssgManifest.js" defer=""></script><script src="/_next/static/Xoig0sIWc0oIgbMH6U6Ew/_buildManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{},"buildId":"Xoig0sIWc0oIgbMH6U6Ew","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"kWbBlOfJtX/nx5xap++ZqATbD2be5EsCxEBRuZyaxzg=\"\n}"
1
+ self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"Y5DM2pBhAkLoyyULylQwumRtOyYSUq/3UTUXfJ9rCOY=\"\n}"
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "node": {},
3
3
  "edge": {},
4
- "encryptionKey": "kWbBlOfJtX/nx5xap++ZqATbD2be5EsCxEBRuZyaxzg="
4
+ "encryptionKey": "Y5DM2pBhAkLoyyULylQwumRtOyYSUq/3UTUXfJ9rCOY="
5
5
  }
@@ -1,3 +1,3 @@
1
- (globalThis.TURBOPACK=globalThis.TURBOPACK||[]).push(["object"==typeof document?document.currentScript:void 0,{86442:function(e){var t,{g:s,__dirname:r,m:a,e:o}=e;"undefined"!=typeof __nccwpck_require__&&(__nccwpck_require__.ab=r+"/"),(t={}).endianness=function(){return"LE"},t.hostname=function(){return"undefined"!=typeof location?location.hostname:""},t.loadavg=function(){return[]},t.uptime=function(){return 0},t.freemem=function(){return Number.MAX_VALUE},t.totalmem=function(){return Number.MAX_VALUE},t.cpus=function(){return[]},t.type=function(){return"Browser"},t.release=function(){return"undefined"!=typeof navigator?navigator.appVersion:""},t.networkInterfaces=t.getNetworkInterfaces=function(){return{}},t.arch=function(){return"javascript"},t.platform=function(){return"browser"},t.tmpdir=t.tmpDir=function(){return"/tmp"},t.EOL="\n",t.homedir=function(){return"/"},a.exports=t},87733:function(e){var{g:t,__dirname:s,m:r,e:a}=e;!function(){"use strict";var e={114:function(e){function t(e){if("string"!=typeof e)throw TypeError("Path must be a string. Received "+JSON.stringify(e))}function s(e,t){for(var s,r="",a=0,o=-1,n=0,c=0;c<=e.length;++c){if(c<e.length)s=e.charCodeAt(c);else if(47===s)break;else s=47;if(47===s){if(o===c-1||1===n);else if(o!==c-1&&2===n){if(r.length<2||2!==a||46!==r.charCodeAt(r.length-1)||46!==r.charCodeAt(r.length-2)){if(r.length>2){var i=r.lastIndexOf("/");if(i!==r.length-1){-1===i?(r="",a=0):a=(r=r.slice(0,i)).length-1-r.lastIndexOf("/"),o=c,n=0;continue}}else if(2===r.length||1===r.length){r="",a=0,o=c,n=0;continue}}t&&(r.length>0?r+="/..":r="..",a=2)}else r.length>0?r+="/"+e.slice(o+1,c):r=e.slice(o+1,c),a=c-o-1;o=c,n=0}else 46===s&&-1!==n?++n:n=-1}return r}var r={resolve:function(){for(var e,r,a="",o=!1,n=arguments.length-1;n>=-1&&!o;n--)n>=0?r=arguments[n]:(void 0===e&&(e=""),r=e),t(r),0!==r.length&&(a=r+"/"+a,o=47===r.charCodeAt(0));if(a=s(a,!o),o)if(a.length>0)return"/"+a;else return"/";return a.length>0?a:"."},normalize:function(e){if(t(e),0===e.length)return".";var r=47===e.charCodeAt(0),a=47===e.charCodeAt(e.length-1);return(0!==(e=s(e,!r)).length||r||(e="."),e.length>0&&a&&(e+="/"),r)?"/"+e:e},isAbsolute:function(e){return t(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0==arguments.length)return".";for(var e,s=0;s<arguments.length;++s){var a=arguments[s];t(a),a.length>0&&(void 0===e?e=a:e+="/"+a)}return void 0===e?".":r.normalize(e)},relative:function(e,s){if(t(e),t(s),e===s||(e=r.resolve(e))===(s=r.resolve(s)))return"";for(var a=1;a<e.length&&47===e.charCodeAt(a);++a);for(var o=e.length,n=o-a,c=1;c<s.length&&47===s.charCodeAt(c);++c);for(var i=s.length-c,l=n<i?n:i,u=-1,g=0;g<=l;++g){if(g===l){if(i>l){if(47===s.charCodeAt(c+g))return s.slice(c+g+1);else if(0===g)return s.slice(c+g)}else n>l&&(47===e.charCodeAt(a+g)?u=g:0===g&&(u=0));break}var p=e.charCodeAt(a+g);if(p!==s.charCodeAt(c+g))break;47===p&&(u=g)}var d="";for(g=a+u+1;g<=o;++g)(g===o||47===e.charCodeAt(g))&&(0===d.length?d+="..":d+="/..");return d.length>0?d+s.slice(c+u):(c+=u,47===s.charCodeAt(c)&&++c,s.slice(c))},_makeLong:function(e){return e},dirname:function(e){if(t(e),0===e.length)return".";for(var s=e.charCodeAt(0),r=47===s,a=-1,o=!0,n=e.length-1;n>=1;--n)if(47===(s=e.charCodeAt(n))){if(!o){a=n;break}}else o=!1;return -1===a?r?"/":".":r&&1===a?"//":e.slice(0,a)},basename:function(e,s){if(void 0!==s&&"string"!=typeof s)throw TypeError('"ext" argument must be a string');t(e);var r,a=0,o=-1,n=!0;if(void 0!==s&&s.length>0&&s.length<=e.length){if(s.length===e.length&&s===e)return"";var c=s.length-1,i=-1;for(r=e.length-1;r>=0;--r){var l=e.charCodeAt(r);if(47===l){if(!n){a=r+1;break}}else -1===i&&(n=!1,i=r+1),c>=0&&(l===s.charCodeAt(c)?-1==--c&&(o=r):(c=-1,o=i))}return a===o?o=i:-1===o&&(o=e.length),e.slice(a,o)}for(r=e.length-1;r>=0;--r)if(47===e.charCodeAt(r)){if(!n){a=r+1;break}}else -1===o&&(n=!1,o=r+1);return -1===o?"":e.slice(a,o)},extname:function(e){t(e);for(var s=-1,r=0,a=-1,o=!0,n=0,c=e.length-1;c>=0;--c){var i=e.charCodeAt(c);if(47===i){if(!o){r=c+1;break}continue}-1===a&&(o=!1,a=c+1),46===i?-1===s?s=c:1!==n&&(n=1):-1!==s&&(n=-1)}return -1===s||-1===a||0===n||1===n&&s===a-1&&s===r+1?"":e.slice(s,a)},format:function(e){var t,s;if(null===e||"object"!=typeof e)throw TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return t=e.dir||e.root,s=e.base||(e.name||"")+(e.ext||""),t?t===e.root?t+s:t+"/"+s:s},parse:function(e){t(e);var s,r={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return r;var a=e.charCodeAt(0),o=47===a;o?(r.root="/",s=1):s=0;for(var n=-1,c=0,i=-1,l=!0,u=e.length-1,g=0;u>=s;--u){if(47===(a=e.charCodeAt(u))){if(!l){c=u+1;break}continue}-1===i&&(l=!1,i=u+1),46===a?-1===n?n=u:1!==g&&(g=1):-1!==n&&(g=-1)}return -1===n||-1===i||0===g||1===g&&n===i-1&&n===c+1?-1!==i&&(0===c&&o?r.base=r.name=e.slice(1,i):r.base=r.name=e.slice(c,i)):(0===c&&o?(r.name=e.slice(1,n),r.base=e.slice(1,i)):(r.name=e.slice(c,n),r.base=e.slice(c,i)),r.ext=e.slice(n,i)),c>0?r.dir=e.slice(0,c-1):o&&(r.dir="/"),r},sep:"/",delimiter:":",win32:null,posix:null};r.posix=r,e.exports=r}},t={};function a(s){var r=t[s];if(void 0!==r)return r.exports;var o=t[s]={exports:{}},n=!0;try{e[s](o,o.exports,a),n=!1}finally{n&&delete t[s]}return o.exports}a.ab=s+"/",r.exports=a(114)}()},7647:e=>{"use strict";var{g:t,__dirname:s}=e;{e.s({PROJECT_CONFIG_PATH:()=>s,ProjectStatus:()=>o,WORKSPACE_CONFIG:()=>t});var r=e.i(86442),a=e.i(87733);let t={WORKSPACE_ROOT:(0,a.join)((0,r.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,r.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},s=(0,a.join)((0,r.homedir)(),".prime-projects.json");var o=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e.INCOMPLETE="incomplete",e}({})}},9993:e=>{"use strict";var{g:t,__dirname:s}=e;{e.s({default:()=>t});var r=e.i(20393),a=e.i(19886),o=e.i(42152),n=e.i(86871),c=e.i(7647);let t=()=>{let e=(0,o.useRouter)(),[t,s]=(0,a.useState)({isInitializing:!1,isCompleted:!1,isLoading:!0,hasCompleted:!1,globalProgress:0,globalMessage:"正在检查工作空间状态...",projects:{}}),[i,l]=(0,a.useState)({});(0,a.useEffect)(()=>{u()},[]);let u=async()=>{try{s(e=>({...e,isLoading:!0,globalMessage:"正在检查工作空间状态..."}));let e=await fetch("/api/check-workspace"),t=await e.json();if(t.success){let e={};t.projects.forEach(t=>{e[t.name]={name:t.name,status:t.status,progress:100*(t.status===c.ProjectStatus.EXISTING),message:t.message,canRetry:!1,needsCleanup:t.needsCleanup||!1}}),s(s=>({...s,isLoading:!1,projects:e,globalMessage:t.message||"检查完成"}))}else s(e=>({...e,isLoading:!1,globalMessage:t.error||"检查工作空间状态失败"}))}catch(e){s(e=>({...e,isLoading:!1,globalMessage:"无法连接到服务器,请刷新页面重试"})),console.error("检查工作空间状态失败:",e)}},g=e=>{switch(e.type){case"initialization":case"workspace_created":case"projects_loaded":if(s(t=>({...t,globalProgress:e.progress||0,globalMessage:e.message||""})),e.projects&&Array.isArray(e.projects)){let t={};e.projects.forEach(e=>{t[e]={name:e,status:c.ProjectStatus.PENDING,progress:0,message:"等待开始...",canRetry:!1}}),s(e=>({...e,projects:t}))}break;case"project_existing":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,globalMessage:e.message??"",projects:{...s.projects,[t]:{...s.projects[t],status:c.ProjectStatus.EXISTING,message:"项目已存在",progress:100,canRetry:!1}}}))}break;case"project_start":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,globalMessage:e.message??"",projects:{...s.projects,[t]:{...s.projects[t],status:c.ProjectStatus.CLONING,message:"开始克隆...",progress:0}}}))}break;case"project_progress":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,projects:{...s.projects,[t]:{...s.projects[t],message:e.message??"",progress:Math.min(e.progress??0,100)}}}))}break;case"project_success":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,projects:{...s.projects,[t]:{...s.projects[t],status:c.ProjectStatus.SUCCESS,message:"克隆成功",progress:100,canRetry:!1}}}))}break;case"project_failed":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,projects:{...s.projects,[t]:{...s.projects[t],status:c.ProjectStatus.FAILED,message:"克隆失败",error:e.error,canRetry:!0}}}))}break;case"command_log":if(e.projectName&&e.logType&&void 0!==e.content&&e.timestamp){let t=e.projectName,r=e.logType,a=e.content,o=e.timestamp;s(e=>({...e,projects:{...e.projects,[t]:{...e.projects[t],logs:[...e.projects[t]?.logs||[],{type:r,content:a,timestamp:o}].slice(-1e3)}}}))}break;case"completion":s(t=>({...t,isInitializing:!1,isCompleted:!0,hasCompleted:!0,globalProgress:100,globalMessage:e.message??"初始化完成",completionSummary:e.result?{success:e.result.success,totalProjects:e.result.totalProjects,successCount:e.result.successCount,failedCount:e.result.failedCount,duration:e.result.duration}:void 0}));break;case"error":s(t=>({...t,isInitializing:!1,hasCompleted:!0,globalMessage:e.message??"发生错误",globalProgress:e.progress??t.globalProgress}))}},p=async e=>{s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isOpening:!0}}}));try{let t=await fetch("/api/open-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:e})}),r=await t.json();s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isOpening:!1}}})),r.success||console.error("打开项目失败:",r.error)}catch(t){s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isOpening:!1}}})),console.error("打开项目失败:",t)}},d=async e=>{s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isCleaningUp:!0}}}));try{let t=await fetch("/api/cleanup-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:e})}),r=await t.json();r.success?s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],status:c.ProjectStatus.PENDING,message:"已清理,待克隆",isCleaningUp:!1,needsCleanup:!1}}})):s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isCleaningUp:!1,error:r.error}}}))}catch(t){s(s=>({...s,projects:{...s.projects,[e]:{...s.projects[e],isCleaningUp:!1,error:t instanceof Error?t.message:String(t)}}}))}},m=async e=>{s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],status:c.ProjectStatus.RETRYING,message:"正在重试...",progress:0,canRetry:!1}}}));try{let t=await fetch("/api/retry-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:e})}),r=await t.json();s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],status:r.success?c.ProjectStatus.SUCCESS:c.ProjectStatus.FAILED,message:r.message,error:r.error,progress:r.success?100:t.projects[e].progress,canRetry:!r.success}}}))}catch(t){s(s=>({...s,projects:{...s.projects,[e]:{...s.projects[e],status:c.ProjectStatus.FAILED,message:"重试失败",error:t instanceof Error?t.message:String(t),canRetry:!0}}}))}},j=e=>{switch(e){case c.ProjectStatus.EXISTING:case c.ProjectStatus.SUCCESS:return"text-green-600 bg-green-50 border-green-200";case c.ProjectStatus.FAILED:return"text-red-600 bg-red-50 border-red-200";case c.ProjectStatus.INCOMPLETE:return"text-orange-600 bg-orange-50 border-orange-200";case c.ProjectStatus.CLONING:case c.ProjectStatus.RETRYING:return"text-blue-600 bg-blue-50 border-blue-200";case c.ProjectStatus.PENDING:default:return"text-gray-600 bg-gray-50 border-gray-200"}},h=e=>{switch(e){case c.ProjectStatus.PENDING:return"待克隆";case c.ProjectStatus.EXISTING:return"已存在";case c.ProjectStatus.CLONING:return"克隆中";case c.ProjectStatus.SUCCESS:return"成功";case c.ProjectStatus.FAILED:return"失败";case c.ProjectStatus.INCOMPLETE:return"不完整";case c.ProjectStatus.RETRYING:return"重试中";default:return"未知"}},f=()=>{let e=Object.values(t.projects);return e.length>0&&e.every(e=>e.status===c.ProjectStatus.EXISTING)},b=t=>{e.push(`/configuration?project=${encodeURIComponent(t)}`)};return(0,r.jsxs)("div",{className:"container mx-auto p-4 sm:p-6 md:p-8",children:[(0,r.jsxs)("div",{className:"flex justify-between items-center mb-6",children:[(0,r.jsx)("h1",{className:"text-2xl font-bold",children:"项目初始化"}),t.isLoading?(0,r.jsx)(n.Button,{disabled:!0,children:"检查中..."}):(0,r.jsx)(n.Button,{onClick:()=>{s(e=>({...e,isInitializing:!0,isCompleted:!1,hasCompleted:!1,globalProgress:0,globalMessage:"正在连接服务器...",projects:{},completionSummary:void 0}));let e=new EventSource("/api/initialize-workspace");e.onmessage=e=>{try{let t=JSON.parse(e.data);g(t)}catch(e){console.error("解析 SSE 消息失败:",e)}},e.onerror=()=>{s(e=>e.hasCompleted?e:{...e,isInitializing:!1,globalMessage:"连接服务器失败,请重试"}),e.close()},e.addEventListener("error",()=>{e.close()})},disabled:t.isInitializing,children:t.isInitializing?"初始化中...":"创建项目空间"})]}),(t.isInitializing||t.isCompleted)&&!f()&&(0,r.jsxs)("div",{className:"mb-6 p-4 bg-gray-50 rounded-lg",children:[(0,r.jsxs)("div",{className:"flex justify-between items-center mb-2",children:[(0,r.jsx)("span",{className:"text-sm font-medium",children:t.globalMessage}),(0,r.jsxs)("span",{className:"text-sm text-gray-600",children:[t.globalProgress,"%"]})]}),(0,r.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-2",children:(0,r.jsx)("div",{className:"bg-blue-600 h-2 rounded-full transition-all duration-300",style:{width:`${t.globalProgress}%`}})})]}),t.completionSummary&&!f()&&(0,r.jsxs)("div",{className:`mb-6 p-4 rounded-lg border ${t.completionSummary.success?"bg-green-50 border-green-200":"bg-yellow-50 border-yellow-200"}`,children:[(0,r.jsx)("h3",{className:"font-semibold mb-2",children:"初始化完成"}),(0,r.jsxs)("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-sm",children:[(0,r.jsxs)("div",{children:["总项目数: ",t.completionSummary.totalProjects]}),(0,r.jsxs)("div",{className:"text-green-600",children:["成功: ",t.completionSummary.successCount]}),(0,r.jsxs)("div",{className:"text-red-600",children:["失败: ",t.completionSummary.failedCount]}),(0,r.jsxs)("div",{children:["耗时: ",Math.round(t.completionSummary.duration/1e3),"s"]})]})]}),(0,r.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",children:Object.keys(t.projects).length>0?Object.values(t.projects).map(e=>(0,r.jsxs)("div",{className:`border rounded-lg p-4 ${j(e.status)}`,children:[(0,r.jsxs)("div",{className:"flex justify-between items-start mb-2",children:[(0,r.jsx)("h2",{className:"font-semibold cursor-pointer hover:text-blue-600 transition-colors",onClick:()=>b(e.name),title:"点击进入项目配置",children:e.name}),(0,r.jsx)("span",{className:"text-xs px-2 py-1 rounded-full bg-white",children:h(e.status)})]}),(0,r.jsx)("p",{className:"text-sm mb-2",children:e.message}),e.status===c.ProjectStatus.CLONING||e.status===c.ProjectStatus.RETRYING?(0,r.jsxs)("div",{className:"mb-2",children:[(0,r.jsx)("div",{className:"w-full bg-white rounded-full h-1",children:(0,r.jsx)("div",{className:"bg-current h-1 rounded-full transition-all duration-300",style:{width:`${e.progress}%`}})}),(0,r.jsxs)("span",{className:"text-xs",children:[e.progress,"%"]})]}):null,e.error&&(0,r.jsx)("p",{className:"text-xs text-red-600 mb-2",children:e.error}),(0,r.jsxs)("div",{className:"space-y-2",children:[e.canRetry&&(0,r.jsx)(n.Button,{size:"sm",variant:"outline",onClick:()=>m(e.name),className:"w-full",children:"重试"}),e.needsCleanup&&e.status===c.ProjectStatus.INCOMPLETE&&(0,r.jsx)(n.Button,{size:"sm",variant:"destructive",onClick:()=>d(e.name),disabled:e.isCleaningUp,className:"w-full",children:e.isCleaningUp?"清理中...":"清理项目"}),(e.status===c.ProjectStatus.EXISTING||e.status===c.ProjectStatus.SUCCESS)&&(0,r.jsx)(n.Button,{size:"sm",variant:"default",onClick:()=>p(e.name),disabled:e.isOpening,className:"w-full",children:e.isOpening?"打开中...":"在 Cursor 中打开"}),e.logs&&e.logs.length>0&&(0,r.jsx)(n.Button,{size:"sm",variant:"outline",onClick:()=>l(t=>({...t,[e.name]:!t[e.name]})),className:"w-full",children:i[e.name]?"隐藏日志":`查看日志 (${e.logs.length})`})]}),i[e.name]&&e.logs&&e.logs.length>0&&(0,r.jsx)("div",{className:"mt-3 border-t pt-3",children:(0,r.jsx)("div",{className:"bg-black text-white rounded text-xs font-mono p-2 max-h-48 overflow-y-auto",children:e.logs.map((e,t)=>(0,r.jsxs)("div",{className:`mb-1 ${"stderr"===e.type?"text-red-400":"progress"===e.type?"text-yellow-400":"text-green-400"}`,children:[(0,r.jsx)("span",{className:"text-gray-500 mr-2",children:new Date(e.timestamp).toLocaleTimeString()}),(0,r.jsxs)("span",{className:"text-blue-400 mr-2",children:["[",e.type,"]"]}),(0,r.jsx)("span",{className:"whitespace-pre-wrap",children:e.content})]},t))})})]},e.name)):(0,r.jsx)("div",{className:"col-span-full text-center text-gray-500 py-8",children:t.isLoading?"正在检查项目状态...":t.isInitializing?"正在加载项目...":'点击"创建项目空间"开始初始化'})})]})}}}}]);
1
+ (globalThis.TURBOPACK=globalThis.TURBOPACK||[]).push(["object"==typeof document?document.currentScript:void 0,{86442:function(e){var t,{g:s,__dirname:r,m:a,e:o}=e;"undefined"!=typeof __nccwpck_require__&&(__nccwpck_require__.ab=r+"/"),(t={}).endianness=function(){return"LE"},t.hostname=function(){return"undefined"!=typeof location?location.hostname:""},t.loadavg=function(){return[]},t.uptime=function(){return 0},t.freemem=function(){return Number.MAX_VALUE},t.totalmem=function(){return Number.MAX_VALUE},t.cpus=function(){return[]},t.type=function(){return"Browser"},t.release=function(){return"undefined"!=typeof navigator?navigator.appVersion:""},t.networkInterfaces=t.getNetworkInterfaces=function(){return{}},t.arch=function(){return"javascript"},t.platform=function(){return"browser"},t.tmpdir=t.tmpDir=function(){return"/tmp"},t.EOL="\n",t.homedir=function(){return"/"},a.exports=t},87733:function(e){var{g:t,__dirname:s,m:r,e:a}=e;!function(){"use strict";var e={114:function(e){function t(e){if("string"!=typeof e)throw TypeError("Path must be a string. Received "+JSON.stringify(e))}function s(e,t){for(var s,r="",a=0,o=-1,n=0,c=0;c<=e.length;++c){if(c<e.length)s=e.charCodeAt(c);else if(47===s)break;else s=47;if(47===s){if(o===c-1||1===n);else if(o!==c-1&&2===n){if(r.length<2||2!==a||46!==r.charCodeAt(r.length-1)||46!==r.charCodeAt(r.length-2)){if(r.length>2){var i=r.lastIndexOf("/");if(i!==r.length-1){-1===i?(r="",a=0):a=(r=r.slice(0,i)).length-1-r.lastIndexOf("/"),o=c,n=0;continue}}else if(2===r.length||1===r.length){r="",a=0,o=c,n=0;continue}}t&&(r.length>0?r+="/..":r="..",a=2)}else r.length>0?r+="/"+e.slice(o+1,c):r=e.slice(o+1,c),a=c-o-1;o=c,n=0}else 46===s&&-1!==n?++n:n=-1}return r}var r={resolve:function(){for(var e,r,a="",o=!1,n=arguments.length-1;n>=-1&&!o;n--)n>=0?r=arguments[n]:(void 0===e&&(e=""),r=e),t(r),0!==r.length&&(a=r+"/"+a,o=47===r.charCodeAt(0));if(a=s(a,!o),o)if(a.length>0)return"/"+a;else return"/";return a.length>0?a:"."},normalize:function(e){if(t(e),0===e.length)return".";var r=47===e.charCodeAt(0),a=47===e.charCodeAt(e.length-1);return(0!==(e=s(e,!r)).length||r||(e="."),e.length>0&&a&&(e+="/"),r)?"/"+e:e},isAbsolute:function(e){return t(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0==arguments.length)return".";for(var e,s=0;s<arguments.length;++s){var a=arguments[s];t(a),a.length>0&&(void 0===e?e=a:e+="/"+a)}return void 0===e?".":r.normalize(e)},relative:function(e,s){if(t(e),t(s),e===s||(e=r.resolve(e))===(s=r.resolve(s)))return"";for(var a=1;a<e.length&&47===e.charCodeAt(a);++a);for(var o=e.length,n=o-a,c=1;c<s.length&&47===s.charCodeAt(c);++c);for(var i=s.length-c,l=n<i?n:i,u=-1,g=0;g<=l;++g){if(g===l){if(i>l){if(47===s.charCodeAt(c+g))return s.slice(c+g+1);else if(0===g)return s.slice(c+g)}else n>l&&(47===e.charCodeAt(a+g)?u=g:0===g&&(u=0));break}var p=e.charCodeAt(a+g);if(p!==s.charCodeAt(c+g))break;47===p&&(u=g)}var d="";for(g=a+u+1;g<=o;++g)(g===o||47===e.charCodeAt(g))&&(0===d.length?d+="..":d+="/..");return d.length>0?d+s.slice(c+u):(c+=u,47===s.charCodeAt(c)&&++c,s.slice(c))},_makeLong:function(e){return e},dirname:function(e){if(t(e),0===e.length)return".";for(var s=e.charCodeAt(0),r=47===s,a=-1,o=!0,n=e.length-1;n>=1;--n)if(47===(s=e.charCodeAt(n))){if(!o){a=n;break}}else o=!1;return -1===a?r?"/":".":r&&1===a?"//":e.slice(0,a)},basename:function(e,s){if(void 0!==s&&"string"!=typeof s)throw TypeError('"ext" argument must be a string');t(e);var r,a=0,o=-1,n=!0;if(void 0!==s&&s.length>0&&s.length<=e.length){if(s.length===e.length&&s===e)return"";var c=s.length-1,i=-1;for(r=e.length-1;r>=0;--r){var l=e.charCodeAt(r);if(47===l){if(!n){a=r+1;break}}else -1===i&&(n=!1,i=r+1),c>=0&&(l===s.charCodeAt(c)?-1==--c&&(o=r):(c=-1,o=i))}return a===o?o=i:-1===o&&(o=e.length),e.slice(a,o)}for(r=e.length-1;r>=0;--r)if(47===e.charCodeAt(r)){if(!n){a=r+1;break}}else -1===o&&(n=!1,o=r+1);return -1===o?"":e.slice(a,o)},extname:function(e){t(e);for(var s=-1,r=0,a=-1,o=!0,n=0,c=e.length-1;c>=0;--c){var i=e.charCodeAt(c);if(47===i){if(!o){r=c+1;break}continue}-1===a&&(o=!1,a=c+1),46===i?-1===s?s=c:1!==n&&(n=1):-1!==s&&(n=-1)}return -1===s||-1===a||0===n||1===n&&s===a-1&&s===r+1?"":e.slice(s,a)},format:function(e){var t,s;if(null===e||"object"!=typeof e)throw TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return t=e.dir||e.root,s=e.base||(e.name||"")+(e.ext||""),t?t===e.root?t+s:t+"/"+s:s},parse:function(e){t(e);var s,r={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return r;var a=e.charCodeAt(0),o=47===a;o?(r.root="/",s=1):s=0;for(var n=-1,c=0,i=-1,l=!0,u=e.length-1,g=0;u>=s;--u){if(47===(a=e.charCodeAt(u))){if(!l){c=u+1;break}continue}-1===i&&(l=!1,i=u+1),46===a?-1===n?n=u:1!==g&&(g=1):-1!==n&&(g=-1)}return -1===n||-1===i||0===g||1===g&&n===i-1&&n===c+1?-1!==i&&(0===c&&o?r.base=r.name=e.slice(1,i):r.base=r.name=e.slice(c,i)):(0===c&&o?(r.name=e.slice(1,n),r.base=e.slice(1,i)):(r.name=e.slice(c,n),r.base=e.slice(c,i)),r.ext=e.slice(n,i)),c>0?r.dir=e.slice(0,c-1):o&&(r.dir="/"),r},sep:"/",delimiter:":",win32:null,posix:null};r.posix=r,e.exports=r}},t={};function a(s){var r=t[s];if(void 0!==r)return r.exports;var o=t[s]={exports:{}},n=!0;try{e[s](o,o.exports,a),n=!1}finally{n&&delete t[s]}return o.exports}a.ab=s+"/",r.exports=a(114)}()},7647:e=>{"use strict";var{g:t,__dirname:s}=e;{e.s({PROJECT_CONFIG_PATH:()=>s,ProjectStatus:()=>o,WORKSPACE_CONFIG:()=>t});var r=e.i(86442),a=e.i(87733);let t={WORKSPACE_ROOT:(0,a.join)((0,r.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,r.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},s=(0,a.join)((0,r.homedir)(),".prime-projects.json");var o=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e.INCOMPLETE="incomplete",e}({})}},9993:e=>{"use strict";var{g:t,__dirname:s}=e;{e.s({default:()=>t});var r=e.i(20393),a=e.i(19886),o=e.i(42152),n=e.i(86871),c=e.i(7647);let t=()=>{let e=(0,o.useRouter)(),[t,s]=(0,a.useState)({isInitializing:!1,isCompleted:!1,isLoading:!0,hasCompleted:!1,globalProgress:0,globalMessage:"正在检查工作空间状态...",projects:{}}),[i,l]=(0,a.useState)({});(0,a.useEffect)(()=>{u()},[]);let u=async()=>{try{s(e=>({...e,isLoading:!0,globalMessage:"正在检查工作空间状态..."}));let e=await fetch("/api/check-workspace"),t=await e.json();if(t.success){let e={};t.projects.forEach(t=>{e[t.name]={name:t.name,status:t.status,progress:100*(t.status===c.ProjectStatus.EXISTING),message:t.message,canRetry:!1,needsCleanup:t.needsCleanup||!1}}),s(s=>({...s,isLoading:!1,projects:e,globalMessage:t.message||"检查完成"}))}else s(e=>({...e,isLoading:!1,globalMessage:t.error||"检查工作空间状态失败"}))}catch(e){s(e=>({...e,isLoading:!1,globalMessage:"无法连接到服务器,请刷新页面重试"})),console.error("检查工作空间状态失败:",e)}},g=e=>{switch(e.type){case"initialization":case"workspace_created":case"projects_loaded":if(s(t=>({...t,globalProgress:e.progress||0,globalMessage:e.message||""})),e.projects&&Array.isArray(e.projects)){let t={};e.projects.forEach(e=>{t[e]={name:e,status:c.ProjectStatus.PENDING,progress:0,message:"等待开始...",canRetry:!1}}),s(e=>({...e,projects:t}))}break;case"project_existing":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,globalMessage:e.message??"",projects:{...s.projects,[t]:{...s.projects[t],status:c.ProjectStatus.EXISTING,message:"项目已存在",progress:100,canRetry:!1}}}))}break;case"project_start":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,globalMessage:e.message??"",projects:{...s.projects,[t]:{...s.projects[t],status:c.ProjectStatus.CLONING,message:"开始克隆...",progress:0}}}))}break;case"project_progress":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,projects:{...s.projects,[t]:{...s.projects[t],message:e.message??"",progress:Math.min(e.progress??0,100)}}}))}break;case"project_success":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,projects:{...s.projects,[t]:{...s.projects[t],status:c.ProjectStatus.SUCCESS,message:"克隆成功",progress:100,canRetry:!1}}}))}break;case"project_failed":if(e.projectName){let t=e.projectName;s(s=>({...s,globalProgress:e.progress??s.globalProgress,projects:{...s.projects,[t]:{...s.projects[t],status:c.ProjectStatus.FAILED,message:"克隆失败",error:e.error,canRetry:!0}}}))}break;case"command_log":if(e.projectName&&e.logType&&void 0!==e.content&&e.timestamp){let t=e.projectName,r=e.logType,a=e.content,o=e.timestamp;s(e=>({...e,projects:{...e.projects,[t]:{...e.projects[t],logs:[...e.projects[t]?.logs||[],{type:r,content:a,timestamp:o}].slice(-1e3)}}}))}break;case"completion":s(t=>({...t,isInitializing:!1,isCompleted:!0,hasCompleted:!0,globalProgress:100,globalMessage:e.message??"初始化完成",completionSummary:e.result?{success:e.result.success,totalProjects:e.result.totalProjects,successCount:e.result.successCount,failedCount:e.result.failedCount,duration:e.result.duration}:void 0}));break;case"error":s(t=>({...t,isInitializing:!1,hasCompleted:!0,globalMessage:e.message??"发生错误",globalProgress:e.progress??t.globalProgress}))}},p=async e=>{s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isOpening:!0}}}));try{let t=await fetch("/api/open-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:e})}),r=await t.json();if(r.success&&r.cursorUrl){let e=document.createElement("a");e.href=r.cursorUrl,e.style.display="none",document.body.appendChild(e),e.click(),document.body.removeChild(e)}else console.error("打开项目失败:",r.error);s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isOpening:!1}}}))}catch(t){s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isOpening:!1}}})),console.error("打开项目失败:",t)}},d=async e=>{s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isCleaningUp:!0}}}));try{let t=await fetch("/api/cleanup-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:e})}),r=await t.json();r.success?s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],status:c.ProjectStatus.PENDING,message:"已清理,待克隆",isCleaningUp:!1,needsCleanup:!1}}})):s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],isCleaningUp:!1,error:r.error}}}))}catch(t){s(s=>({...s,projects:{...s.projects,[e]:{...s.projects[e],isCleaningUp:!1,error:t instanceof Error?t.message:String(t)}}}))}},m=async e=>{s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],status:c.ProjectStatus.RETRYING,message:"正在重试...",progress:0,canRetry:!1}}}));try{let t=await fetch("/api/retry-project",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:e})}),r=await t.json();s(t=>({...t,projects:{...t.projects,[e]:{...t.projects[e],status:r.success?c.ProjectStatus.SUCCESS:c.ProjectStatus.FAILED,message:r.message,error:r.error,progress:r.success?100:t.projects[e].progress,canRetry:!r.success}}}))}catch(t){s(s=>({...s,projects:{...s.projects,[e]:{...s.projects[e],status:c.ProjectStatus.FAILED,message:"重试失败",error:t instanceof Error?t.message:String(t),canRetry:!0}}}))}},j=e=>{switch(e){case c.ProjectStatus.EXISTING:case c.ProjectStatus.SUCCESS:return"text-green-600 bg-green-50 border-green-200";case c.ProjectStatus.FAILED:return"text-red-600 bg-red-50 border-red-200";case c.ProjectStatus.INCOMPLETE:return"text-orange-600 bg-orange-50 border-orange-200";case c.ProjectStatus.CLONING:case c.ProjectStatus.RETRYING:return"text-blue-600 bg-blue-50 border-blue-200";case c.ProjectStatus.PENDING:default:return"text-gray-600 bg-gray-50 border-gray-200"}},h=e=>{switch(e){case c.ProjectStatus.PENDING:return"待克隆";case c.ProjectStatus.EXISTING:return"已存在";case c.ProjectStatus.CLONING:return"克隆中";case c.ProjectStatus.SUCCESS:return"成功";case c.ProjectStatus.FAILED:return"失败";case c.ProjectStatus.INCOMPLETE:return"不完整";case c.ProjectStatus.RETRYING:return"重试中";default:return"未知"}},f=()=>{let e=Object.values(t.projects);return e.length>0&&e.every(e=>e.status===c.ProjectStatus.EXISTING)},b=t=>{e.push(`/configuration?project=${encodeURIComponent(t)}`)};return(0,r.jsxs)("div",{className:"container mx-auto p-4 sm:p-6 md:p-8",children:[(0,r.jsxs)("div",{className:"flex justify-between items-center mb-6",children:[(0,r.jsx)("h1",{className:"text-2xl font-bold",children:"项目初始化"}),t.isLoading?(0,r.jsx)(n.Button,{disabled:!0,children:"检查中..."}):(0,r.jsx)(n.Button,{onClick:()=>{s(e=>({...e,isInitializing:!0,isCompleted:!1,hasCompleted:!1,globalProgress:0,globalMessage:"正在连接服务器...",projects:{},completionSummary:void 0}));let e=new EventSource("/api/initialize-workspace");e.onmessage=e=>{try{let t=JSON.parse(e.data);g(t)}catch(e){console.error("解析 SSE 消息失败:",e)}},e.onerror=()=>{s(e=>e.hasCompleted?e:{...e,isInitializing:!1,globalMessage:"连接服务器失败,请重试"}),e.close()},e.addEventListener("error",()=>{e.close()})},disabled:t.isInitializing,children:t.isInitializing?"初始化中...":"创建项目空间"})]}),(t.isInitializing||t.isCompleted)&&!f()&&(0,r.jsxs)("div",{className:"mb-6 p-4 bg-gray-50 rounded-lg",children:[(0,r.jsxs)("div",{className:"flex justify-between items-center mb-2",children:[(0,r.jsx)("span",{className:"text-sm font-medium",children:t.globalMessage}),(0,r.jsxs)("span",{className:"text-sm text-gray-600",children:[t.globalProgress,"%"]})]}),(0,r.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-2",children:(0,r.jsx)("div",{className:"bg-blue-600 h-2 rounded-full transition-all duration-300",style:{width:`${t.globalProgress}%`}})})]}),t.completionSummary&&!f()&&(0,r.jsxs)("div",{className:`mb-6 p-4 rounded-lg border ${t.completionSummary.success?"bg-green-50 border-green-200":"bg-yellow-50 border-yellow-200"}`,children:[(0,r.jsx)("h3",{className:"font-semibold mb-2",children:"初始化完成"}),(0,r.jsxs)("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-sm",children:[(0,r.jsxs)("div",{children:["总项目数: ",t.completionSummary.totalProjects]}),(0,r.jsxs)("div",{className:"text-green-600",children:["成功: ",t.completionSummary.successCount]}),(0,r.jsxs)("div",{className:"text-red-600",children:["失败: ",t.completionSummary.failedCount]}),(0,r.jsxs)("div",{children:["耗时: ",Math.round(t.completionSummary.duration/1e3),"s"]})]})]}),(0,r.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",children:Object.keys(t.projects).length>0?Object.values(t.projects).map(e=>(0,r.jsxs)("div",{className:`border rounded-lg p-4 ${j(e.status)}`,children:[(0,r.jsxs)("div",{className:"flex justify-between items-start mb-2",children:[(0,r.jsx)("h2",{className:"font-semibold cursor-pointer hover:text-blue-600 transition-colors",onClick:()=>b(e.name),title:"点击进入项目配置",children:e.name}),(0,r.jsx)("span",{className:"text-xs px-2 py-1 rounded-full bg-white",children:h(e.status)})]}),(0,r.jsx)("p",{className:"text-sm mb-2",children:e.message}),e.status===c.ProjectStatus.CLONING||e.status===c.ProjectStatus.RETRYING?(0,r.jsxs)("div",{className:"mb-2",children:[(0,r.jsx)("div",{className:"w-full bg-white rounded-full h-1",children:(0,r.jsx)("div",{className:"bg-current h-1 rounded-full transition-all duration-300",style:{width:`${e.progress}%`}})}),(0,r.jsxs)("span",{className:"text-xs",children:[e.progress,"%"]})]}):null,e.error&&(0,r.jsx)("p",{className:"text-xs text-red-600 mb-2",children:e.error}),(0,r.jsxs)("div",{className:"space-y-2",children:[e.canRetry&&(0,r.jsx)(n.Button,{size:"sm",variant:"outline",onClick:()=>m(e.name),className:"w-full",children:"重试"}),e.needsCleanup&&e.status===c.ProjectStatus.INCOMPLETE&&(0,r.jsx)(n.Button,{size:"sm",variant:"destructive",onClick:()=>d(e.name),disabled:e.isCleaningUp,className:"w-full",children:e.isCleaningUp?"清理中...":"清理项目"}),(e.status===c.ProjectStatus.EXISTING||e.status===c.ProjectStatus.SUCCESS)&&(0,r.jsx)(n.Button,{size:"sm",variant:"default",onClick:()=>p(e.name),disabled:e.isOpening,className:"w-full",children:e.isOpening?"打开中...":"在 Cursor 中打开"}),e.logs&&e.logs.length>0&&(0,r.jsx)(n.Button,{size:"sm",variant:"outline",onClick:()=>l(t=>({...t,[e.name]:!t[e.name]})),className:"w-full",children:i[e.name]?"隐藏日志":`查看日志 (${e.logs.length})`})]}),i[e.name]&&e.logs&&e.logs.length>0&&(0,r.jsx)("div",{className:"mt-3 border-t pt-3",children:(0,r.jsx)("div",{className:"bg-black text-white rounded text-xs font-mono p-2 max-h-48 overflow-y-auto",children:e.logs.map((e,t)=>(0,r.jsxs)("div",{className:`mb-1 ${"stderr"===e.type?"text-red-400":"progress"===e.type?"text-yellow-400":"text-green-400"}`,children:[(0,r.jsx)("span",{className:"text-gray-500 mr-2",children:new Date(e.timestamp).toLocaleTimeString()}),(0,r.jsxs)("span",{className:"text-blue-400 mr-2",children:["[",e.type,"]"]}),(0,r.jsx)("span",{className:"whitespace-pre-wrap",children:e.content})]},t))})})]},e.name)):(0,r.jsx)("div",{className:"col-span-full text-center text-gray-500 py-8",children:t.isLoading?"正在检查项目状态...":t.isInitializing?"正在加载项目...":'点击"创建项目空间"开始初始化'})})]})}}}}]);
2
2
 
3
- //# sourceMappingURL=2c669537f498f2db.js.map
3
+ //# sourceMappingURL=f31695470ae3a484.js.map