@kitecd/cli 1.2.0 → 1.3.0

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 (87) hide show
  1. package/dist/index.js +12 -0
  2. package/dist/server/index.js +2827 -137
  3. package/dist/upload.js +3 -1
  4. package/dist/web/assets/AuditLog-BO9BJdsk.js +1 -0
  5. package/dist/web/assets/ConfirmDialog-CikXU818.js +1 -0
  6. package/dist/web/assets/Dashboard-ho157_Gr.js +1 -0
  7. package/dist/web/assets/DefaultLayout-Y_852d55.js +1 -0
  8. package/dist/web/assets/DefaultLayout-lj5NNciV.css +1 -0
  9. package/dist/web/assets/FileExplorer-oxT6ZdHt.js +1 -0
  10. package/dist/web/assets/FolderPickerDialog-CDO-yrvE.css +1 -0
  11. package/dist/web/assets/FolderPickerDialog-CKohwBIP.js +1 -0
  12. package/dist/web/assets/LogBoard-DkvHTXcb.js +6 -0
  13. package/dist/web/assets/LogBoard-Dx8yNofc.css +1 -0
  14. package/dist/web/assets/LogTail-CuaBDDKf.js +9 -0
  15. package/dist/web/assets/Login-kcvq2T9U.js +1 -0
  16. package/dist/web/assets/Migration-C_M_Exzf.js +1 -0
  17. package/dist/web/assets/ProjectDetail-BTOfo71A.js +1 -0
  18. package/dist/web/assets/ProjectList-D_PoTDT9.js +1 -0
  19. package/dist/web/assets/ProjectList-YJlvRRNh.css +1 -0
  20. package/dist/web/assets/ProjectTagsEditor-zXN_5rwP.js +1 -0
  21. package/dist/web/assets/Settings-BL4hNZpU.js +1 -0
  22. package/dist/web/assets/Storage-B-pZjj08.js +1 -0
  23. package/dist/web/assets/Storage-CFbfZtA5.css +1 -0
  24. package/dist/web/assets/Terminal-Bh7bM6Bb.css +1 -0
  25. package/dist/web/assets/Terminal-fTZlKf2Y.js +7 -0
  26. package/dist/web/assets/{activity-Ba-YPfmn.js → activity-DZCOq6kQ.js} +1 -1
  27. package/dist/web/assets/{archive-CJ5gDBKY.js → archive-MB1JcYug.js} +1 -1
  28. package/dist/web/assets/arrow-left-CsZYc3XK.js +1 -0
  29. package/dist/web/assets/{circle-alert-DQzM-U4P.js → circle-alert-kmcvMchB.js} +1 -1
  30. package/dist/web/assets/clock-DIBzfDoY.js +1 -0
  31. package/dist/web/assets/constants-m1eFfRMw.js +1 -0
  32. package/dist/web/assets/{copy-C1rADgcQ.js → copy-CNXWZJbC.js} +1 -1
  33. package/dist/web/assets/createLucideIcon-BmsTm7z-.js +1 -0
  34. package/dist/web/assets/{database-CI6acTSY.js → database-D6rC_24l.js} +1 -1
  35. package/dist/web/assets/{eye-off-4PD31MPV.js → eye-off-BNUfzp8P.js} +1 -1
  36. package/dist/web/assets/{eye-Cas8HsmK.js → eye-vRDqRzR9.js} +1 -1
  37. package/dist/web/assets/file-text-BxWt6is5.js +1 -0
  38. package/dist/web/assets/{folder-D9pvA6oI.js → folder-CYPJgLMr.js} +1 -1
  39. package/dist/web/assets/{folder-open-CGeIri0U.js → folder-open-DQz0XviI.js} +1 -1
  40. package/dist/web/assets/{hard-drive-CGWwV4Ei.js → hard-drive-DBiQxkNS.js} +1 -1
  41. package/dist/web/assets/history-dkZbN_TB.js +1 -0
  42. package/dist/web/assets/{house-8ZvvlaEh.js → house-D9JIOKIs.js} +1 -1
  43. package/dist/web/assets/index-BZU6i5nw.js +2 -0
  44. package/dist/web/assets/index-BrlC5Hdt.css +1 -0
  45. package/dist/web/assets/loader-circle-OwtRa1dp.js +1 -0
  46. package/dist/web/assets/pencil-BTFuj0gA.js +1 -0
  47. package/dist/web/assets/plus-CcefsCv_.js +1 -0
  48. package/dist/web/assets/{refresh-cw-0yb8DZDc.js → refresh-cw-OqaxwQhF.js} +1 -1
  49. package/dist/web/assets/{rotate-ccw-YevaWXw9.js → rotate-ccw-D8C0iiAw.js} +1 -1
  50. package/dist/web/assets/{save-BuzCP3T1.js → save-D0NTjP8Q.js} +1 -1
  51. package/dist/web/assets/{scroll-text-BIYMFNN5.js → scroll-text-6UwJwqap.js} +1 -1
  52. package/dist/web/assets/{server-B31hj0g7.js → server-DFHpqwVn.js} +1 -1
  53. package/dist/web/assets/square-terminal-C1oJyHEG.js +1 -0
  54. package/dist/web/assets/{sun-BaEbKNDV.js → sun-Cg6PdQms.js} +1 -1
  55. package/dist/web/assets/terminal-CUz5b_ol.js +1 -0
  56. package/dist/web/assets/{trash-2-BWqtqkeW.js → trash-2-20ikd6fk.js} +1 -1
  57. package/dist/web/assets/useIntervalRaf-CXWU2lqg.js +1 -0
  58. package/dist/web/index.html +3 -3
  59. package/package.json +10 -6
  60. package/scripts/postinstall.js +53 -0
  61. package/dist/web/assets/AuditLog-BFmJfgzL.js +0 -1
  62. package/dist/web/assets/ConfirmDialog-CJ8lJeUc.js +0 -1
  63. package/dist/web/assets/Dashboard-BTliTkq1.js +0 -1
  64. package/dist/web/assets/DefaultLayout-BG_y85yG.js +0 -1
  65. package/dist/web/assets/DefaultLayout-CZENO67n.css +0 -1
  66. package/dist/web/assets/FileExplorer-Bf32_MMS.js +0 -1
  67. package/dist/web/assets/LogBoard-0so-XiW3.css +0 -1
  68. package/dist/web/assets/LogBoard-CDz4n0DY.js +0 -6
  69. package/dist/web/assets/Login-C3zfObzP.js +0 -1
  70. package/dist/web/assets/Migration-BaKlcCkB.js +0 -1
  71. package/dist/web/assets/ProjectDetail-BL_D0OJY.js +0 -1
  72. package/dist/web/assets/ProjectList-7AnhOS7h.css +0 -1
  73. package/dist/web/assets/ProjectList-C4KuZEq4.js +0 -1
  74. package/dist/web/assets/Settings-CzWG9312.js +0 -1
  75. package/dist/web/assets/Storage-BCao_e7Y.js +0 -1
  76. package/dist/web/assets/Storage-DNadqpUy.css +0 -1
  77. package/dist/web/assets/arrow-left-WEOMLXIi.js +0 -1
  78. package/dist/web/assets/chevron-right-DLiDJVJl.js +0 -1
  79. package/dist/web/assets/clock-IwxBKgP4.js +0 -1
  80. package/dist/web/assets/constants-Ch47JPs3.js +0 -1
  81. package/dist/web/assets/createLucideIcon-CE-ry2oA.js +0 -1
  82. package/dist/web/assets/file-text-C6nzo1us.js +0 -1
  83. package/dist/web/assets/index-BFE6PEIL.js +0 -2
  84. package/dist/web/assets/index-XrzJwjrk.css +0 -1
  85. package/dist/web/assets/loader-circle-uiC7GaCG.js +0 -1
  86. package/dist/web/assets/plus-CfMi1Jv1.js +0 -1
  87. package/dist/web/assets/square-terminal-DT6aoXm0.js +0 -1
package/dist/upload.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import { randomUUID } from 'crypto';
3
3
  export async function uploadZip(options) {
4
- const { serverUrl, token, zipFilePath, projectId, preDeploy, postDeploy, env, startedAt } = options;
4
+ const { serverUrl, token, zipFilePath, projectId, preDeploy, postDeploy, postDeployAsync, env, startedAt } = options;
5
5
  const traceId = options.traceId || randomUUID();
6
6
  const fileData = await fs.promises.readFile(zipFilePath);
7
7
  const blob = new Blob([fileData], { type: 'application/zip' });
@@ -12,6 +12,8 @@ export async function uploadZip(options) {
12
12
  form.append('preDeploy', preDeploy);
13
13
  if (postDeploy)
14
14
  form.append('postDeploy', postDeploy);
15
+ if (typeof postDeployAsync === 'boolean')
16
+ form.append('postDeployAsync', postDeployAsync ? 'true' : 'false');
15
17
  if (env && Object.keys(env).length > 0)
16
18
  form.append('env', JSON.stringify(env));
17
19
  if (startedAt)
@@ -0,0 +1 @@
1
+ import{A as e,D as t,M as n,U as r,V as i,b as ee,c as a,d as o,f as s,ft as c,h as l,m as u,mt as d,n as te,q as f,t as p,v as m,y as h,z as g}from"./createLucideIcon-BmsTm7z-.js";import{n as ne,t as re}from"./file-text-BxWt6is5.js";import{t as ie}from"./circle-alert-kmcvMchB.js";import{t as ae}from"./refresh-cw-OqaxwQhF.js";import{t as oe}from"./scroll-text-6UwJwqap.js";import{g as _,h as se,l as ce,o as v,r as y,s as b,u as le,y as ue}from"./index-BZU6i5nw.js";var de=p(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),fe=p(`funnel`,[[`path`,{d:`M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z`,key:`sc7q7i`}]]),pe={class:`space-y-6`},me={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},he={class:`flex items-center gap-3 min-w-0`},ge=[`disabled`],_e={class:`bg-panel border border-border rounded-lg p-4`},ve={class:`flex items-center gap-2 mb-3 text-sm text-textMuted`},ye={class:`grid grid-cols-1 md:grid-cols-4 gap-3`},be=[`value`],xe={class:`flex items-end`},Se=[`disabled`],Ce={class:`bg-panel border border-border rounded-lg overflow-hidden`},x={key:0,class:`p-12 text-center text-textMuted`},S={key:1,class:`p-12 text-center`},C={key:2,class:`overflow-x-auto`},w={class:`w-full text-sm min-w-[720px]`},T=[`onClick`],E={class:`px-4 py-3 text-textMuted font-mono text-xs whitespace-nowrap`},D={class:`px-4 py-3`},O={class:`px-4 py-3`},k={key:0,class:`text-textMain`},A={key:1,class:`text-xs text-textMuted font-mono`},we={key:2,class:`text-textMuted`},Te={class:`px-4 py-3 text-textMain max-w-xs truncate`},Ee={class:`px-4 py-3 text-textMuted font-mono text-xs`},De={class:`px-4 py-3`},Oe={key:0,class:`inline-flex items-center gap-1 text-success text-xs`},ke={key:1,class:`inline-flex items-center gap-1 text-danger text-xs`},Ae={class:`px-4 py-3 text-right`},je={key:3,class:`flex items-center justify-between px-4 py-3 border-t border-border bg-base/30`},Me={class:`text-xs text-textMuted`},Ne={class:`flex items-center gap-2`},Pe=[`disabled`],Fe=[`disabled`],Ie={class:`relative w-full max-w-2xl h-full bg-panel border-l border-border overflow-y-auto`},Le={class:`sticky top-0 bg-panel border-b border-border px-6 py-4 flex items-center justify-between`},Re={class:`text-xs text-textMuted font-mono mt-1`},j={class:`p-6 space-y-5`},ze={class:`grid grid-cols-2 gap-4 text-sm`},Be={class:`text-xs text-textMuted font-mono mt-1`},Ve={key:0,class:`inline-flex items-center gap-1 text-success text-xs`},He={key:1,class:`inline-flex items-center gap-1 text-danger text-xs`},Ue={class:`text-textMain font-mono text-xs`},We={class:`text-textMain font-mono text-xs`},Ge={class:`col-span-2`},Ke={class:`text-textMain`},qe={key:0,class:`text-xs text-textMuted font-mono break-all`},Je={key:0,class:`col-span-2`},Ye={class:`text-textMain`},Xe={key:1,class:`col-span-2`},Ze={class:`text-danger text-sm`},Qe={key:0,class:`space-y-3`},$e={class:`grid grid-cols-1 md:grid-cols-2 gap-3`},et={class:`bg-base border border-border rounded p-3 text-xs text-textMain font-mono overflow-auto max-h-96`},tt={class:`bg-base border border-border rounded p-3 text-xs text-textMain font-mono overflow-auto max-h-96`},M=50,N=ee({__name:`AuditLog`,setup(ee){let p=te(),N=ce(),nt=le(),P=r([]),F=r(0),I=r(!1),L=r(null),R=r(0),z=r(``),B=r(``),V=r(``),H=[{value:``,label:`全部操作`},{value:`project.create`,label:`创建项目`},{value:`project.update`,label:`更新项目`},{value:`project.delete`,label:`删除项目`},{value:`project.token.rotate`,label:`重置项目 Token`},{value:`settings.update`,label:`更新系统设置`},{value:`admin_token.change`,label:`修改 Admin Token`},{value:`migration.export`,label:`导出迁移包`},{value:`migration.import`,label:`导入迁移包`},{value:`auth.login_failed`,label:`登录失败`}],U=e=>H.find(t=>t.value===e)?.label||e,W=e=>e.endsWith(`.delete`)?`text-danger bg-danger/10 border-danger/30`:e.endsWith(`.create`)?`text-success bg-success/10 border-success/30`:e.includes(`token`)||e.includes(`admin_token`)?`text-yellow-400 bg-yellow-400/10 border-yellow-400/30`:e.startsWith(`migration.`)?`text-primary bg-primary/10 border-primary/30`:e.startsWith(`auth.`)?`text-textMuted bg-white/5 border-border`:`text-primary bg-primary/10 border-primary/30`,G=o(()=>Math.max(1,Math.ceil(F.value/M))),K=o(()=>Math.floor(R.value/M)+1),q=e=>{if(!e)return`-`;let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`},J=e=>{if(!e)return null;try{return JSON.parse(e)}catch{return e}},Y=o(()=>J(L.value?.before??null)),X=o(()=>J(L.value?.after??null)),rt=o(()=>Y.value!==null||X.value!==null);async function Z(){I.value=!0;try{let e=await p.fetchAuditLogs({action:z.value||void 0,targetId:B.value||void 0,targetType:V.value||void 0,limit:M,offset:R.value});P.value=e.rows||[],F.value=e.total||0}finally{I.value=!1}}function it(){z.value=``,B.value=``,V.value=``}function at(){K.value<G.value&&(R.value+=M,Z())}function ot(){R.value>0&&(R.value=Math.max(0,R.value-M),Z())}function st(e){L.value=e}function Q(){L.value=null}t(()=>{let e=N.query;typeof e.action==`string`&&(z.value=e.action),typeof e.targetId==`string`&&(B.value=e.targetId),typeof e.targetType==`string`&&(V.value=e.targetType),Z()});let $=null;return g([z,B,V],([e],[t])=>{$&&clearTimeout($),$=setTimeout(()=>{R.value=0;let e={};z.value&&(e.action=z.value),B.value&&(e.targetId=B.value),V.value&&(e.targetType=V.value),nt.replace({query:e}),Z()},e===t?300:0)}),g(()=>N.query.targetId,e=>{typeof e==`string`&&e!==B.value&&(B.value=e)}),(t,r)=>(e(),l(`div`,pe,[s(`div`,me,[s(`div`,he,[h(f(oe),{class:`w-6 h-6 text-primary shrink-0`}),r[3]||=s(`div`,{class:`min-w-0`},[s(`h1`,{class:`text-2xl font-bold text-textMain`},`操作日志`),s(`p`,{class:`text-sm text-textMuted mt-1`},`所有服务端运维操作的审计记录,含变更前后状态`)],-1)]),s(`button`,{onClick:Z,disabled:I.value,class:`flex items-center gap-2 px-4 py-2 bg-panel border border-border rounded-md text-textMain hover:border-primary/50 transition-colors disabled:opacity-50 self-start sm:self-auto shrink-0`},[h(f(ae),{class:c([`w-4 h-4`,{"animate-spin":I.value}])},null,8,[`class`]),r[4]||=s(`span`,{class:`text-sm`},`刷新`,-1)],8,ge)]),s(`div`,_e,[s(`div`,ve,[h(f(fe),{class:`w-4 h-4`}),r[5]||=s(`span`,null,`筛选`,-1)]),s(`div`,ye,[s(`div`,null,[r[6]||=s(`label`,{class:`block text-xs text-textMuted mb-1`},`操作类型`,-1),i(s(`select`,{"onUpdate:modelValue":r[0]||=e=>z.value=e,class:`w-full bg-base border border-border rounded px-3 py-2 text-sm text-textMain focus:border-primary focus:outline-none`},[(e(),l(a,null,n(H,e=>s(`option`,{key:e.value,value:e.value},d(e.label),9,be)),64))],512),[[se,z.value]])]),s(`div`,null,[r[7]||=s(`label`,{class:`block text-xs text-textMuted mb-1`},`目标 ID`,-1),i(s(`input`,{"onUpdate:modelValue":r[1]||=e=>B.value=e,type:`text`,placeholder:`如 proj_xxxxx`,class:`w-full bg-base border border-border rounded px-3 py-2 text-sm text-textMain focus:border-primary focus:outline-none font-mono`},null,512),[[_,B.value]])]),s(`div`,null,[r[8]||=s(`label`,{class:`block text-xs text-textMuted mb-1`},`目标类型`,-1),i(s(`input`,{"onUpdate:modelValue":r[2]||=e=>V.value=e,type:`text`,placeholder:`如 project / settings`,class:`w-full bg-base border border-border rounded px-3 py-2 text-sm text-textMain focus:border-primary focus:outline-none`},null,512),[[_,V.value]])]),s(`div`,xe,[s(`button`,{onClick:it,disabled:!z.value&&!B.value&&!V.value,class:`w-full px-3 py-2 bg-base border border-border text-textMuted rounded text-sm hover:border-textMuted hover:text-textMain transition-colors disabled:opacity-40 disabled:cursor-not-allowed flex items-center justify-center gap-1.5`},[h(f(y),{class:`w-3.5 h-3.5`}),r[9]||=m(` 清空筛选 `,-1)],8,Se)])])]),s(`div`,Ce,[I.value&&P.value.length===0?(e(),l(`div`,x,` 加载中... `)):P.value.length===0?(e(),l(`div`,S,[h(f(ie),{class:`w-10 h-10 mx-auto text-textMuted mb-3`}),r[10]||=s(`p`,{class:`text-textMuted`},`暂无操作日志`,-1)])):(e(),l(`div`,C,[s(`table`,w,[r[13]||=s(`thead`,{class:`bg-base/50 border-b border-border`},[s(`tr`,{class:`text-left text-xs text-textMuted`},[s(`th`,{class:`px-4 py-3 font-medium`},`时间`),s(`th`,{class:`px-4 py-3 font-medium`},`操作`),s(`th`,{class:`px-4 py-3 font-medium`},`目标`),s(`th`,{class:`px-4 py-3 font-medium`},`摘要`),s(`th`,{class:`px-4 py-3 font-medium`},`来源 IP`),s(`th`,{class:`px-4 py-3 font-medium`},`状态`),s(`th`,{class:`px-4 py-3 font-medium`})])],-1),s(`tbody`,null,[(e(!0),l(a,null,n(P.value,t=>(e(),l(`tr`,{key:t.id,class:`border-b border-border last:border-0 hover:bg-base/50 transition-colors cursor-pointer`,onClick:e=>st(t)},[s(`td`,E,d(q(t.createdAt)),1),s(`td`,D,[s(`span`,{class:c([`inline-flex items-center px-2 py-0.5 rounded text-xs border`,W(t.action)])},d(U(t.action)),3)]),s(`td`,O,[t.targetName?(e(),l(`div`,k,d(t.targetName),1)):u(``,!0),t.targetId?(e(),l(`div`,A,d(t.targetId),1)):u(``,!0),!t.targetName&&!t.targetId?(e(),l(`span`,we,`-`)):u(``,!0)]),s(`td`,Te,d(t.summary||`-`),1),s(`td`,Ee,d(t.actorIp||`-`),1),s(`td`,De,[t.status===`success`?(e(),l(`span`,Oe,[h(f(b),{class:`w-3.5 h-3.5`}),r[11]||=m(` 成功 `,-1)])):(e(),l(`span`,ke,[h(f(v),{class:`w-3.5 h-3.5`}),r[12]||=m(` 失败 `,-1)]))]),s(`td`,Ae,[h(f(re),{class:`w-4 h-4 text-textMuted inline`})])],8,T))),128))])])])),P.value.length>0?(e(),l(`div`,je,[s(`span`,Me,`共 `+d(F.value)+` 条,第 `+d(K.value)+` / `+d(G.value)+` 页`,1),s(`div`,Ne,[s(`button`,{onClick:ot,disabled:R.value===0||I.value,class:`p-1.5 border border-border rounded text-textMuted hover:text-textMain hover:border-textMuted disabled:opacity-40 disabled:cursor-not-allowed`},[h(f(de),{class:`w-4 h-4`})],8,Pe),s(`button`,{onClick:at,disabled:K.value>=G.value||I.value,class:`p-1.5 border border-border rounded text-textMuted hover:text-textMain hover:border-textMuted disabled:opacity-40 disabled:cursor-not-allowed`},[h(f(ne),{class:`w-4 h-4`})],8,Fe)])])):u(``,!0)]),L.value?(e(),l(`div`,{key:0,class:`fixed inset-0 z-50 flex justify-end`,onClick:ue(Q,[`self`])},[s(`div`,{class:`fixed inset-0 bg-black/40`,onClick:Q}),s(`div`,Ie,[s(`div`,Le,[s(`div`,null,[r[14]||=s(`h2`,{class:`text-lg font-bold text-textMain`},`操作详情`,-1),s(`p`,Re,d(L.value.id),1)]),s(`button`,{onClick:Q,class:`p-1.5 hover:bg-base rounded text-textMuted hover:text-textMain`},[h(f(y),{class:`w-5 h-5`})])]),s(`div`,j,[s(`div`,ze,[s(`div`,null,[r[15]||=s(`div`,{class:`text-xs text-textMuted mb-1`},`操作类型`,-1),s(`span`,{class:c([`inline-flex items-center px-2 py-0.5 rounded text-xs border`,W(L.value.action)])},d(U(L.value.action)),3),s(`div`,Be,d(L.value.action),1)]),s(`div`,null,[r[18]||=s(`div`,{class:`text-xs text-textMuted mb-1`},`状态`,-1),L.value.status===`success`?(e(),l(`span`,Ve,[h(f(b),{class:`w-3.5 h-3.5`}),r[16]||=m(` 成功 `,-1)])):(e(),l(`span`,He,[h(f(v),{class:`w-3.5 h-3.5`}),r[17]||=m(` 失败 `,-1)]))]),s(`div`,null,[r[19]||=s(`div`,{class:`text-xs text-textMuted mb-1`},`时间`,-1),s(`div`,Ue,d(q(L.value.createdAt)),1)]),s(`div`,null,[r[20]||=s(`div`,{class:`text-xs text-textMuted mb-1`},`来源 IP`,-1),s(`div`,We,d(L.value.actorIp||`-`),1)]),s(`div`,Ge,[r[21]||=s(`div`,{class:`text-xs text-textMuted mb-1`},`目标`,-1),s(`div`,Ke,d(L.value.targetName||`-`),1),L.value.targetId?(e(),l(`div`,qe,d(L.value.targetType)+`: `+d(L.value.targetId),1)):u(``,!0)]),L.value.summary?(e(),l(`div`,Je,[r[22]||=s(`div`,{class:`text-xs text-textMuted mb-1`},`摘要`,-1),s(`div`,Ye,d(L.value.summary),1)])):u(``,!0),L.value.errorMessage?(e(),l(`div`,Xe,[r[23]||=s(`div`,{class:`text-xs text-textMuted mb-1`},`错误信息`,-1),s(`div`,Ze,d(L.value.errorMessage),1)])):u(``,!0)]),rt.value?(e(),l(`div`,Qe,[r[26]||=s(`div`,{class:`text-xs text-textMuted`},`变更前后`,-1),s(`div`,$e,[s(`div`,null,[r[24]||=s(`div`,{class:`text-xs text-danger mb-1`},`Before`,-1),s(`pre`,et,[s(`code`,null,d(Y.value===null?`(无)`:JSON.stringify(Y.value,null,2)),1)])]),s(`div`,null,[r[25]||=s(`div`,{class:`text-xs text-success mb-1`},`After`,-1),s(`pre`,tt,[s(`code`,null,d(X.value===null?`(无)`:JSON.stringify(X.value,null,2)),1)])])])])):u(``,!0)])])])):u(``,!0)]))}});export{N as default};
@@ -0,0 +1 @@
1
+ import{A as e,B as t,F as n,N as r,T as i,U as a,V as o,b as s,d as c,f as l,ft as u,h as d,m as f,mt as p,p as m,q as h,v as g,y as _,z as v}from"./createLucideIcon-BmsTm7z-.js";import{t as y}from"./refresh-cw-OqaxwQhF.js";import{a as b,d as x,g as S,i as C,r as w,t as T,v as E,y as D}from"./index-BZU6i5nw.js";var O={class:`flex items-start space-x-4`},k={class:`flex-1 min-w-0`},A={class:`text-base font-semibold text-textMain`},j={key:0,class:`text-sm text-textMuted mt-1 whitespace-pre-line`},M=[`disabled`],N={key:0,class:`mt-5`},P={key:0,class:`text-xs text-textMuted mb-2`},F=[`disabled`,`placeholder`,`onKeydown`],I={class:`mt-6 flex items-center justify-end space-x-2`},L=[`disabled`],R=[`disabled`],z=T(s({__name:`ConfirmDialog`,props:{open:{type:Boolean},title:{default:`确认操作`},message:{default:``},tone:{default:`info`},confirmText:{default:`确认`},cancelText:{default:`取消`},loading:{type:Boolean,default:!1},requireText:{default:``},requireTextPlaceholder:{default:``},requireTextHint:{default:``}},emits:[`confirm`,`cancel`,`update:open`],setup(s,{emit:T}){let z=s,B=T,V=a(``),H=a(null),U=c(()=>z.tone===`info`?b:C),W=c(()=>{switch(z.tone){case`danger`:return{border:`border-danger/30`,iconBg:`bg-danger/10`,iconText:`text-danger`,confirmBtn:`bg-danger text-white hover:bg-danger/90`};case`warning`:return{border:`border-yellow-400/30`,iconBg:`bg-yellow-400/10`,iconText:`text-yellow-400`,confirmBtn:`bg-yellow-400 text-black hover:bg-yellow-300`};default:return{border:`border-border`,iconBg:`bg-primary/10`,iconText:`text-primary`,confirmBtn:`bg-primary text-white hover:bg-primary/90`}}}),G=c(()=>z.requireText.length>0),K=c(()=>z.loading?!1:G.value?V.value.trim()===z.requireText:!0);function q(){z.loading||(B(`cancel`),B(`update:open`,!1))}function J(){K.value&&B(`confirm`)}return v(()=>z.open,async e=>{e&&(V.value=``,await i(),H.value?.focus())}),(i,a)=>(e(),m(x,{name:`fade`},{default:t(()=>[s.open?(e(),d(`div`,{key:0,class:`fixed inset-0 z-[60] flex items-center justify-center bg-black/60 backdrop-blur-sm`,onClick:D(q,[`self`])},[l(`div`,{class:u([`bg-panel border rounded-xl w-full max-w-lg p-6 shadow-2xl`,W.value.border]),onKeydown:E(q,[`esc`])},[l(`div`,O,[l(`div`,{class:u([`flex-shrink-0 w-10 h-10 rounded-lg flex items-center justify-center`,W.value.iconBg])},[(e(),m(n(U.value),{class:u([`w-5 h-5`,W.value.iconText])},null,8,[`class`]))],2),l(`div`,k,[l(`h3`,A,p(s.title),1),s.message?(e(),d(`p`,j,p(s.message),1)):f(``,!0),r(i.$slots,`default`,{},void 0,!0)]),l(`button`,{onClick:q,disabled:s.loading,class:`text-textMuted hover:text-textMain rounded p-1 disabled:opacity-50`},[_(h(w),{class:`w-4 h-4`})],8,M)]),G.value?(e(),d(`div`,N,[s.requireTextHint?(e(),d(`p`,P,p(s.requireTextHint),1)):f(``,!0),o(l(`input`,{ref_key:`inputRef`,ref:H,"onUpdate:modelValue":a[0]||=e=>V.value=e,type:`text`,disabled:s.loading,placeholder:s.requireTextPlaceholder||s.requireText,class:`w-full bg-base border border-border rounded-md px-3 py-2 text-textMain font-mono focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 text-sm disabled:opacity-60`,onKeydown:E(D(J,[`prevent`]),[`enter`])},null,40,F),[[S,V.value]])])):f(``,!0),l(`div`,I,[l(`button`,{onClick:q,disabled:s.loading,class:`px-4 py-2 text-sm font-medium text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed`},p(s.cancelText),9,L),l(`button`,{onClick:J,disabled:!K.value,class:u([`px-4 py-2 text-sm font-medium rounded-md transition-colors flex items-center disabled:opacity-50 disabled:cursor-not-allowed`,W.value.confirmBtn])},[s.loading?(e(),m(h(y),{key:0,class:`w-4 h-4 mr-2 animate-spin`})):f(``,!0),g(` `+p(s.loading?`处理中...`:s.confirmText),1)],10,R)])],34)])):f(``,!0)]),_:3}))}}),[[`__scopeId`,`data-v-543f8e0c`]]);export{z as t};
@@ -0,0 +1 @@
1
+ import{A as e,D as t,F as n,M as r,U as i,_ as a,b as o,c as s,d as c,f as l,ft as u,h as d,m as f,mt as p,n as m,p as h,pt as g,q as _,v,y}from"./createLucideIcon-BmsTm7z-.js";import{t as ee}from"./activity-DZCOq6kQ.js";import{t as te}from"./circle-alert-kmcvMchB.js";import{t as b}from"./clock-DIBzfDoY.js";import{n as x,r as S,t as ne}from"./useIntervalRaf-CXWU2lqg.js";import{t as re}from"./hard-drive-DBiQxkNS.js";import{t as C}from"./server-DFHpqwVn.js";import{i as ie,u as ae}from"./index-BZU6i5nw.js";import{t as oe}from"./constants-m1eFfRMw.js";var w={class:`bg-panel border border-border rounded-xl p-4 sm:p-6 shadow-sm`},T={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 mb-4`},E={class:`text-xs text-textMuted mt-1`},D={key:0,class:`text-sm text-textMuted py-8 text-center`},O={key:1,class:`text-sm text-textMuted py-8 text-center`},k={key:2,class:`flex gap-3 overflow-x-auto`},A={class:`flex flex-col justify-around text-[10px] text-textMuted pt-1 pb-1 select-none`},j={class:`flex gap-[3px]`},M=[`title`,`aria-label`],se=o({__name:`DeployHeatmap`,props:{cells:{},loading:{type:Boolean}},setup(t){let n=t,i=[`日`,`一`,`二`,`三`,`四`,`五`,`六`],o=c(()=>{if(!n.cells.length)return{columns:[],max:0};let e=[...n.cells].sort((e,t)=>e.date.localeCompare(t.date)),t=new Date(e[0].date+`T00:00:00Z`).getUTCDay(),r=Array(t).fill(null).concat(e),i=[];for(let e=0;e<r.length;e+=7)i.push(r.slice(e,e+7));if(i.length&&i[i.length-1].length<7)for(;i[i.length-1].length<7;)i[i.length-1].push(null);return{columns:i,max:e.reduce((e,t)=>Math.max(e,t.count),0)}});function f(e,t){if(!e)return`bg-border/40`;if(t<=1)return`bg-emerald-500`;let n=e/t;return n>=.75?`bg-emerald-400`:n>=.5?`bg-emerald-500/80`:n>=.25?`bg-emerald-600/70`:`bg-emerald-700/60`}function m(e){return e?`${e.date} · ${e.count} 次部署`:``}let h=c(()=>n.cells.reduce((e,t)=>e+t.count,0));return(n,c)=>(e(),d(`div`,w,[l(`div`,T,[l(`div`,null,[c[0]||=l(`h3`,{class:`text-base font-semibold text-textMain`},`部署频次热力图`,-1),l(`p`,E,`最近 `+p(t.cells.length)+` 天 · 共 `+p(h.value)+` 次`,1)]),c[1]||=a(`<div class="flex items-center gap-1 text-xs text-textMuted"><span class="mr-1">少</span><span class="w-3 h-3 rounded-sm bg-border/40"></span><span class="w-3 h-3 rounded-sm bg-emerald-700/60"></span><span class="w-3 h-3 rounded-sm bg-emerald-600/70"></span><span class="w-3 h-3 rounded-sm bg-emerald-500/80"></span><span class="w-3 h-3 rounded-sm bg-emerald-400"></span><span class="ml-1">多</span></div>`,1)]),t.loading?(e(),d(`div`,D,`加载中…`)):t.cells.length?(e(),d(`div`,k,[l(`div`,A,[(e(),d(s,null,r(i,e=>l(`span`,{key:e,class:`h-3 leading-3`},p(e),1)),64))]),l(`div`,j,[(e(!0),d(s,null,r(o.value.columns,(t,n)=>(e(),d(`div`,{key:n,class:`flex flex-col gap-[3px]`},[(e(!0),d(s,null,r(t,(t,n)=>(e(),d(`div`,{key:n,class:u([`w-3 h-3 rounded-sm transition-transform hover:scale-125`,t?f(t.count,o.value.max):`bg-transparent`]),title:m(t),"aria-label":m(t)||`无数据`},null,10,M))),128))]))),128))])])):(e(),d(`div`,O,`暂无数据`))]))}}),N={class:`bg-panel border border-border rounded-xl p-4 sm:p-6 shadow-sm`},P={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 mb-4`},F={class:`text-base font-semibold text-textMain`},I={class:`text-xs text-textMuted mt-1`},L={class:`text-success`},R={class:`text-danger`},z={class:`font-mono`},B={key:0,class:`text-sm text-textMuted py-8 text-center`},V={key:1,class:`text-sm text-textMuted py-8 text-center`},H=[`viewBox`],U={class:`text-textMuted`,stroke:`currentColor`,"stroke-opacity":`0.15`},W=[`x2`],G=[`y1`,`x2`,`y2`],K=[`y1`,`x2`,`y2`],ce={class:`text-textMuted`,fill:`currentColor`,"font-size":`10`,"font-family":`monospace`},le=[`x`,`y`],ue=[`x`,`y`],de=[`x`,`y`],fe=[`points`],pe=[`cx`,`cy`,`r`],me={class:`text-textMuted`,fill:`currentColor`,"font-size":`10`,"font-family":`monospace`},he=[`x`,`y`],q=600,J=180,Y=32,X=12,Z=16,Q=28,ge=o({__name:`SuccessRateChart`,props:{points:{},loading:{type:Boolean}},setup(t){let n=t,i=c(()=>{let e=n.points;if(!e.length)return{coords:[],polyline:``,avg:null};let t=q-Y-X,r=J-Z-Q,i=e.length>1?t/(e.length-1):0,a=e.map((e,t)=>{let n=e.rate??1;return{x:Y+i*t,y:Z+r*(1-n),p:e}}),o=e.filter(e=>e.rate!==null),s=o.length?o.reduce((e,t)=>e+(t.rate??0),0)/o.length:null;return{coords:a,polyline:a.map(e=>`${e.x.toFixed(1)},${e.y.toFixed(1)}`).join(` `),avg:s}}),a=c(()=>{let e=n.points;return e.length?(e.length<=7?e.map((e,t)=>t):[0,Math.floor(e.length/2),e.length-1]).map(t=>({x:i.value.coords[t]?.x??0,label:e[t].date.slice(5)})):[]}),o=c(()=>{let e=0,t=0,r=0;for(let i of n.points)e+=i.success,t+=i.failed,r+=i.total;return{success:e,failed:t,total:r}});function f(e){return e==null?`—`:`${(e*100).toFixed(1)}%`}return(n,c)=>(e(),d(`div`,N,[l(`div`,P,[l(`div`,null,[l(`h3`,F,`近 `+p(t.points.length)+` 天部署成功率`,1),l(`p`,I,[v(` 总计 `+p(o.value.total)+` 次 · 成功 `,1),l(`span`,L,p(o.value.success),1),c[0]||=v(` · 失败 `,-1),l(`span`,R,p(o.value.failed),1),c[1]||=v(` · 均值 `,-1),l(`span`,z,p(f(i.value.avg)),1)])])]),t.loading?(e(),d(`div`,B,`加载中…`)):o.value.total?(e(),d(`svg`,{key:2,viewBox:`0 0 ${q} ${J}`,class:`w-full h-44 overflow-visible`,role:`img`,"aria-label":`部署成功率折线图`},[l(`g`,U,[l(`line`,{x1:Y,y1:Z,x2:q-X,y2:Z},null,8,W),l(`line`,{x1:Y,y1:Z+(J-Z-Q)*.5,x2:q-X,y2:Z+(J-Z-Q)*.5},null,8,G),l(`line`,{x1:Y,y1:J-Q,x2:q-X,y2:J-Q},null,8,K)]),l(`g`,ce,[l(`text`,{x:Y-6,y:Z+3,"text-anchor":`end`},`100%`,8,le),l(`text`,{x:Y-6,y:Z+(J-Z-Q)*.5+3,"text-anchor":`end`},`50%`,8,ue),l(`text`,{x:Y-6,y:J-Q+3,"text-anchor":`end`},`0%`,8,de)]),l(`polyline`,{points:i.value.polyline,fill:`none`,class:`text-primary`,stroke:`currentColor`,"stroke-width":`1.5`,"stroke-linejoin":`round`,"stroke-linecap":`round`},null,8,fe),l(`g`,null,[(e(!0),d(s,null,r(i.value.coords,(t,n)=>(e(),d(`circle`,{key:n,cx:t.x,cy:t.y,r:t.p.total===0?1.5:3,class:u(t.p.rate===null?`text-textMuted`:t.p.rate<.8?`text-danger`:`text-primary`),fill:`currentColor`},[l(`title`,null,p(t.p.date)+` · 成功 `+p(t.p.success)+` / 失败 `+p(t.p.failed)+` · `+p(f(t.p.rate)),1)],10,pe))),128))]),l(`g`,me,[(e(!0),d(s,null,r(a.value,(t,n)=>(e(),d(`text`,{key:n,x:t.x,y:J-Q+14,"text-anchor":`middle`},p(t.label),9,he))),128))])],8,H)):(e(),d(`div`,V,`暂无部署`))]))}}),_e={class:`space-y-6 max-w-7xl mx-auto`},ve={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center gap-3 mb-8`},ye={class:`text-sm text-textMuted bg-panel px-3 py-1 rounded-full border border-border self-start sm:self-auto`},be={class:`grid grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-6`},xe={class:`ml-3 sm:ml-4 min-w-0`},Se={class:`text-xs sm:text-sm font-medium text-textMuted truncate`},Ce={class:`text-2xl sm:text-3xl font-bold text-textMain mt-1 font-mono`},we={class:`bg-panel border border-border rounded-xl p-4 sm:p-6 shadow-sm`},Te={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 mb-4`},Ee={class:`text-base font-semibold text-textMain flex items-center gap-2`},De={class:`text-xs text-textMuted mt-1`},Oe={key:0,class:`ml-2 font-mono`},ke={key:0,class:`text-xs text-textMuted font-mono`},Ae={key:0,class:`text-sm text-textMuted py-6 text-center`},je={key:1,class:`grid grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4`},Me={class:`bg-base border border-border rounded-lg p-3`},Ne={class:`flex items-center justify-between text-xs text-textMuted`},Pe={class:`flex items-center gap-1.5`},Fe={class:`font-mono text-textMain`},Ie={class:`mt-2 h-1.5 bg-border rounded-full overflow-hidden`},Le={class:`mt-2 text-[11px] text-textMuted font-mono`},Re={class:`bg-base border border-border rounded-lg p-3`},ze={class:`flex items-center justify-between text-xs text-textMuted`},Be={class:`flex items-center gap-1.5`},Ve={class:`font-mono text-textMain`},He={class:`mt-2 h-1.5 bg-border rounded-full overflow-hidden`},Ue={class:`mt-2 text-[11px] text-textMuted font-mono`},We={class:`bg-base border border-border rounded-lg p-3`},Ge={class:`flex items-center justify-between text-xs text-textMuted`},Ke={class:`flex items-center gap-1.5`},qe={class:`font-mono text-textMain`},Je={class:`mt-2 h-1.5 bg-border rounded-full overflow-hidden`},Ye={class:`mt-2 text-[11px] text-textMuted font-mono`},Xe={class:`bg-base border border-border rounded-lg p-3`},Ze={class:`flex items-center justify-between text-xs text-textMuted`},Qe={class:`flex items-center gap-1.5`},$e={class:`font-mono text-textMain`},et={class:`mt-2 h-1.5 bg-border rounded-full overflow-hidden`},tt={class:`mt-2 text-[11px] text-textMuted font-mono`},nt={class:`bg-base border border-border rounded-lg p-3`},rt={class:`flex items-center justify-between text-xs text-textMuted`},it={class:`flex items-center gap-1.5`},at={class:`font-mono text-textMain`},ot={class:`mt-2 text-[11px] text-textMuted font-mono`},st={class:`bg-base border border-border rounded-lg p-3`},ct={class:`flex items-center justify-between text-xs text-textMuted`},lt={class:`flex items-center gap-1.5`},ut={class:`mt-2 text-sm font-mono text-textMain`},dt={class:`mt-1 text-[11px] text-textMuted font-mono`},ft={class:`grid grid-cols-1 lg:grid-cols-3 gap-6`},pt={class:`lg:col-span-2`},mt={class:`bg-panel border border-border rounded-xl p-4 sm:p-6 shadow-sm`},ht={class:`flex items-center justify-between mb-4`},gt={class:`text-base font-semibold text-textMain flex items-center gap-2`},_t={key:0,class:`text-sm text-textMuted py-6 text-center`},vt={key:1,class:`space-y-2`},yt=[`onClick`],bt={class:`min-w-0`},xt={class:`text-sm font-medium text-textMain truncate`},St={class:`text-xs text-textMuted font-mono mt-0.5`},Ct={key:2,class:`text-sm text-textMuted py-6 text-center`},wt={class:`mt-8`},Tt={class:`bg-panel border border-border rounded-xl overflow-hidden shadow-sm`},Et={class:`divide-y divide-border`},$={key:0,class:`px-6 py-8 text-center text-textMuted`},Dt=[`onClick`],Ot={class:`flex items-center space-x-4 min-w-0`},kt={class:`min-w-0`},At={class:`text-sm font-medium text-textMain truncate`},jt={class:`font-mono text-primary ml-1`},Mt={class:`text-xs text-textMuted mt-1 truncate`},Nt={class:`text-left sm:text-right pl-6 sm:pl-0 shrink-0`},Pt={class:`text-xs sm:text-sm text-textMuted font-mono`},Ft=o({__name:`Dashboard`,setup(a){let o=m(),w=ae(),T=i([]),E=i([]),D=i([]),O=i(!0);t(async()=>{o.fetchProjects(),o.fetchLogs();try{let[e,t,n]=await Promise.all([o.fetchHeatmap(30),o.fetchSuccessRate(14),o.fetchFailureTop(5,30)]);T.value=e?.cells??[],E.value=t?.points??[],D.value=n?.items??[]}finally{O.value=!1}}),ne(async()=>{await o.fetchSystemResources()},5e3);let k=c(()=>o.systemResources);function A(e){if(e==null||!Number.isFinite(e))return`-`;if(e<1024)return`${e} B`;let t=[`KB`,`MB`,`GB`,`TB`],n=e/1024,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r++;return`${n.toFixed(n>=10?0:1)} ${t[r]}`}function j(e){return e==null||!Number.isFinite(e)?`-`:`${e.toFixed(e<10?1:0)}%`}function M(e){if(e==null||!Number.isFinite(e))return`-`;let t=Math.floor(e/86400),n=Math.floor(e%86400/3600),r=Math.floor(e%3600/60);return t>0?`${t}d ${n}h`:n>0?`${n}h ${r}m`:`${r}m`}function N(e){return e==null?`bg-textMuted/40`:e>=90?`bg-danger`:e>=70?`bg-yellow-500`:`bg-primary`}let P=c(()=>o.logs.slice(0,5));function F(e){return!Number.isFinite(e)||e<0?`-`:e<1e3?`${e}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${Math.floor(e/6e4)}m ${Math.round(e%6e4/1e3)}s`}function I(e){if(!e.endTime||!e.startTime)return null;let t=new Date(e.endTime).getTime()-new Date(e.startTime).getTime();return Number.isFinite(t)&&t>=0?t:null}let L=c(()=>{let e=o.logs.filter(e=>e.status!==`running`).map(I).filter(e=>e!==null);if(e.length===0)return`-`;let t=e.reduce((e,t)=>e+t,0);return F(Math.round(t/e.length))}),R=c(()=>[{label:`总计项目数`,value:o.projects.length,icon:C,color:`text-primary`},{label:`成功部署`,value:o.logs.filter(e=>e.status===`success`).length,icon:ee,color:`text-success`},{label:`失败任务`,value:o.logs.filter(e=>e.status===`failed`).length,icon:te,color:`text-danger`},{label:`平均耗时`,value:L.value,icon:b,color:`text-blue-400`}]);function z(e){w.push({name:`LogBoard`,query:{id:e}})}function B(e){w.push({name:`ProjectDetail`,params:{id:e}})}function V(e){return`${(e*100).toFixed(1)}%`}return(t,i)=>(e(),d(`div`,_e,[l(`div`,ve,[i[0]||=l(`h1`,{class:`text-2xl font-bold text-textMain tracking-tight`},`Kite 概览`,-1),l(`div`,ye,` 当前版本:v`+p(_(oe)),1)]),l(`div`,be,[(e(!0),d(s,null,r(R.value,t=>(e(),d(`div`,{key:t.label,class:`bg-panel border border-border rounded-xl p-4 sm:p-6 flex items-center shadow-sm hover:border-primary/50 transition-colors`},[l(`div`,{class:u([`w-10 h-10 sm:w-12 sm:h-12 rounded-lg bg-base flex items-center justify-center border border-border shrink-0`,t.color])},[(e(),h(n(t.icon),{class:`w-5 h-5 sm:w-6 sm:h-6`}))],2),l(`div`,xe,[l(`p`,Se,p(t.label),1),l(`p`,Ce,p(t.value),1)])]))),128))]),l(`div`,we,[l(`div`,Te,[l(`div`,null,[l(`h3`,Ee,[y(_(C),{class:`w-4 h-4 text-primary`}),i[1]||=v(` 服务器资源 `,-1)]),l(`p`,De,[i[2]||=v(` 每 5 秒刷新 · 切到后台自动暂停 `,-1),k.value?(e(),d(`span`,Oe,p(k.value.host.hostname)+` · `+p(k.value.host.platform)+`/`+p(k.value.host.arch)+` · `+p(k.value.host.cpuCount)+` 核 `,1)):f(``,!0)])]),k.value?(e(),d(`div`,ke,` 采集于 `+p(new Date(k.value.collectedAt).toLocaleTimeString()),1)):f(``,!0)]),k.value?(e(),d(`div`,je,[l(`div`,Me,[l(`div`,Ne,[l(`span`,Pe,[y(_(S),{class:`w-3.5 h-3.5`}),i[3]||=v(`整机 CPU`,-1)]),l(`span`,Fe,p(j(k.value.cpu.percent)),1)]),l(`div`,Ie,[l(`div`,{class:u([`h-full rounded-full transition-all`,N(k.value.cpu.percent)]),style:g({width:`${Math.min(100,k.value.cpu.percent??0)}%`})},null,6)]),l(`p`,Le,`负载: `+p(k.value.host.loadAvg.map(e=>e.toFixed(2)).join(` / `)),1)]),l(`div`,Re,[l(`div`,ze,[l(`span`,Be,[y(_(x),{class:`w-3.5 h-3.5`}),i[4]||=v(`整机内存`,-1)]),l(`span`,Ve,p(j(k.value.memory.percentUsed)),1)]),l(`div`,He,[l(`div`,{class:u([`h-full rounded-full transition-all`,N(k.value.memory.percentUsed)]),style:g({width:`${k.value.memory.percentUsed}%`})},null,6)]),l(`p`,Ue,`已用 `+p(A(k.value.memory.usedBytes))+` · 可用 `+p(A(k.value.memory.availableBytes))+` / 总 `+p(A(k.value.memory.totalBytes)),1)]),l(`div`,We,[l(`div`,Ge,[l(`span`,Ke,[y(_(re),{class:`w-3.5 h-3.5`}),i[5]||=v(`磁盘(KITE_HOME)`,-1)]),l(`span`,qe,p(j(k.value.disk.percentUsed)),1)]),l(`div`,Je,[l(`div`,{class:u([`h-full rounded-full transition-all`,N(k.value.disk.percentUsed)]),style:g({width:`${k.value.disk.percentUsed??0}%`})},null,6)]),l(`p`,Ye,`空闲 `+p(A(k.value.disk.freeBytes))+` / 总 `+p(A(k.value.disk.totalBytes)),1)]),l(`div`,Xe,[l(`div`,Ze,[l(`span`,Qe,[y(_(S),{class:`w-3.5 h-3.5`}),i[6]||=v(`Kite 进程 CPU`,-1)]),l(`span`,$e,p(j(k.value.process.cpuPercent)),1)]),l(`div`,et,[l(`div`,{class:u([`h-full rounded-full transition-all`,N(k.value.process.cpuPercent)]),style:g({width:`${Math.min(100,k.value.process.cpuPercent??0)}%`})},null,6)]),l(`p`,tt,`PID `+p(k.value.process.pid)+` · `+p(k.value.process.runtime)+` `+p(k.value.process.runtimeVersion),1)]),l(`div`,nt,[l(`div`,rt,[l(`span`,it,[y(_(x),{class:`w-3.5 h-3.5`}),i[7]||=v(`Kite 进程内存`,-1)]),l(`span`,at,p(A(k.value.process.memoryRssBytes)),1)]),l(`p`,ot,`Heap `+p(A(k.value.process.memoryHeapUsedBytes)),1)]),l(`div`,st,[l(`div`,ct,[l(`span`,lt,[y(_(b),{class:`w-3.5 h-3.5`}),i[8]||=v(`运行时长`,-1)])]),l(`p`,ut,`进程 `+p(M(k.value.process.uptimeSec)),1),l(`p`,dt,`主机 `+p(M(k.value.host.uptimeSec)),1)])])):(e(),d(`div`,Ae,`加载中…`))]),y(se,{cells:T.value,loading:O.value},null,8,[`cells`,`loading`]),l(`div`,ft,[l(`div`,pt,[y(ge,{points:E.value,loading:O.value},null,8,[`points`,`loading`])]),l(`div`,mt,[l(`div`,ht,[l(`div`,null,[l(`h3`,gt,[y(_(ie),{class:`w-4 h-4 text-danger`}),i[9]||=v(` 失败率 TopN `,-1)]),i[10]||=l(`p`,{class:`text-xs text-textMuted mt-1`},`近 30 天 · 至少 3 次部署`,-1)])]),O.value?(e(),d(`div`,_t,`加载中…`)):D.value.length?(e(),d(`ul`,vt,[(e(!0),d(s,null,r(D.value,t=>(e(),d(`li`,{key:t.projectId,onClick:e=>B(t.projectId),class:`flex items-center justify-between px-3 py-2 rounded-lg border border-border bg-base hover:border-primary/40 cursor-pointer transition-colors`},[l(`div`,bt,[l(`p`,xt,p(t.projectName),1),l(`p`,St,p(t.failed)+` / `+p(t.total)+` 失败`,1)]),l(`span`,{class:u([`font-mono text-sm shrink-0 ml-3`,t.rate>=.5?`text-danger`:t.rate>=.2?`text-yellow-400`:`text-textMuted`])},p(V(t.rate)),3)],8,yt))),128))])):(e(),d(`div`,Ct,`暂无符合条件的项目`))])]),l(`div`,wt,[i[11]||=l(`h2`,{class:`text-lg font-semibold text-textMain mb-4`},`最近部署活动`,-1),l(`div`,Tt,[l(`ul`,Et,[P.value.length===0?(e(),d(`li`,$,`暂无部署活动`)):f(``,!0),(e(!0),d(s,null,r(P.value,t=>(e(),d(`li`,{key:t.id,onClick:e=>z(t.id),class:`px-4 sm:px-6 py-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 dark:hover:bg-white/5 hover:bg-black/5 transition-colors cursor-pointer`},[l(`div`,Ot,[l(`div`,{class:u([`w-2 h-2 rounded-full shadow-[0_0_8px_currentColor] shrink-0`,t.status===`success`?`bg-success text-success`:t.status===`failed`?`bg-danger text-danger`:`bg-primary text-primary`])},null,2),l(`div`,kt,[l(`p`,At,[v(`部署`+p(t.status===`success`?`完成`:t.status===`failed`?`失败`:`中`)+`: `,1),l(`span`,jt,p(t.projectName),1)]),l(`p`,Mt,`触发源: `+p(t.triggerSource),1)])]),l(`div`,Nt,[l(`p`,Pt,p(new Date(t.startTime).toLocaleString()),1),l(`p`,{class:u([`text-xs mt-1`,t.status===`success`?`text-success`:t.status===`failed`?`text-danger`:`text-primary`])},p(F(I(t)??NaN)),3)])],8,Dt))),128))])])])]))}});export{Ft as default};
@@ -0,0 +1 @@
1
+ import{A as e,B as t,E as n,F as r,M as i,P as a,U as o,b as s,c,d as l,f as u,ft as d,h as f,m as ee,mt as p,n as te,p as m,q as h,t as g,v as _,y as v,z as y}from"./createLucideIcon-BmsTm7z-.js";import{t as ne}from"./database-D6rC_24l.js";import{t as re}from"./hard-drive-DBiQxkNS.js";import{n as b,t as x}from"./square-terminal-C1oJyHEG.js";import{i as ie,n as S,r as ae,t as oe}from"./sun-Cg6PdQms.js";import{t as C}from"./scroll-text-6UwJwqap.js";import{t as w}from"./terminal-CUz5b_ol.js";import{c as se,d as T,l as ce,r as le,t as E,u as ue}from"./index-BZU6i5nw.js";import{t as D}from"./constants-m1eFfRMw.js";var O=g(`folder-archive`,[[`circle`,{cx:`15`,cy:`19`,r:`2`,key:`u2pros`}],[`path`,{d:`M20.9 19.8A2 2 0 0 0 22 18V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h5.1`,key:`1jj40k`}],[`path`,{d:`M15 11v-1`,key:`cntcp`}],[`path`,{d:`M15 17v-2`,key:`1279jj`}]]),k=g(`log-out`,[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]),A=g(`menu`,[[`path`,{d:`M4 5h16`,key:`1tepv9`}],[`path`,{d:`M4 12h16`,key:`1lakjw`}],[`path`,{d:`M4 19h16`,key:`1djgab`}]]),j=`data:image/svg+xml,%3csvg%20width='32'%20height='32'%20viewBox='0%200%2032%2032'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3crect%20width='32'%20height='32'%20rx='8'%20fill='%2309090B'/%3e%3cpath%20d='M7%2022L16%205L25%2022L16%2018L7%2022Z'%20fill='%233B82F6'/%3e%3cpath%20d='M16%2018L12%2027L16%2024L20%2027L16%2018Z'%20fill='%2310B981'/%3e%3c/svg%3e`,M={class:`min-h-screen bg-base flex`},N={class:`w-64 border-r border-border bg-panel flex-col hidden md:flex`},P={class:`h-16 flex items-center px-6 border-b border-border`},F=[`src`],I={class:`ml-2 text-xs bg-primary/20 text-primary px-2 py-0.5 rounded-full`},L=[`title`,`aria-label`],R={class:`flex-1 py-6 px-3 space-y-1`},z={class:`font-medium text-sm`},B={class:`p-4 border-t border-border space-y-1`},V={class:`h-16 flex items-center px-4 border-b border-border`},H=[`src`],de={class:`ml-2 text-xs bg-primary/20 text-primary px-2 py-0.5 rounded-full`},fe={class:`flex-1 py-6 px-3 space-y-1 overflow-y-auto`},pe={class:`font-medium text-sm`},me={class:`p-4 border-t border-border space-y-1`},he={class:`flex-1 flex flex-col h-screen overflow-hidden min-w-0`},ge={class:`h-16 border-b border-border bg-panel flex items-center px-4 md:hidden`},_e=[`src`],ve=[`title`,`aria-label`],ye={class:`flex-1 overflow-auto p-4 sm:p-6 md:p-8`},U=E(s({__name:`DefaultLayout`,setup(s){let g=ce(),E=ue(),U=te(),W=se(),G=[{name:`概览`,path:`/`,icon:b},{name:`项目管理`,path:`/projects`,icon:O},{name:`部署日志`,path:`/logs`,icon:x},{name:`终端`,path:`/terminal`,icon:w},{name:`操作日志`,path:`/audit`,icon:C},{name:`存储`,path:`/storage`,icon:re},{name:`数据迁移`,path:`/migration`,icon:ne}],K=[`light`,`dark`,`system`],be={light:`浅色`,dark:`深色`,system:`跟随系统`},q=l(()=>W.mode===`system`?ie:W.mode===`dark`?ae:oe),J=l(()=>`外观:${be[W.mode]}(点击切换)`),Y=()=>{let e=K[(K.indexOf(W.mode)+1)%K.length];W.setMode(e)},X=()=>{U.logout(),E.push(`/login`)},Z=e=>g.path===e||e!==`/`&&g.path.startsWith(e),Q=o(!1),xe=()=>{Q.value=!0},$=()=>{Q.value=!1};return y(()=>g.fullPath,()=>{Q.value=!1}),y(Q,e=>{typeof document>`u`||(e?document.body.style.overflow=`hidden`:document.body.style.overflow=``)}),n(()=>{typeof document<`u`&&(document.body.style.overflow=``)}),(n,o)=>{let s=a(`router-link`),l=a(`router-view`);return e(),f(`div`,M,[u(`aside`,N,[u(`div`,P,[v(s,{to:`/`,class:`flex items-center min-w-0 hover:opacity-90 transition-opacity`},{default:t(()=>[u(`img`,{src:h(j),alt:`Kite Logo`,class:`w-6 h-6 mr-2`},null,8,F),o[0]||=u(`span`,{class:`text-lg font-bold text-textMain tracking-wide`},`KITE`,-1),u(`span`,I,`v`+p(h(D)),1)]),_:1}),u(`button`,{onClick:Y,title:J.value,"aria-label":J.value,class:`ml-auto p-1.5 rounded-md text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5 transition-colors`},[(e(),m(r(q.value),{class:`w-4 h-4`}))],8,L)]),u(`nav`,R,[(e(),f(c,null,i(G,n=>v(s,{key:n.path,to:n.path,class:d([`flex items-center px-3 py-2.5 rounded-md transition-all duration-200 group`,[Z(n.path)?`bg-primary/10 text-primary shadow-[inset_2px_0_0_0_#3b82f6]`:`text-textMuted dark:hover:bg-white/5 hover:bg-black/5 hover:text-textMain`]])},{default:t(()=>[(e(),m(r(n.icon),{class:d([`w-5 h-5 mr-3`,Z(n.path)?`text-primary`:`text-textMuted group-hover:text-textMain`])},null,8,[`class`])),u(`span`,z,p(n.name),1)]),_:2},1032,[`to`,`class`])),64))]),u(`div`,B,[v(s,{to:`/settings`,class:d([`flex items-center w-full px-3 py-2 text-sm rounded-md transition-colors`,h(g).path===`/settings`?`bg-primary/10 text-primary shadow-[inset_2px_0_0_0_#3b82f6]`:`text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5`])},{default:t(()=>[v(h(S),{class:d([`w-5 h-5 mr-3`,h(g).path===`/settings`?`text-primary`:`text-textMuted`])},null,8,[`class`]),o[1]||=_(` 系统设置 `,-1)]),_:1},8,[`class`]),u(`button`,{onClick:X,class:`flex items-center w-full px-3 py-2 text-sm text-danger hover:bg-danger/10 rounded-md transition-colors`},[v(h(k),{class:`w-5 h-5 mr-3`}),o[2]||=_(` 退出登录 `,-1)])])]),v(T,{name:`fade`},{default:t(()=>[Q.value?(e(),f(`div`,{key:0,class:`fixed inset-0 z-40 bg-black/60 md:hidden`,onClick:$})):ee(``,!0)]),_:1}),u(`aside`,{class:d([`fixed inset-y-0 left-0 z-50 w-64 border-r border-border bg-panel flex flex-col transform transition-transform duration-200 md:hidden`,Q.value?`translate-x-0`:`-translate-x-full`]),"aria-label":`移动端导航`},[u(`div`,V,[v(s,{to:`/`,class:`flex items-center min-w-0 hover:opacity-90 transition-opacity`,onClick:$},{default:t(()=>[u(`img`,{src:h(j),alt:`Kite Logo`,class:`w-6 h-6 mr-2`},null,8,H),o[3]||=u(`span`,{class:`text-lg font-bold text-textMain tracking-wide`},`KITE`,-1),u(`span`,de,`v`+p(h(D)),1)]),_:1}),u(`button`,{onClick:$,"aria-label":`关闭菜单`,class:`ml-auto p-1.5 rounded-md text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5 transition-colors`},[v(h(le),{class:`w-4 h-4`})])]),u(`nav`,fe,[(e(),f(c,null,i(G,n=>v(s,{key:n.path,to:n.path,class:d([`flex items-center px-3 py-2.5 rounded-md transition-all duration-200 group`,[Z(n.path)?`bg-primary/10 text-primary shadow-[inset_2px_0_0_0_#3b82f6]`:`text-textMuted dark:hover:bg-white/5 hover:bg-black/5 hover:text-textMain`]])},{default:t(()=>[(e(),m(r(n.icon),{class:d([`w-5 h-5 mr-3`,Z(n.path)?`text-primary`:`text-textMuted group-hover:text-textMain`])},null,8,[`class`])),u(`span`,pe,p(n.name),1)]),_:2},1032,[`to`,`class`])),64))]),u(`div`,me,[v(s,{to:`/settings`,class:d([`flex items-center w-full px-3 py-2 text-sm rounded-md transition-colors`,h(g).path===`/settings`?`bg-primary/10 text-primary shadow-[inset_2px_0_0_0_#3b82f6]`:`text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5`])},{default:t(()=>[v(h(S),{class:d([`w-5 h-5 mr-3`,h(g).path===`/settings`?`text-primary`:`text-textMuted`])},null,8,[`class`]),o[4]||=_(` 系统设置 `,-1)]),_:1},8,[`class`]),u(`button`,{onClick:X,class:`flex items-center w-full px-3 py-2 text-sm text-danger hover:bg-danger/10 rounded-md transition-colors`},[v(h(k),{class:`w-5 h-5 mr-3`}),o[5]||=_(` 退出登录 `,-1)])])],2),u(`main`,he,[u(`header`,ge,[u(`button`,{onClick:xe,"aria-label":`打开菜单`,class:`p-1.5 mr-2 rounded-md text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5 transition-colors`},[v(h(A),{class:`w-5 h-5`})]),v(s,{to:`/`,class:`flex items-center min-w-0 hover:opacity-90 transition-opacity`},{default:t(()=>[u(`img`,{src:h(j),alt:`Kite Logo`,class:`w-6 h-6 mr-2`},null,8,_e),o[6]||=u(`span`,{class:`text-lg font-bold text-textMain`},`KITE`,-1)]),_:1}),u(`button`,{onClick:Y,title:J.value,"aria-label":J.value,class:`ml-auto p-1.5 rounded-md text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5 transition-colors`},[(e(),m(r(q.value),{class:`w-4 h-4`}))],8,ve)]),u(`div`,ye,[v(l,null,{default:t(({Component:n})=>[v(T,{name:`fade`,mode:`out-in`},{default:t(()=>[(e(),m(r(n)))]),_:2},1024)]),_:1})])])])}}}),[[`__scopeId`,`data-v-4ff48246`]]);export{U as default};
@@ -0,0 +1 @@
1
+ .fade-enter-active[data-v-4ff48246],.fade-leave-active[data-v-4ff48246]{transition:opacity .2s,transform .2s}.fade-enter-from[data-v-4ff48246],.fade-leave-to[data-v-4ff48246]{opacity:0;transform:translateY(10px)}
@@ -0,0 +1 @@
1
+ import{A as e,D as t,F as n,M as r,P as i,U as a,b as o,c as s,d as c,f as l,ft as u,h as d,m as f,mt as p,n as m,p as h,pt as g,q as _,t as v,v as y,y as b}from"./createLucideIcon-BmsTm7z-.js";import{t as ee}from"./arrow-left-CsZYc3XK.js";import{n as x,t as S}from"./file-text-BxWt6is5.js";import{t as C}from"./folder-open-DQz0XviI.js";import{t as w}from"./folder-CYPJgLMr.js";import{t as T}from"./house-D9JIOKIs.js";import{t as E}from"./loader-circle-OwtRa1dp.js";import{l as D,u as O}from"./index-BZU6i5nw.js";var k=v(`file-braces`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1`,key:`1oajmo`}],[`path`,{d:`M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1`,key:`mpwhp6`}]]),A=v(`file-code`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 12.5 8 15l2 2.5`,key:`1tg20x`}],[`path`,{d:`m14 12.5 2 2.5-2 2.5`,key:`yinavb`}]]),j=v(`file-cog`,[[`path`,{d:`M15 8a1 1 0 0 1-1-1V2a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8z`,key:`1ckgky`}],[`path`,{d:`M20 8v12a2 2 0 0 1-2 2h-4.182`,key:`1726p0`}],[`path`,{d:`m3.305 19.53.923-.382`,key:`ao1pio`}],[`path`,{d:`M4 10.592V4a2 2 0 0 1 2-2h8`,key:`1foop0`}],[`path`,{d:`m4.228 16.852-.924-.383`,key:`1fv9zy`}],[`path`,{d:`m5.852 15.228-.383-.923`,key:`1a9hc2`}],[`path`,{d:`m5.852 20.772-.383.924`,key:`1sh9ke`}],[`path`,{d:`m8.148 15.228.383-.923`,key:`4yu6lf`}],[`path`,{d:`m8.53 21.696-.382-.924`,key:`18b0s9`}],[`path`,{d:`m9.773 16.852.922-.383`,key:`ti6xop`}],[`path`,{d:`m9.773 19.148.922.383`,key:`rws47d`}],[`circle`,{cx:`7`,cy:`18`,r:`3`,key:`lvkj7j`}]]),M=v(`file-image`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`circle`,{cx:`10`,cy:`12`,r:`2`,key:`737tya`}],[`path`,{d:`m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22`,key:`wt3hpn`}]]),N=v(`file`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}]]),te=v(`panel-left`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}]]),P={key:1,class:`w-3.5 mr-1`},F={class:`truncate`},I={key:0},L=o({__name:`FileTreeNode`,props:{node:{},depth:{},selectedFile:{}},emits:[`toggle`,`select`],setup(t,{emit:a}){let o=a;function c(e,t,n){if(t)return n?C:w;let r=e.split(`.`).pop()?.toLowerCase()||``;return[`json`,`jsonc`].includes(r)?k:[`js`,`ts`,`jsx`,`tsx`,`vue`,`svelte`,`py`,`rb`,`go`,`rs`,`java`,`c`,`cpp`,`h`].includes(r)?A:[`png`,`jpg`,`jpeg`,`gif`,`svg`,`webp`,`ico`].includes(r)?M:[`yml`,`yaml`,`toml`,`ini`,`cfg`,`conf`,`env`].includes(r)?j:S}return(a,m)=>{let v=i(`FileTreeNode`,!0);return e(),d(`div`,null,[l(`button`,{class:u([`w-full flex items-center py-1.5 text-sm hover:bg-primary/5 transition-colors`,[t.selectedFile===t.node.path&&!t.node.isDir?`bg-primary/10 text-primary`:`text-textMain`,t.node.isHidden?`opacity-60`:``]]),style:g({paddingLeft:t.depth*16+12+`px`}),onClick:m[0]||=e=>t.node.isDir?o(`toggle`,t.node):o(`select`,t.node)},[t.node.isDir?(e(),h(_(x),{key:0,class:u([`w-3.5 h-3.5 mr-1 shrink-0 transition-transform`,t.node.expanded?`rotate-90`:``])},null,8,[`class`])):(e(),d(`span`,P)),(e(),h(n(c(t.node.name,t.node.isDir,t.node.expanded)),{class:u([`w-4 h-4 mr-1.5 shrink-0`,t.node.isDir?`text-primary/70`:`text-textMuted`])},null,8,[`class`])),l(`span`,F,p(t.node.name),1)],6),t.node.isDir&&t.node.expanded?(e(),d(`div`,I,[t.node.loading?(e(),d(`div`,{key:0,class:`py-1 text-textMuted text-xs flex items-center`,style:g({paddingLeft:t.depth*16+28+`px`})},[b(_(E),{class:`w-3 h-3 animate-spin mr-1`}),m[3]||=y(` 加载中... `,-1)],4)):t.node.children?(e(!0),d(s,{key:1},r(t.node.children,n=>(e(),h(v,{key:n.path,node:n,depth:t.depth+1,"selected-file":t.selectedFile,onToggle:m[1]||=e=>o(`toggle`,e),onSelect:m[2]||=e=>o(`select`,e)},null,8,[`node`,`depth`,`selected-file`]))),128)):f(``,!0)])):f(``,!0)])}}}),R={class:`h-[calc(100vh-4rem)] flex flex-col p-4 md:p-0`},z={class:`flex items-center space-x-3 sm:space-x-4 mb-4`},B={class:`min-w-0 flex-1`},V={class:`text-xl font-bold text-textMain tracking-tight truncate`},H={class:`flex-1 flex flex-col md:flex-row border border-border rounded-xl overflow-hidden bg-panel min-h-0`},U={key:0,class:`flex items-center justify-center py-8 text-textMuted`},W={key:1,class:`py-8 text-center text-textMuted text-sm`},G={key:2,class:`py-2`},K={class:`flex-1 flex flex-col min-w-0 min-h-0`},q={key:0,class:`flex items-center px-4 py-2 border-b border-border text-sm bg-base/30 overflow-x-auto`},J={class:`flex-1 overflow-auto`},Y={key:0,class:`h-full flex items-center justify-center text-textMuted p-4`},X={class:`text-center`},Z={key:1,class:`h-full flex items-center justify-center text-textMuted`},ne={key:2,class:`h-full flex items-center justify-center text-textMuted p-4`},re={class:`text-center`},ie={key:0,class:`text-xs mt-1`},ae={key:3,class:`p-4 text-sm font-mono text-textMain leading-relaxed whitespace-pre-wrap break-all overflow-x-auto`},Q=o({__name:`FileExplorer`,setup(n){let i=D(),o=O(),g=m(),v=i.params.id,S=c(()=>g.getProjectById(v)),C=a([]),w=a(``),k=a(null),A=a(!1),j=a(!0),M=a(!0);t(async()=>{if(await g.fetchProjects(),!S.value){o.replace(`/projects`);return}await P(``)});async function P(e){j.value=!0,C.value=(await g.fetchFiles(v,e)).map(e=>({...e,expanded:!1,children:void 0,loading:!1})),j.value=!1}async function F(e){if(e.isDir){if(e.expanded){e.expanded=!1;return}e.expanded=!0,e.children||(e.loading=!0,e.children=(await g.fetchFiles(v,e.path)).map(e=>({...e,expanded:!1,children:void 0,loading:!1})),e.loading=!1)}}async function I(e){e.isDir||(w.value=e.path,A.value=!0,k.value=null,k.value=await g.fetchFileContent(v,e.path),A.value=!1,M.value=!1)}function Q(e){return e<1024?e+` B`:e<1024*1024?(e/1024).toFixed(1)+` KB`:(e/(1024*1024)).toFixed(1)+` MB`}function oe(e){return e?e.split(`/`).map((e,t,n)=>({name:e,path:n.slice(0,t+1).join(`/`)})):[]}let $=c(()=>oe(w.value));return(t,n)=>(e(),d(`div`,R,[l(`div`,z,[l(`button`,{onClick:n[0]||=e=>_(o).push(`/projects/${_(v)}`),class:`p-2 dark:hover:bg-white/10 hover:bg-black/10 rounded-full transition-colors text-textMuted hover:text-textMain shrink-0`},[b(_(ee),{class:`w-5 h-5`})]),l(`div`,B,[l(`h1`,V,[y(p(S.value?.name||`项目`)+` `,1),n[2]||=l(`span`,{class:`text-textMuted font-normal`},`/ 文件浏览`,-1)])]),l(`button`,{onClick:n[1]||=e=>M.value=!M.value,class:u([`md:hidden p-2 dark:hover:bg-white/10 hover:bg-black/10 rounded-md transition-colors text-textMuted hover:text-textMain shrink-0`,M.value?`text-primary`:``]),type:`button`},[b(_(te),{class:`w-5 h-5`})],2)]),l(`div`,H,[l(`aside`,{class:u([`w-full md:w-64 md:border-r border-b md:border-b-0 border-border overflow-auto bg-base/50 shrink-0 max-h-64 md:max-h-full`,M.value?`block`:`hidden md:block`])},[j.value?(e(),d(`div`,U,[b(_(E),{class:`w-5 h-5 animate-spin mr-2`}),n[3]||=l(`span`,{class:`text-sm`},`加载中...`,-1)])):C.value.length===0?(e(),d(`div`,W,` 暂无文件 `)):(e(),d(`div`,G,[(e(!0),d(s,null,r(C.value,t=>(e(),h(L,{key:t.path,node:t,depth:0,"selected-file":w.value,onToggle:F,onSelect:I},null,8,[`node`,`selected-file`]))),128))]))],2),l(`div`,K,[w.value?(e(),d(`div`,q,[b(_(T),{class:`w-3.5 h-3.5 text-textMuted mr-1 shrink-0`}),(e(!0),d(s,null,r($.value,(t,n)=>(e(),d(`span`,{key:t.path,class:`flex items-center shrink-0`},[b(_(x),{class:`w-3 h-3 text-textMuted mx-1`}),l(`span`,{class:u(n===$.value.length-1?`text-textMain font-medium`:`text-textMuted`)},p(t.name),3)]))),128))])):f(``,!0),l(`div`,J,[w.value?A.value?(e(),d(`div`,Z,[b(_(E),{class:`w-6 h-6 animate-spin`})])):k.value?.type===`binary`?(e(),d(`div`,ne,[l(`div`,re,[b(_(N),{class:`w-12 h-12 mx-auto mb-3 opacity-30`}),n[5]||=l(`p`,{class:`text-sm`},`二进制文件,无法预览`,-1),k.value.size?(e(),d(`p`,ie,`大小: `+p(Q(k.value.size)),1)):f(``,!0)])])):k.value?.type===`text`?(e(),d(`pre`,ae,[l(`code`,null,p(k.value.content),1)])):f(``,!0):(e(),d(`div`,Y,[l(`div`,X,[b(_(N),{class:`w-12 h-12 mx-auto mb-3 opacity-30`}),n[4]||=l(`p`,{class:`text-sm`},`选择左侧文件查看内容`,-1)])]))])])])]))}});export{Q as default};
@@ -0,0 +1 @@
1
+ .fade-enter-active[data-v-ab5c267d],.fade-leave-active[data-v-ab5c267d]{transition:opacity .15s}.fade-enter-from[data-v-ab5c267d],.fade-leave-to[data-v-ab5c267d]{opacity:0}
@@ -0,0 +1 @@
1
+ import{A as e,B as t,F as n,M as r,U as i,V as ee,b as a,c as o,d as s,f as c,ft as l,h as u,m as d,mt as f,n as te,p,q as m,t as h,v as g,y as _,z as ne}from"./createLucideIcon-BmsTm7z-.js";import{n as re}from"./pencil-BTFuj0gA.js";import{n as v,t as ie}from"./file-text-BxWt6is5.js";import{t as ae}from"./eye-off-BNUfzp8P.js";import{t as oe}from"./eye-vRDqRzR9.js";import{t as se}from"./folder-open-DQz0XviI.js";import{t as ce}from"./folder-CYPJgLMr.js";import{t as le}from"./house-D9JIOKIs.js";import{t as ue}from"./refresh-cw-OqaxwQhF.js";import{d as de,g as fe,i as pe,n as me,r as y,t as b,v as x,y as S}from"./index-BZU6i5nw.js";var he=h(`arrow-up`,[[`path`,{d:`m5 12 7-7 7 7`,key:`hav0vg`}],[`path`,{d:`M12 19V5`,key:`x0mq9r`}]]),ge={class:`flex items-center justify-between px-5 py-4 border-b border-border`},_e={class:`flex items-center space-x-2`},ve={class:`text-base font-semibold text-textMain`},ye={key:0,class:`text-xs text-textMuted ml-2`},be={class:`px-5 py-3 border-b border-border space-y-2`},xe={class:`flex items-center space-x-2`},Se=[`disabled`],Ce=[`disabled`],we=[`onKeydown`],C=[`disabled`],w={class:`flex items-center flex-wrap text-xs text-textMuted`},T=[`onClick`],E={class:`flex-1 overflow-auto px-2 py-2 min-h-[280px]`},D={key:0,class:`flex items-center justify-center h-full text-textMuted text-sm`},O={key:1,class:`flex items-start justify-center h-full`},k={class:`flex items-start space-x-2 text-danger text-sm max-w-md p-4`},Te={class:`break-all`},Ee={key:2,class:`flex items-center justify-center h-full text-textMuted text-sm`},De={key:3,class:`space-y-0.5`},Oe=[`onDblclick`],ke=[`type`,`checked`,`disabled`,`onClick`],Ae=[`onClick`],je={key:0,class:`text-[10px] text-textMuted mr-2`},Me={key:4,class:`text-xs text-yellow-400 text-center mt-2`},Ne={key:0,class:`px-5 py-2 border-t border-border max-h-28 overflow-auto`},Pe={class:`flex flex-wrap gap-1.5`},Fe=[`title`],Ie=[`onClick`],Le={class:`flex items-center justify-between px-5 py-3 border-t border-border`},Re={class:`flex items-center space-x-3 text-xs text-textMuted`},ze=[`disabled`],Be={class:`flex items-center space-x-2`},Ve=[`disabled`],A=`kite:folderPicker:lastDir`,j=b(a({__name:`FolderPickerDialog`,props:{open:{type:Boolean},mode:{default:`multi`},title:{default:`选择文件夹`},pickKind:{default:`dir`}},emits:[`update:open`,`confirm`],setup(a,{emit:h}){let b=a,j=h,M=te(),He=me();function Ue(){try{return localStorage.getItem(A)||``}catch{return``}}function We(e){if(e)try{localStorage.setItem(A,e)}catch{}}let N=i(!1),P=i(``),F=i(!1),I=i(``),L=i(null),R=i([]),z=i(`/`),B=i(``),Ge=i([`/`]),V=i(!1),H=i(``),U=i([]),W=s(()=>V.value?R.value:R.value.filter(e=>!e.isHidden)),G=s(()=>{if(!I.value)return[];let e=z.value===`\\`,t=[];if(e){let e=I.value.split(/\\+/).filter(Boolean),n=``;e.forEach((e,r)=>{r===0?(n=e.endsWith(`:`)?`${e}\\`:e,t.push({label:n,path:n})):(n=n.endsWith(`\\`)?`${n}${e}`:`${n}\\${e}`,t.push({label:e,path:n}))})}else{let e=I.value.split(`/`).filter(Boolean);t.push({label:`/`,path:`/`});let n=``;e.forEach(e=>{n=`${n}/${e}`,t.push({label:e,path:n})})}return t});function K(e){return U.value.includes(e)}function q(e){return b.pickKind===`file`?!!e.isFile:e.isDir}function J(e){if(b.mode===`single`){U.value=K(e)?[]:[e];return}let t=U.value.indexOf(e);t>=0?U.value.splice(t,1):U.value.push(e)}function Ke(e){let t=U.value.indexOf(e);t>=0&&U.value.splice(t,1)}async function Y(e){N.value=!0,P.value=``;try{let t=b.pickKind===`file`?`both`:`dirs`,n=await M.fetchFsList(e,t);return I.value=n.path,L.value=n.parent,R.value=n.entries,F.value=n.truncated,H.value=n.path,We(n.path),!0}catch(e){return P.value=e?.message||`读取目录失败`,R.value=[],F.value=!1,!1}finally{N.value=!1}}async function qe(){N.value=!0,P.value=``;try{let e=await M.fetchFsHome();B.value=e.home,z.value=e.sep,Ge.value=e.roots||[`/`];let t=e.home||e.cwd||e.roots&&e.roots[0]||`/`,n=Ue();if(n&&n!==t){if(await Y(n))return;P.value=``}await Y(t)}catch(e){P.value=e?.message||`初始化目录浏览器失败`}finally{N.value=!1}}function X(){L.value&&Y(L.value)}function Je(){B.value&&Y(B.value)}function Z(){let e=H.value.trim();e&&Y(e)}function Q(e){e.isDir&&Y(e.path)}function Ye(){I.value&&(K(I.value)||J(I.value))}function $(){j(`update:open`,!1)}function Xe(){if(U.value.length===0){He.error(b.pickKind===`file`?`请至少选择一个文件`:`请至少选择一个目录`);return}j(`confirm`,[...U.value]),j(`update:open`,!1)}return ne(()=>b.open,e=>{e&&(U.value=[],P.value=``,qe())}),(i,s)=>(e(),p(de,{name:`fade`},{default:t(()=>[a.open?(e(),u(`div`,{key:0,class:`fixed inset-0 z-[60] flex items-center justify-center bg-black/60 backdrop-blur-sm`,onClick:S($,[`self`])},[c(`div`,{class:`bg-panel border border-border rounded-xl w-full max-w-3xl shadow-2xl flex flex-col`,style:{"max-height":`80vh`},onKeydown:x($,[`esc`])},[c(`div`,ge,[c(`div`,_e,[_(m(se),{class:`w-5 h-5 text-primary`}),c(`h3`,ve,f(a.title),1),a.mode===`multi`?(e(),u(`span`,ye,`支持多选`)):d(``,!0)]),c(`button`,{onClick:$,class:`text-textMuted hover:text-textMain rounded p-1`},[_(m(y),{class:`w-4 h-4`})])]),c(`div`,be,[c(`div`,xe,[c(`button`,{onClick:X,disabled:!L.value||N.value,class:`p-2 rounded-md border border-border text-textMuted hover:text-textMain disabled:opacity-40 disabled:cursor-not-allowed`,title:`上一级`},[_(m(he),{class:`w-4 h-4`})],8,Se),c(`button`,{onClick:Je,disabled:!B.value||N.value,class:`p-2 rounded-md border border-border text-textMuted hover:text-textMain disabled:opacity-40 disabled:cursor-not-allowed`,title:`回到 HOME`},[_(m(le),{class:`w-4 h-4`})],8,Ce),ee(c(`input`,{"onUpdate:modelValue":s[0]||=e=>H.value=e,type:`text`,spellcheck:`false`,class:`flex-1 bg-base border border-border rounded-md px-3 py-1.5 text-textMain font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50`,placeholder:`粘贴绝对路径并回车跳转`,onKeydown:x(S(Z,[`prevent`]),[`enter`])},null,40,we),[[fe,H.value]]),c(`button`,{onClick:Z,disabled:N.value,class:`px-3 py-1.5 text-sm border border-border rounded-md text-textMuted hover:text-textMain disabled:opacity-40`},`跳转`,8,C)]),c(`div`,w,[(e(!0),u(o,null,r(G.value,(t,n)=>(e(),u(o,{key:t.path},[c(`button`,{onClick:e=>Y(t.path),class:`px-1.5 py-0.5 rounded hover:bg-white/5 hover:text-textMain font-mono`},f(t.label),9,T),n<G.value.length-1?(e(),p(m(v),{key:0,class:`w-3 h-3 mx-0.5 opacity-60`})):d(``,!0)],64))),128))])]),c(`div`,E,[N.value?(e(),u(`div`,D,[_(m(ue),{class:`w-4 h-4 mr-2 animate-spin`}),s[2]||=g(` 加载中… `,-1)])):P.value?(e(),u(`div`,O,[c(`div`,k,[_(m(pe),{class:`w-4 h-4 mt-0.5 flex-shrink-0`}),c(`span`,Te,f(P.value),1)])])):W.value.length===0?(e(),u(`div`,Ee,` 空目录 `)):(e(),u(`ul`,De,[(e(!0),u(o,null,r(W.value,t=>(e(),u(`li`,{key:t.path,class:l([`group flex items-center px-3 py-2 rounded-md hover:bg-white/5 cursor-pointer`,{"opacity-60":t.isHidden}]),onDblclick:e=>Q(t)},[c(`input`,{type:a.mode===`single`?`radio`:`checkbox`,checked:K(t.path),disabled:!q(t),onClick:S(e=>q(t)&&J(t.path),[`stop`]),class:`mr-3 accent-primary disabled:opacity-30`},null,8,ke),(e(),p(n(t.isDir?m(ce):m(ie)),{class:l([`w-4 h-4 mr-2 flex-shrink-0`,t.isDir?`text-primary/80`:`text-textMuted`])},null,8,[`class`])),c(`span`,{class:`flex-1 text-sm text-textMain truncate font-mono`,onClick:e=>Q(t)},f(t.name),9,Ae),t.isSymlink?(e(),u(`span`,je,`link`)):d(``,!0),t.isDir?(e(),p(m(v),{key:1,class:`w-4 h-4 text-textMuted opacity-0 group-hover:opacity-100`,onClick:S(e=>Q(t),[`stop`])},null,8,[`onClick`])):d(``,!0)],42,Oe))),128))])),F.value?(e(),u(`p`,Me,` 目录条目过多,已截断展示前 500 项,请通过路径输入精确跳转。 `)):d(``,!0)]),U.value.length>0?(e(),u(`div`,Ne,[c(`div`,Pe,[(e(!0),u(o,null,r(U.value,t=>(e(),u(`span`,{key:t,class:`inline-flex items-center max-w-full bg-primary/10 border border-primary/30 text-primary text-xs font-mono rounded px-2 py-1`},[c(`span`,{class:`truncate`,title:t},f(t),9,Fe),c(`button`,{onClick:e=>Ke(t),class:`ml-1.5 hover:text-textMain`},[_(m(y),{class:`w-3 h-3`})],8,Ie)]))),128))])])):d(``,!0),c(`div`,Le,[c(`div`,Re,[c(`button`,{onClick:s[1]||=e=>V.value=!V.value,class:`flex items-center hover:text-textMain`},[(e(),p(n(V.value?m(oe):m(ae)),{class:`w-3.5 h-3.5 mr-1`})),g(` `+f(V.value?`隐藏点开头目录`:`显示点开头目录`),1)]),a.pickKind===`dir`?(e(),u(`button`,{key:0,onClick:Ye,disabled:!I.value||N.value,class:`flex items-center hover:text-textMain disabled:opacity-40 disabled:cursor-not-allowed`,title:`把当前所在目录加入选中`},[_(m(re),{class:`w-3.5 h-3.5 mr-1`}),s[3]||=g(` 选中当前目录 `,-1)],8,ze)):d(``,!0),c(`span`,null,`已选 `+f(U.value.length)+` 项`,1)]),c(`div`,Be,[c(`button`,{onClick:$,class:`px-4 py-2 text-sm font-medium text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5 rounded-md transition-colors`},`取消`),c(`button`,{onClick:Xe,disabled:U.value.length===0,class:`px-4 py-2 text-sm font-medium bg-primary text-white rounded-md hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`},`确认(`+f(U.value.length)+`)`,9,Ve)])])],32)])):d(``,!0)]),_:1}))}}),[[`__scopeId`,`data-v-ab5c267d`]]);export{j as t};
@@ -0,0 +1,6 @@
1
+ import{A as e,D as t,E as n,M as r,O as i,T as a,U as o,V as s,b as c,c as l,d as u,f as d,ft as ee,h as f,m as p,mt as m,n as te,p as h,q as g,t as _,v,y,z as b}from"./createLucideIcon-BmsTm7z-.js";import{n as x,r as ne,t as re}from"./rotate-ccw-D8C0iiAw.js";import{t as ie}from"./archive-MB1JcYug.js";import{t as S}from"./circle-alert-kmcvMchB.js";import{t as ae}from"./clock-DIBzfDoY.js";import{t as C}from"./copy-CNXWZJbC.js";import{t as w}from"./refresh-cw-OqaxwQhF.js";import{t as oe}from"./terminal-CUz5b_ol.js";import{g as se,h as ce,l as le,n as ue,o as de,s as fe,t as pe,u as me,y as he}from"./index-BZU6i5nw.js";import{t as T}from"./ConfirmDialog-CikXU818.js";var E=_(`wrench`,[[`path`,{d:`M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z`,key:`1ngwbx`}]]),D={30:`#1e1e1e`,31:`#e06c75`,32:`#98c379`,33:`#e5c07b`,34:`#61afef`,35:`#c678dd`,36:`#56b6c2`,37:`#abb2bf`,90:`#5c6370`,91:`#e06c75`,92:`#98c379`,93:`#e5c07b`,94:`#61afef`,95:`#c678dd`,96:`#56b6c2`,97:`#ffffff`},O={40:`#1e1e1e`,41:`#e06c75`,42:`#98c379`,43:`#e5c07b`,44:`#61afef`,45:`#c678dd`,46:`#56b6c2`,47:`#abb2bf`},k=/\x1b\[([0-9;]*)m/g;function ge(e){let t=``,n=0,r=0;e=e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`);let i;for(k.lastIndex=0;(i=k.exec(e))!==null;){t+=e.slice(r,i.index),r=i.index+i[0].length;let a=i[1].split(`;`).map(Number);if(a.length===0||a.length===1&&a[0]===0){for(;n>0;)t+=`</span>`,n--;continue}for(let e of a)if(e===0)for(;n>0;)t+=`</span>`,n--;else e===1?(t+=`<span style="font-weight:bold">`,n++):e===2?(t+=`<span style="opacity:0.7">`,n++):e===3?(t+=`<span style="font-style:italic">`,n++):e===4?(t+=`<span style="text-decoration:underline">`,n++):D[e]?(t+=`<span style="color:${D[e]}">`,n++):O[e]&&(t+=`<span style="background-color:${O[e]}">`,n++)}for(t+=e.slice(r);n>0;)t+=`</span>`,n--;return t}function _e(e,t){let n=o([]),r=o(``),a=null,s=!1;async function c(e){l(),n.value=[],r.value=``,s=!1,a=new AbortController;try{let i=await fetch(`/api/logs/${e}/stream`,{headers:{Authorization:`Bearer ${t.value}`},signal:a.signal});if(!i.ok||!i.body)return;let o=i.body.getReader(),c=new TextDecoder,u=``;for(;;){let{done:e,value:t}=await o.read();if(e)break;u+=c.decode(t,{stream:!0});let i=u.split(`
2
+
3
+ `);u=i.pop();for(let e of i){if(!e.trim())continue;let t=`message`,i=``;for(let n of e.split(`
4
+ `))n.startsWith(`event: `)?t=n.slice(7):n.startsWith(`data: `)&&(i=n.slice(6));if(t===`log`){let e=JSON.parse(i);s?n.value.push(e):(n.value=e.split(`
5
+ `),s=!0)}else if(t===`status`){r.value=JSON.parse(i).status,l();return}}}}catch(e){e.name!==`AbortError`&&console.error(`SSE connection error:`,e)}}function l(){a&&=(a.abort(),null)}return b(e,e=>{e?c(e):l()}),i(l),{lines:n,status:r,disconnect:l}}var ve={class:`h-full flex flex-col space-y-6 max-w-7xl mx-auto`},ye={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center gap-3 shrink-0`},be={class:`flex-1 flex flex-col lg:flex-row gap-6 min-h-0`},xe={class:`w-full lg:w-1/3 bg-panel border border-border rounded-xl shadow-sm overflow-hidden flex flex-col h-[400px] lg:h-auto`},Se={class:`p-4 border-b border-border bg-base/50 shrink-0 space-y-2`},Ce=[`value`],we={key:0,class:`flex items-center justify-between text-xs text-textMuted`},Te={class:`flex-1 overflow-y-auto p-2 space-y-1`},Ee=[`onClick`],De={class:`mt-0.5`},Oe={class:`flex-1 min-w-0`},ke={class:`flex justify-between items-center mb-1 gap-2`},Ae={class:`font-medium text-textMain text-sm truncate`},je={class:`text-xs text-textMuted font-mono shrink-0 truncate`},Me={class:`flex items-center text-xs text-textMuted gap-1.5 flex-wrap`},Ne=[`title`,`onClick`],Pe={key:0,class:`inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-success/10 border border-success/30 text-success`,title:`该版本为当前线上版本`},Fe={class:`flex items-center`},Ie={class:`flex items-center`},Le={key:1,class:`ml-auto text-[10px] font-mono px-1 py-0 rounded bg-yellow-400/10 border border-yellow-400/30 text-yellow-400`},Re={key:0,class:`flex flex-col items-center justify-center py-10 text-textMuted text-sm`},ze={class:`flex-1 bg-[#09090b] border border-border rounded-xl shadow-sm flex flex-col overflow-hidden h-[500px] lg:h-auto font-mono text-sm`},Be={class:`h-10 bg-panel border-b border-border flex items-center px-4 shrink-0 gap-2`},Ve={class:`flex-1 text-center text-textMuted text-xs font-sans truncate flex items-center justify-center gap-1.5`},He=[`title`],Ue={key:0,class:`flex items-center gap-1.5`},We={key:0,class:`text-[10px] font-medium px-1.5 py-0.5 rounded bg-success/10 border border-success/30 text-success`,title:`该版本为当前线上版本`},Ge=[`title`],Ke=[`title`],qe=[`title`],Je=[`title`],Ye=[`title`],Xe={class:`flex-1 p-4 overflow-y-auto bg-[#09090b] text-[#f4f4f5] leading-relaxed selection:bg-primary/30`},Ze={key:0,class:`space-y-1 whitespace-pre-wrap break-all`},Qe={class:`w-8 text-right mr-4 text-textMuted/30 select-none group-hover:text-textMuted/50 transition-colors`},$e=[`innerHTML`],et={key:0,class:`flex px-2 -mx-2 mt-2`},tt={class:`w-8 text-right mr-4 text-textMuted/30 select-none`},nt={key:1,class:`h-full flex flex-col items-center justify-center text-textMuted font-sans`},rt=10,A=pe(c({__name:`LogBoard`,setup(i){let c=te(),_=le(),pe=me(),D=ue(),O=o(``),k=o(``),A=u(()=>{let e=c.projects.map(e=>({id:e.id,name:e.name})),t=new Set(e.map(e=>e.id));for(let n of c.logs)t.has(n.projectId)||(t.add(n.projectId),e.push({id:n.projectId,name:n.projectName}));return e}),j=u(()=>{let e=O.value.trim().toLowerCase();return c.logs.filter(t=>k.value&&t.projectId!==k.value?!1:e?t.projectName.toLowerCase().includes(e)||t.id.toLowerCase().includes(e):!0)}),M=o(null),N=u(()=>M.value?.status===`running`),P=o(Date.now()),F=null,I=o(rt),it=u(()=>I.value*60*1e3),L=o({}),at=e=>t=>{L.value[e]=t};async function R(e){if(!e)return;let t=c.logs.find(t=>t.id===e);if(!t)return;M.value=t,await a();let n=L.value[e];n&&typeof n.scrollIntoView==`function`&&n.scrollIntoView({block:`nearest`})}t(async()=>{c.projects.length===0&&c.fetchProjects(),await c.fetchLogs(),c.fetchSettings().then(e=>{let t=e?.deployment_stuck_threshold_min,n=t==null?NaN:Number(t);Number.isFinite(n)&&Number.isInteger(n)&&n>=1&&n<=1440&&(I.value=n)}).catch(()=>{});let e=typeof _.query.projectId==`string`?_.query.projectId:``;e&&(k.value=e),await R(typeof _.query.id==`string`?_.query.id:null),P.value=Date.now(),F=window.setInterval(()=>{P.value=Date.now()},3e4)}),n(()=>{F!==null&&(clearInterval(F),F=null)}),b(()=>_.query.id,async e=>{typeof e==`string`&&await R(e)}),b(()=>_.query.projectId,e=>{k.value=typeof e==`string`?e:``}),b(k,e=>{if(e===(typeof _.query.projectId==`string`?_.query.projectId:``))return;let t={..._.query};e?t.projectId=e:delete t.projectId,pe.replace({query:t}),M.value&&e&&M.value.projectId!==e&&(M.value=null)});let{lines:z,status:ot}=_e(u(()=>N.value?M.value?.id:null),u(()=>c.adminToken));b(ot,e=>{e&&c.fetchLogs().then(()=>{if(M.value){let e=c.logs.find(e=>e.id===M.value.id);e&&(M.value=e)}})});let B=u(()=>N.value&&z.value.length>0?z.value:M.value?.output?.split(`
6
+ `)||[]),st=e=>{M.value=e},ct=async()=>{await c.fetchLogs(),M.value&&=j.value.find(e=>e.id===M.value.id)||null};function lt(e){return ge(e)}let V=u(()=>{let e=M.value;return!e||e.status===`running`||e.triggerSource===`rollback`?!1:!!e.artifactPath}),H=u(()=>{let e=M.value;return e?e.status===`running`?`部署进行中,无法回滚`:e.triggerSource===`rollback`?`回滚记录不可再被回滚`:e.artifactPath?``:`该版本归档已被清理或过早,无法回滚`:``}),U=o(!1),W=o(!1);function G(e){return e?e.slice(0,8):``}let K=o(``);async function q(e,t){if(t&&(t.stopPropagation(),t.preventDefault()),e)try{await navigator.clipboard.writeText(e),K.value=e,D.success(`已复制部署 ID`,G(e)),setTimeout(()=>{K.value===e&&(K.value=``)},2e3)}catch(e){D.error(`复制失败`,e?.message||`请手动选择文本复制`)}}let ut=u(()=>{let e={},t=[...c.logs].sort((e,t)=>{let n=new Date(e.startTime).getTime()||0;return(new Date(t.startTime).getTime()||0)-n});for(let n of t)n.status===`success`&&n.triggerSource!==`rollback`&&(e[n.projectId]||(e[n.projectId]=n.id));return e});function J(e){return ut.value[e.projectId]===e.id}function dt(){V.value&&(U.value=!0)}async function ft(){let e=M.value?.id;if(e){W.value=!0;try{let t=await c.rollbackDeployment(e);D.success(`回滚已完成`,`新部署 ${G(t.deployId)}`),U.value=!1,await c.fetchLogs();let n=c.logs.find(e=>e.id===t.deployId);if(n){M.value=n,await a();let e=L.value[n.id];e&&typeof e.scrollIntoView==`function`&&e.scrollIntoView({block:`nearest`})}}catch(e){D.error(`回滚失败`,e?.message||`未知错误`)}finally{W.value=!1}}}let Y=u(()=>{let e=M.value;if(!e||e.status!==`running`)return 0;let t=new Date(e.startTime).getTime();return Number.isFinite(t)?Math.max(0,P.value-t):0}),pt=u(()=>Y.value>=it.value),X=u(()=>{let e=Y.value;if(e<=0)return``;let t=Math.floor(e/6e4);if(t<60)return`${t} 分钟`;let n=Math.floor(t/60),r=t%60;return r===0?`${n} 小时`:`${n} 小时 ${r} 分钟`}),Z=o(!1),Q=o(`failed`),$=o(!1),mt=u(()=>Q.value===`failed`?`danger`:`warning`),ht=u(()=>Q.value===`failed`?`确认将此部署标记为失败?`:`确认将此部署标记为成功?`),gt=u(()=>{let e=M.value,t=e?G(e.id):``,n=e?.projectName||``,r=X.value?`(已持续 ${X.value})`:``;return Q.value===`failed`?`部署 ${t}(${n})当前显示为进行中${r}。此操作只会修正数据库记录与项目状态,不会回滚或清理已落盘的文件,仅适用于服务进程已退出 / 卡死的场景。`:`部署 ${t}(${n})当前显示为进行中${r}。标记为成功仅会修正数据库状态,**不代表部署真的执行成功**,请确认你已通过其他方式验证产物可用。`});function _t(e){pt.value&&(Q.value=e,Z.value=!0)}async function vt(){let e=M.value;if(e){$.value=!0;try{let t=await c.markDeploymentStatus(e.id,Q.value);D.success(Q.value===`failed`?`已标记为失败`:`已标记为成功`,`部署 ${G(e.id)}`),Z.value=!1,await c.fetchLogs();let n=c.logs.find(t=>t.id===e.id);n?M.value=n:t?.deployment&&(M.value=t.deployment)}catch(e){let t=e?.data?.code===`NOT_RUNNING`?`该部署已不是进行中状态,无需修正`:e?.message||`未知错误`;D.error(`标记失败`,t)}finally{$.value=!1}}}return(t,n)=>(e(),f(`div`,ve,[d(`div`,ye,[n[9]||=d(`div`,null,[d(`h1`,{class:`text-2xl font-bold text-textMain tracking-tight`},`部署日志`),d(`p`,{class:`text-textMuted text-sm mt-1`},`实时查看所有项目的自动化部署过程及终端输出`)],-1),d(`button`,{onClick:ct,class:`flex items-center px-4 py-2 bg-panel dark:hover:bg-white/5 hover:bg-black/5 border border-border text-textMain rounded-md transition-colors text-sm font-medium shadow-sm self-start sm:self-auto`},[y(g(w),{class:`w-4 h-4 mr-2`}),n[8]||=v(` 刷新 `,-1)])]),d(`div`,be,[d(`div`,xe,[d(`div`,Se,[s(d(`select`,{"onUpdate:modelValue":n[0]||=e=>k.value=e,class:`w-full bg-base border border-border rounded-md px-3 py-2 text-sm text-textMain focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all`},[n[10]||=d(`option`,{value:``},`全部项目`,-1),(e(!0),f(l,null,r(A.value,t=>(e(),f(`option`,{key:t.id,value:t.id},m(t.name),9,Ce))),128))],512),[[ce,k.value]]),s(d(`input`,{"onUpdate:modelValue":n[1]||=e=>O.value=e,type:`text`,placeholder:`搜索项目或记录 ID...`,class:`w-full bg-base border border-border rounded-md px-3 py-2 text-sm text-textMain focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all`},null,512),[[se,O.value]]),k.value||O.value?(e(),f(`div`,we,[d(`span`,null,`已过滤 `+m(j.value.length)+` 条记录`,1),d(`button`,{onClick:n[2]||=e=>{k.value=``,O.value=``},class:`text-primary hover:underline`},`清除过滤`)])):p(``,!0)]),d(`div`,Te,[(e(!0),f(l,null,r(j.value,t=>(e(),f(`div`,{key:t.id,ref_for:!0,ref:at(t.id),onClick:e=>st(t),class:ee([`p-3 rounded-lg cursor-pointer transition-all border border-transparent flex items-start space-x-3`,M.value?.id===t.id?`bg-primary/10 border-primary/20 shadow-[inset_2px_0_0_0_#3b82f6]`:`dark:hover:bg-white/5 hover:bg-black/5`])},[d(`div`,De,[t.status===`success`?(e(),h(g(fe),{key:0,class:`w-5 h-5 text-success`})):t.status===`failed`?(e(),h(g(de),{key:1,class:`w-5 h-5 text-danger`})):(e(),h(g(w),{key:2,class:`w-5 h-5 text-primary animate-spin`}))]),d(`div`,Oe,[d(`div`,ke,[d(`span`,Ae,m(t.projectName),1),d(`span`,je,m(new Date(t.startTime).toLocaleString()),1)]),d(`div`,Me,[d(`span`,{class:`inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-base border border-border font-mono text-[10px] text-textMuted hover:text-primary hover:border-primary/40 transition-colors cursor-pointer`,title:`点击复制完整 ID: ${t.id}`,onClick:he(e=>q(t.id,e),[`stop`])},[K.value===t.id?(e(),h(g(x),{key:0,class:`w-3 h-3 text-success`})):(e(),h(g(C),{key:1,class:`w-3 h-3`})),v(` `+m(G(t.id)),1)],8,Ne),J(t)?(e(),f(`span`,Pe,`当前`)):p(``,!0),d(`span`,Fe,[y(g(oe),{class:`w-3 h-3 mr-1`}),v(` `+m(t.triggerSource),1)]),d(`span`,Ie,[y(g(ae),{class:`w-3 h-3 mr-1`}),v(` `+m(t.duration),1)]),t.triggerSource===`rollback`?(e(),f(`span`,Le,`RB`)):p(``,!0)])])],10,Ee))),128)),j.value.length===0?(e(),f(`div`,Re,[y(g(S),{class:`w-8 h-8 mb-2 opacity-50`}),n[11]||=d(`p`,null,`暂无匹配的部署记录`,-1)])):p(``,!0)])]),d(`div`,ze,[d(`div`,Be,[n[15]||=d(`div`,{class:`flex space-x-2 mr-2`},[d(`div`,{class:`w-3 h-3 rounded-full bg-danger/80`}),d(`div`,{class:`w-3 h-3 rounded-full bg-yellow-500/80`}),d(`div`,{class:`w-3 h-3 rounded-full bg-success/80`})],-1),d(`div`,Ve,[M.value?(e(),f(l,{key:0},[d(`span`,null,`bash - `+m(M.value.projectName),1),d(`button`,{type:`button`,class:`inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-base border border-border font-mono text-[10px] text-textMuted hover:text-primary hover:border-primary/40 transition-colors`,title:`点击复制完整 ID: ${M.value.id}`,onClick:n[3]||=e=>q(M.value.id,e)},[K.value===M.value.id?(e(),h(g(x),{key:0,class:`w-3 h-3 text-success`})):(e(),h(g(C),{key:1,class:`w-3 h-3`})),v(` `+m(G(M.value.id)),1)],8,He)],64)):(e(),f(l,{key:1},[v(`等待选择...`)],64))]),M.value?(e(),f(`div`,Ue,[J(M.value)?(e(),f(`span`,We,`当前版本`)):p(``,!0),M.value.triggerSource===`rollback`?(e(),f(`span`,{key:1,class:`text-[10px] font-mono px-1.5 py-0.5 rounded bg-yellow-400/10 border border-yellow-400/30 text-yellow-400`,title:`rollbackOf=${M.value.rollbackOf||``}`},`rollback`,8,Ge)):p(``,!0),M.value.artifactPath?(e(),h(g(ie),{key:2,class:`w-3.5 h-3.5 text-success/70`,title:`已归档,可回滚`})):(e(),h(g(ne),{key:3,class:`w-3.5 h-3.5 text-textMuted/50`,title:`无归档`})),N.value&&pt.value?(e(),f(l,{key:4},[d(`button`,{onClick:n[4]||=e=>_t(`failed`),class:`flex items-center px-2.5 py-1 text-[11px] font-medium bg-danger/10 border border-danger/30 text-danger hover:bg-danger hover:text-white rounded transition-colors`,type:`button`,title:`部署已持续 ${X.value},将状态修正为 failed`},[y(g(E),{class:`w-3 h-3 mr-1`}),n[12]||=v(` 标记为失败 `,-1)],8,Ke),d(`button`,{onClick:n[5]||=e=>_t(`success`),class:`flex items-center px-2.5 py-1 text-[11px] font-medium bg-success/10 border border-success/30 text-success hover:bg-success hover:text-white rounded transition-colors`,type:`button`,title:`部署已持续 ${X.value},将状态修正为 success(仅状态修正,不验证产物)`},[y(g(E),{class:`w-3 h-3 mr-1`}),n[13]||=v(` 标记为成功 `,-1)],8,qe)],64)):N.value?(e(),f(`span`,{key:5,class:`text-[10px] text-textMuted/70 italic`,title:`部署进行中不足 ${I.value} 分钟,暂不允许手动修正状态`},`进行中…`,8,Je)):p(``,!0),V.value?(e(),f(`button`,{key:6,onClick:dt,class:`flex items-center px-2.5 py-1 text-[11px] font-medium bg-yellow-400/10 border border-yellow-400/30 text-yellow-400 hover:bg-yellow-400 hover:text-black rounded transition-colors`,type:`button`},[y(g(re),{class:`w-3 h-3 mr-1`}),n[14]||=v(` 回滚到此版本 `,-1)])):H.value?(e(),f(`span`,{key:7,class:`text-[10px] text-textMuted/70 italic`,title:H.value},`不可回滚`,8,Ye)):p(``,!0)])):p(``,!0)]),d(`div`,Xe,[M.value?(e(),f(`div`,Ze,[(e(!0),f(l,null,r(B.value,(t,n)=>(e(),f(`div`,{key:n,class:`flex dark:hover:bg-white/5 hover:bg-black/5 px-2 -mx-2 rounded transition-colors group`},[d(`span`,Qe,m(Number(n)+1),1),d(`span`,{innerHTML:lt(t)},null,8,$e)]))),128)),M.value.status===`running`?(e(),f(`div`,et,[d(`span`,tt,m(B.value.length+1),1),n[16]||=d(`span`,{class:`w-2 h-4 bg-textMain animate-pulse inline-block align-middle`},null,-1)])):p(``,!0)])):(e(),f(`div`,nt,[y(g(S),{class:`w-12 h-12 mb-4 opacity-50`}),n[17]||=d(`p`,null,`请选择左侧部署记录以查看详细终端输出`,-1)]))])])]),y(T,{open:U.value,"onUpdate:open":n[6]||=e=>U.value=e,tone:`warning`,title:`确认回滚到此版本?`,message:`将以归档 ${G(M.value?.id)} 重新部署到项目 ${M.value?.projectName}。会按当前项目的 cleanMode / protectPaths 执行清理后再解压,运行时数据按保护规则保留。`,"confirm-text":`确认回滚`,"cancel-text":`取消`,loading:W.value,onConfirm:ft},null,8,[`open`,`message`,`loading`]),y(T,{open:Z.value,"onUpdate:open":n[7]||=e=>Z.value=e,tone:mt.value,title:ht.value,message:gt.value,"confirm-text":Q.value===`failed`?`确认标记失败`:`确认标记成功`,"cancel-text":`取消`,loading:$.value,onConfirm:vt},null,8,[`open`,`tone`,`title`,`message`,`confirm-text`,`loading`])]))}}),[[`__scopeId`,`data-v-af06cb3a`]]);export{A as default};
@@ -0,0 +1 @@
1
+ .overflow-y-auto[data-v-af06cb3a]::-webkit-scrollbar{width:10px}.overflow-y-auto[data-v-af06cb3a]::-webkit-scrollbar-track{background:#09090b}.overflow-y-auto[data-v-af06cb3a]::-webkit-scrollbar-thumb{background:#27272a;border:2px solid #09090b;border-radius:5px}.overflow-y-auto[data-v-af06cb3a]::-webkit-scrollbar-thumb:hover{background:#3f3f46}
@@ -0,0 +1,9 @@
1
+ import{A as e,D as t,F as n,M as r,O as i,T as a,U as o,V as s,b as ee,c,d as l,f as u,ft as d,h as f,m as p,mt as m,n as te,p as h,q as g,t as _,v,y,z as ne}from"./createLucideIcon-BmsTm7z-.js";import{t as re}from"./activity-DZCOq6kQ.js";import{t as ie}from"./arrow-left-CsZYc3XK.js";import{t as ae}from"./FolderPickerDialog-CKohwBIP.js";import{t as oe}from"./pencil-BTFuj0gA.js";import{n as se,r as ce,t as le}from"./history-dkZbN_TB.js";import{t as ue}from"./file-text-BxWt6is5.js";import{t as de}from"./loader-circle-OwtRa1dp.js";import{t as fe}from"./plus-CcefsCv_.js";import{t as pe}from"./refresh-cw-OqaxwQhF.js";import{t as me}from"./trash-2-20ikd6fk.js";import{f as he,g as ge,h as _e,i as ve,l as ye,n as be,r as xe,u as Se,v as Ce,y as b}from"./index-BZU6i5nw.js";import{t as we}from"./ConfirmDialog-CikXU818.js";var Te=_(`pause`,[[`rect`,{x:`14`,y:`3`,width:`5`,height:`18`,rx:`1`,key:`kaeet6`}],[`rect`,{x:`5`,y:`3`,width:`5`,height:`18`,rx:`1`,key:`1wsw3u`}]]),Ee=_(`play`,[[`path`,{d:`M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z`,key:`10ikf1`}]]),De=_(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]),Oe=_(`zap`,[[`path`,{d:`M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z`,key:`1xq2db`}]]);function ke(e){let t=o(!1),n=null;async function r(r,i,o){a(),n=new AbortController,t.value=!0;try{let a=await fetch(`/api/log-sources/${r}/stream?tailLines=${i}`,{headers:{Authorization:`Bearer ${e()}`},signal:n.signal});if(!a.ok||!a.body){o.onError?.(`HTTP ${a.status}`),t.value=!1;return}let s=a.body.getReader(),ee=new TextDecoder,c=``;for(;;){let{done:e,value:t}=await s.read();if(e)break;c+=ee.decode(t,{stream:!0});let n=c.split(`
2
+
3
+ `);c=n.pop();for(let e of n){if(!e.trim()||e.startsWith(`:`))continue;let t=`message`,n=``;for(let r of e.split(`
4
+ `))r.startsWith(`event: `)?t=r.slice(7):r.startsWith(`data: `)&&(n+=(n?`
5
+ `:``)+r.slice(6));if(n)try{let e=JSON.parse(n);t===`snapshot`?o.onSnapshot?.(e):t===`lines`?o.onLines?.(e):t===`rotated`?o.onRotated?.(e):t===`error`&&o.onError?.(e?.message||`stream error`)}catch{}}}}catch(e){e?.name!==`AbortError`&&o.onError?.(e?.message||`connect failed`)}finally{t.value=!1}}function a(){n&&=(n.abort(),null),t.value=!1}return i(a),{connected:t,connect:r,disconnect:a}}function Ae(e){let t=o(!1),n=null;async function r(r,i,o){a(),n=new AbortController,t.value=!0;let s=new URLSearchParams;s.set(`q`,i.q),i.regex&&s.set(`regex`,`1`),i.caseInsensitive&&s.set(`caseInsensitive`,`1`),i.maxHits&&s.set(`maxHits`,String(i.maxHits)),i.context!==void 0&&s.set(`context`,String(i.context)),i.fromOffset!==void 0&&s.set(`fromOffset`,String(i.fromOffset)),i.toOffset!==void 0&&s.set(`toOffset`,String(i.toOffset));try{let i=await fetch(`/api/log-sources/${r}/search?${s.toString()}`,{headers:{Authorization:`Bearer ${e()}`},signal:n.signal});if(!i.ok||!i.body){o.onError?.(`HTTP ${i.status}`),t.value=!1;return}let a=i.body.getReader(),ee=new TextDecoder,c=``;for(;;){let{done:e,value:t}=await a.read();if(e)break;c+=ee.decode(t,{stream:!0});let n=c.split(`
6
+
7
+ `);c=n.pop();for(let e of n){if(!e.trim()||e.startsWith(`:`))continue;let t=`message`,n=``;for(let r of e.split(`
8
+ `))r.startsWith(`event: `)?t=r.slice(7):r.startsWith(`data: `)&&(n+=(n?`
9
+ `:``)+r.slice(6));if(n)try{let e=JSON.parse(n);t===`hit`?o.onHit?.(e):t===`truncated`?o.onTruncated?.(e):t===`done`?o.onDone?.(e):t===`error`&&o.onError?.(e?.message||`search error`)}catch{}}}}catch(e){e?.name!==`AbortError`&&o.onError?.(e?.message||`search failed`)}finally{t.value=!1}}function a(){n&&=(n.abort(),null),t.value=!1}return i(a),{running:t,search:r,abort:a}}var je={class:`space-y-6`},Me={class:`flex items-center justify-between`},Ne={class:`flex items-center space-x-3`},Pe={class:`text-xs text-textMuted font-mono mt-0.5`},Fe={class:`flex items-center space-x-2`},Ie=[`disabled`,`title`],Le=[`title`],Re={class:`grid grid-cols-12 gap-4`},ze={class:`col-span-12 lg:col-span-3 bg-panel border border-border rounded-lg p-3`},Be={class:`text-xs text-textMuted mb-2 px-1 flex items-center justify-between`},Ve={key:0,class:`text-xs text-textMuted py-6 text-center`},He={key:1,class:`text-xs text-textMuted py-8 text-center`},Ue={key:2,class:`space-y-1`},We={class:`flex items-start p-2`},Ge=[`onClick`],Ke=[`onKeydown`],qe={key:1},Je={class:`text-sm text-textMain font-medium truncate`},Ye=[`title`],Xe={class:`flex items-center space-x-0.5 opacity-0 group-hover:opacity-100 transition-opacity`},Ze=[`onClick`],Qe=[`onClick`],$e={class:`col-span-12 lg:col-span-9 bg-panel border border-border rounded-lg flex flex-col`,style:{"min-height":`540px`}},et={key:0,class:`flex-1 flex items-center justify-center text-textMuted text-sm`},tt={class:`flex items-center justify-between px-4 py-3 border-b border-border`},nt={class:`min-w-0 flex-1`},rt={class:`text-sm text-textMain font-medium truncate`},it=[`title`],at={class:`flex items-center space-x-1 ml-3`},ot=[`onClick`],st={key:0,class:`flex-1 flex flex-col min-h-0`},ct={class:`flex items-center justify-between px-4 py-2 border-b border-border text-xs`},lt={class:`flex items-center space-x-3 text-textMuted`},ut={class:`flex items-center space-x-1`},dt={class:`flex items-center space-x-2`},ft={key:0,class:`px-4 py-2 text-xs text-danger flex items-center bg-danger/5 border-b border-danger/20`},pt={key:0,class:`text-textMuted text-center py-12`},mt={key:1},ht={key:1,class:`flex-1 flex flex-col min-h-0`},gt={class:`flex items-center justify-between px-4 py-2 border-b border-border text-xs`},_t={class:`flex items-center space-x-2`},vt=[`disabled`],yt=[`disabled`],bt={class:`text-textMuted font-mono`},xt={key:0,class:`ml-2 text-yellow-400`},St={key:0,class:`px-4 py-2 text-xs text-danger flex items-center bg-danger/5 border-b border-danger/20`},Ct={class:`flex-1 overflow-auto bg-base p-3 font-mono text-xs leading-relaxed`,style:{"min-height":`380px`}},wt={key:0,class:`text-textMuted text-center py-12`},Tt={key:1},Et={key:0,class:`text-[10px] text-textMuted text-center py-1`},Dt={key:1,class:`text-[10px] text-textMuted text-center py-1`},Ot={key:2,class:`flex-1 flex flex-col min-h-0`},kt={class:`px-4 py-2 border-b border-border space-y-2`},At={class:`flex items-center space-x-2`},jt=[`onKeydown`],Mt={class:`flex items-center space-x-3 text-xs text-textMuted`},Nt={class:`flex items-center`},Pt={class:`flex items-center`},Ft={key:0,class:`text-primary`},It={key:1},Lt={key:2,class:`text-yellow-400`},Rt={key:0,class:`px-4 py-2 text-xs text-danger flex items-center bg-danger/5 border-b border-danger/20`},zt={class:`flex-1 overflow-auto bg-base p-3 font-mono text-xs leading-relaxed`,style:{"min-height":`380px`}},Bt={key:0,class:`text-textMuted text-center py-12`},Vt=[`title`],Ht=[`innerHTML`],Ut=64*1024,Wt=ee({__name:`LogTail`,setup(ee){let _=ye(),Wt=Se(),x=te(),S=be(),C=l(()=>String(_.params.id)),Gt=l(()=>x.projects.find(e=>e.id===C.value)),w=o([]),T=o(!1),E=o(``),Kt=l(()=>w.value.find(e=>e.id===E.value)||null),D=o(null),qt=o(!1),O=o(!1),k=l(()=>Gt.value?.pm2AppName?.trim()||``),Jt=l(()=>{let e=D.value;if(!e||e.found===!1)return[];let t=[];return e.outLogPath&&t.push({path:e.outLogPath,kind:`stdout`}),e.errorLogPath&&t.push({path:e.errorLogPath,kind:`stderr`}),t}),A=l(()=>{if(Jt.value.length===0)return[];let e=new Set(w.value.map(e=>e.filePath));return Jt.value.filter(t=>!e.has(t.path))}),Yt=l(()=>k.value&&D.value?.found===!0&&Jt.value.length>0),Xt=o(!1),Zt=o(!1),Qt=o(``),j=o(``),M=o(``),N=o(`live`),P=o(0),F=o([]),I=o(!0),$t=o(20),L=o(``),en=o(null),R=ke(()=>x.adminToken),z=o([]),B=o(0),V=o(0),H=o(0),tn=o(!1),nn=o(!1),U=o(!1),W=o(``),rn=o(!1),G=o(``),an=o(!1),on=o(!0),K=o([]),q=o(null),J=o(null),Y=o(``),X=Ae(()=>x.adminToken);async function Z(){T.value=!0;try{w.value=(await x.fetchLogSources(C.value)).items,!E.value&&w.value.length>0&&mn(w.value[0].id)}catch(e){S.error(e?.message||`加载日志源失败`)}finally{T.value=!1}}async function sn(){if(!k.value){D.value=null;return}qt.value=!0;try{D.value=await x.fetchProjectPm2(C.value)}catch{D.value=null}finally{qt.value=!1}}async function cn(){if(O.value)return;let e=A.value;if(e.length===0){S.success(`PM2 日志文件已全部导入`);return}let t=k.value||`pm2`,n=e.map(e=>({filePath:e.path,label:`${t} · ${e.kind}`,kind:`pm2`}));O.value=!0;try{let e=await x.createLogSources(C.value,n),t=Array.isArray(e?.created)?e.created:[],r=Array.isArray(e?.errors)?e.errors:[];t.length>0&&S.success(`已从 PM2 导入 ${t.length} 个日志源`),r.length>0&&S.error(`${r.length} 个未能导入`,r.map(e=>e?.error).filter(Boolean).join(`; `)||`请检查 PM2 日志路径是否可读`),await Z(),t.length>0&&mn(t[0].id)}catch(e){S.error(e?.message||`导入 PM2 日志失败`)}finally{O.value=!1}}async function ln(e){if(Xt.value=!1,e.length)try{let t=e.map(e=>({filePath:e}));await x.createLogSources(C.value,t),S.success(`已添加 ${e.length} 个日志文件`),await Z()}catch(e){S.error(e?.message||`添加日志失败`)}}function un(e){Qt.value=e,Zt.value=!0}async function dn(){let e=Qt.value;if(Qt.value=``,Zt.value=!1,e)try{await x.deleteLogSource(e),E.value===e&&(R.disconnect(),X.abort(),E.value=``,F.value=[],z.value=[],K.value=[]),await Z(),S.success(`已删除`)}catch(e){S.error(e?.message||`删除失败`)}}function fn(e){j.value=e.id,M.value=e.label}async function pn(){let e=j.value,t=M.value.trim();if(j.value=``,M.value=``,!(!e||!t))try{await x.updateLogSource(e,{label:t}),await Z()}catch(e){S.error(e?.message||`重命名失败`)}}function mn(e){E.value!==e&&(R.disconnect(),X.abort(),E.value=e,F.value=[],L.value=``,z.value=[],W.value=``,K.value=[],q.value=null,J.value=null,Y.value=``,hn())}function hn(){R.disconnect(),X.abort(),E.value&&(N.value===`live`?gn():N.value===`history`&&bn())}ne(N,hn);function gn(){E.value&&(F.value=[],L.value=``,R.connect(E.value,$t.value,{onSnapshot:({size:e,lines:t})=>{P.value=e,F.value=t,_n()},onLines:({lines:e})=>{F.value.push(...e),F.value.length>5e3&&F.value.splice(0,F.value.length-5e3),I.value&&_n()},onRotated:()=>{F.value.push(`--- log rotated ---`)},onError:e=>{L.value=e}}))}function _n(){a(()=>{let e=en.value;e&&(e.scrollTop=e.scrollHeight)})}function vn(){let e=en.value;e&&(I.value=e.scrollHeight-e.scrollTop-e.clientHeight<32)}async function yn(e,t=`forward`){if(E.value){U.value=!0,W.value=``;try{let n=await x.fetchLogSourceRange(E.value,{offset:e,size:Ut,direction:t});z.value=n.lines,B.value=n.startOffset,V.value=n.endOffset,H.value=n.fileSize,tn.value=n.truncatedHead,nn.value=n.truncatedTail,rn.value=n.binary,P.value=n.fileSize}catch(e){W.value=e?.message||`读取失败`}finally{U.value=!1}}}async function bn(){if(!E.value)return;let e=await wn();e&&await yn(Math.max(0,e.size-Ut),`forward`)}async function xn(){await yn(0,`forward`)}async function Sn(){let e=Math.max(0,B.value-Ut);e!==B.value&&await yn(e,`forward`)}async function Cn(){V.value>=H.value||await yn(V.value,`forward`)}async function wn(){if(!E.value)return null;try{let e=await x.fetchLogSourceMeta(E.value);return P.value=e.size,e}catch(e){return S.error(e?.message||`读取元数据失败`),null}}function Tn(){if(E.value){if(!G.value.trim()){S.error(`请输入关键词`);return}K.value=[],q.value=null,J.value=null,Y.value=``,X.search(E.value,{q:G.value,regex:an.value,caseInsensitive:on.value,maxHits:500,context:0},{onHit:e=>{K.value.push(e)},onTruncated:e=>{q.value=e},onDone:e=>{J.value=e},onError:e=>{Y.value=e}})}}function En(){X.abort()}function Q(e){return!Number.isFinite(e)||e<0?`-`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:e<1024*1024*1024?`${(e/1024/1024).toFixed(1)} MB`:`${(e/1024/1024/1024).toFixed(2)} GB`}function Dn(e){let t=G.value;if(!t)return $(e);let n=on.value?`gi`:`g`,r;try{r=an.value?new RegExp(t,n):new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),n)}catch{return $(e)}let i=``,a=0;for(let t of e.matchAll(r)){let n=t.index??0,r=n+t[0].length;n>a&&(i+=$(e.slice(a,n))),i+=`<mark class="bg-yellow-500/30 text-yellow-100 rounded px-0.5">${$(e.slice(n,r))}</mark>`,a=r}return a<e.length&&(i+=$(e.slice(a))),i}function $(e){return e.replace(/[&<>"']/g,e=>e===`&`?`&amp;`:e===`<`?`&lt;`:e===`>`?`&gt;`:e===`"`?`&quot;`:`&#39;`)}return t(async()=>{if(!x.projects.length)try{await x.fetchProjects()}catch{}await Z(),await sn()}),ne(k,()=>{sn()}),i(()=>{R.disconnect(),X.abort()}),(t,i)=>(e(),f(`div`,je,[u(`div`,Me,[u(`div`,Ne,[u(`button`,{onClick:i[0]||=e=>g(Wt).back(),class:`p-2 rounded-md text-textMuted hover:text-textMain hover:bg-white/5`},[y(g(ie),{class:`w-4 h-4`})]),u(`div`,null,[i[12]||=u(`h1`,{class:`text-xl font-bold text-textMain`},`运行日志`,-1),u(`p`,Pe,m(Gt.value?.name||C.value),1)])]),u(`div`,Fe,[u(`button`,{onClick:Z,class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-base border border-border hover:border-primary/50 hover:text-primary text-textMuted rounded-md transition-all`},[y(g(pe),{class:d([`w-3.5 h-3.5 mr-1.5`,{"animate-spin":T.value}])},null,8,[`class`]),i[13]||=v(` 刷新 `,-1)]),Yt.value?(e(),f(`button`,{key:0,onClick:cn,disabled:O.value||A.value.length===0,class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-base border border-yellow-400/40 text-yellow-400 hover:bg-yellow-400/10 disabled:opacity-50 disabled:hover:bg-base rounded-md transition-all`,title:A.value.length===0?`PM2 应用 ${k.value} 的日志文件已全部导入`:`从 pm2 jlist 自动识别 ${k.value} 的 stdout / stderr 文件路径并添加为日志源`},[y(g(Oe),{class:d([`w-3.5 h-3.5 mr-1.5`,{"animate-pulse":O.value}])},null,8,[`class`]),v(` `+m(A.value.length===0?`PM2 日志已导入`:`从 PM2 导入 (${A.value.length})`),1)],8,Ie)):k.value&&D.value&&D.value.found===!1?(e(),f(`span`,{key:1,class:`text-[11px] text-textMuted/70 italic`,title:D.value.message||`未在 PM2 中找到此应用`},`PM2 应用未找到`,8,Le)):p(``,!0),u(`button`,{onClick:i[1]||=e=>Xt.value=!0,class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-primary text-white hover:bg-primary/90 rounded-md transition-all`},[y(g(fe),{class:`w-3.5 h-3.5 mr-1.5`}),i[14]||=v(` 添加日志文件 `,-1)])])]),u(`div`,Re,[u(`aside`,ze,[u(`div`,Be,[i[15]||=u(`span`,null,`日志源`,-1),u(`span`,null,m(w.value.length),1)]),T.value?(e(),f(`div`,Ve,[y(g(de),{class:`w-4 h-4 mx-auto animate-spin`})])):w.value.length===0?(e(),f(`div`,He,[y(g(ue),{class:`w-5 h-5 mx-auto mb-2 opacity-50`}),i[16]||=v(` 暂无日志源 `,-1),i[17]||=u(`p`,{class:`mt-1 text-[10px]`},`点击右上「添加日志文件」`,-1)])):(e(),f(`ul`,Ue,[(e(!0),f(c,null,r(w.value,t=>(e(),f(`li`,{key:t.id,class:d([`group rounded-md border transition-all`,E.value===t.id?`border-primary/60 bg-primary/5`:`border-transparent hover:bg-white/5`])},[u(`div`,We,[u(`button`,{onClick:e=>mn(t.id),class:`flex-1 text-left min-w-0`},[j.value===t.id?(e(),f(`div`,{key:0,onClick:i[4]||=b(()=>{},[`stop`])},[s(u(`input`,{"onUpdate:modelValue":i[2]||=e=>M.value=e,onKeydown:[Ce(b(pn,[`prevent`]),[`enter`]),i[3]||=Ce(b(e=>j.value=``,[`prevent`]),[`esc`])],onBlur:pn,class:`w-full bg-base border border-border rounded px-2 py-1 text-xs text-textMain focus:outline-none focus:border-primary`,autofocus:``},null,40,Ke),[[ge,M.value]])])):(e(),f(`div`,qe,[u(`div`,Je,m(t.label),1),u(`div`,{class:`text-[10px] text-textMuted font-mono truncate`,title:t.filePath},m(t.filePath),9,Ye)]))],8,Ge),u(`div`,Xe,[u(`button`,{onClick:b(e=>fn(t),[`stop`]),class:`p-1 text-textMuted hover:text-textMain rounded`,title:`重命名`},[y(g(oe),{class:`w-3 h-3`})],8,Ze),u(`button`,{onClick:b(e=>un(t.id),[`stop`]),class:`p-1 text-textMuted hover:text-danger rounded`,title:`移除`},[y(g(me),{class:`w-3 h-3`})],8,Qe)])])],2))),128))]))]),u(`section`,$e,[Kt.value?(e(),f(c,{key:1},[u(`div`,tt,[u(`div`,nt,[u(`div`,rt,m(Kt.value.label),1),u(`div`,{class:`text-[10px] text-textMuted font-mono truncate`,title:Kt.value.filePath},m(Kt.value.filePath)+` · `+m(Q(P.value)),9,it)]),u(`div`,at,[(e(),f(c,null,r([`live`,`history`,`search`],t=>u(`button`,{key:t,onClick:e=>N.value=t,class:d([`inline-flex items-center px-2.5 py-1 text-xs rounded-md border transition-all`,N.value===t?`border-primary/60 bg-primary/10 text-primary`:`border-border text-textMuted hover:text-textMain`])},[t===`live`?(e(),h(g(re),{key:0,class:`w-3 h-3 mr-1`})):t===`history`?(e(),h(g(le),{key:1,class:`w-3 h-3 mr-1`})):(e(),h(g(De),{key:2,class:`w-3 h-3 mr-1`})),v(` `+m(t===`live`?`实时`:t===`history`?`历史`:`搜索`),1)],10,ot)),64))])]),N.value===`live`?(e(),f(`div`,st,[u(`div`,ct,[u(`div`,lt,[u(`label`,ut,[i[19]||=u(`span`,null,`尾部行数`,-1),s(u(`select`,{"onUpdate:modelValue":i[5]||=e=>$t.value=e,onChange:gn,class:`bg-base border border-border rounded px-2 py-0.5 text-textMain focus:outline-none focus:border-primary`},[...i[18]||=[u(`option`,{value:5},`5`,-1),u(`option`,{value:10},`10`,-1),u(`option`,{value:20},`20`,-1),u(`option`,{value:30},`30`,-1),u(`option`,{value:50},`50`,-1),u(`option`,{value:100},`100`,-1),u(`option`,{value:200},`200`,-1),u(`option`,{value:500},`500`,-1),u(`option`,{value:1e3},`1000`,-1)]],544),[[_e,$t.value,void 0,{number:!0}]])]),u(`span`,{class:d(g(R).connected?`text-success`:`text-textMuted`)},m(g(R).connected?`● 实时跟随`:`○ 已断开`),3)]),u(`div`,dt,[u(`button`,{onClick:i[6]||=e=>{I.value=!I.value,I.value&&_n()},class:d([`inline-flex items-center px-2 py-1 border border-border text-textMuted hover:text-textMain rounded`,{"text-primary border-primary/40":I.value}])},[(e(),h(n(I.value?g(Te):g(Ee)),{class:`w-3 h-3 mr-1`})),v(` `+m(I.value?`自动滚动中`:`已暂停滚动`),1)],2),u(`button`,{onClick:gn,class:`inline-flex items-center px-2 py-1 border border-border text-textMuted hover:text-textMain rounded`},[y(g(pe),{class:`w-3 h-3 mr-1`}),i[20]||=v(` 重连 `,-1)])])]),L.value?(e(),f(`div`,ft,[y(g(ve),{class:`w-3.5 h-3.5 mr-1`}),v(` `+m(L.value),1)])):p(``,!0),u(`div`,{ref_key:`liveLogRef`,ref:en,onScroll:vn,class:`flex-1 overflow-auto bg-base p-3 font-mono text-xs leading-relaxed`,style:{"min-height":`380px`}},[F.value.length===0?(e(),f(`div`,pt,[g(R).connected?(e(),h(g(de),{key:0,class:`w-4 h-4 mx-auto animate-spin`})):(e(),f(`span`,mt,`暂无日志内容`))])):p(``,!0),(e(!0),f(c,null,r(F.value,(t,n)=>(e(),f(`div`,{key:n,class:`whitespace-pre-wrap break-all text-textMain/90`},m(t),1))),128))],544)])):N.value===`history`?(e(),f(`div`,ht,[u(`div`,gt,[u(`div`,_t,[u(`button`,{onClick:xn,class:`inline-flex items-center px-2 py-1 border border-border text-textMuted hover:text-textMain rounded`},` 最前 `),u(`button`,{onClick:Sn,disabled:U.value||B.value<=0,class:`inline-flex items-center px-2 py-1 border border-border text-textMuted hover:text-textMain rounded disabled:opacity-40`},[y(g(se),{class:`w-3 h-3 mr-1`}),i[21]||=v(` 上一页 `,-1)],8,vt),u(`button`,{onClick:Cn,disabled:U.value||V.value>=H.value,class:`inline-flex items-center px-2 py-1 border border-border text-textMuted hover:text-textMain rounded disabled:opacity-40`},[y(g(ce),{class:`w-3 h-3 mr-1`}),i[22]||=v(` 下一页 `,-1)],8,yt),u(`button`,{onClick:bn,class:`inline-flex items-center px-2 py-1 border border-border text-textMuted hover:text-textMain rounded`},` 最末 `)]),u(`div`,bt,[v(m(Q(B.value))+` ~ `+m(Q(V.value))+` / `+m(Q(H.value))+` `,1),rn.value?(e(),f(`span`,xt,`[二进制]`)):p(``,!0)])]),W.value?(e(),f(`div`,St,[y(g(ve),{class:`w-3.5 h-3.5 mr-1`}),v(` `+m(W.value),1)])):p(``,!0),u(`div`,Ct,[U.value&&z.value.length===0?(e(),f(`div`,wt,[y(g(de),{class:`w-4 h-4 mx-auto animate-spin`})])):(e(),f(`div`,Tt,[tn.value?(e(),f(`div`,Et,`… 顶部已截齐到换行`)):p(``,!0),(e(!0),f(c,null,r(z.value,(t,n)=>(e(),f(`div`,{key:n,class:`whitespace-pre-wrap break-all text-textMain/90`},m(t),1))),128)),nn.value?(e(),f(`div`,Dt,`… 底部已截齐到换行`)):p(``,!0)]))])])):(e(),f(`div`,Ot,[u(`div`,kt,[u(`div`,At,[s(u(`input`,{"onUpdate:modelValue":i[7]||=e=>G.value=e,onKeydown:Ce(b(Tn,[`prevent`]),[`enter`]),type:`text`,spellcheck:`false`,placeholder:`输入关键词 / 正则 (回车搜索)`,class:`flex-1 bg-base border border-border rounded-md px-3 py-1.5 text-textMain text-sm font-mono focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/40`},null,40,jt),[[ge,G.value]]),g(X).running?(e(),f(`button`,{key:0,onClick:En,class:`inline-flex items-center px-3 py-1.5 text-xs border border-border rounded-md text-textMuted hover:text-textMain`},[y(g(xe),{class:`w-3 h-3 mr-1`}),i[23]||=v(` 中止 `,-1)])):(e(),f(`button`,{key:1,onClick:Tn,class:`inline-flex items-center px-3 py-1.5 text-xs bg-primary text-white rounded-md hover:bg-primary/90`},[y(g(De),{class:`w-3 h-3 mr-1`}),i[24]||=v(` 搜索 `,-1)]))]),u(`div`,Mt,[u(`label`,Nt,[s(u(`input`,{type:`checkbox`,"onUpdate:modelValue":i[8]||=e=>an.value=e,class:`mr-1 accent-primary`},null,512),[[he,an.value]]),i[25]||=v(` 正则`,-1)]),u(`label`,Pt,[s(u(`input`,{type:`checkbox`,"onUpdate:modelValue":i[9]||=e=>on.value=e,class:`mr-1 accent-primary`},null,512),[[he,on.value]]),i[26]||=v(` 忽略大小写`,-1)]),g(X).running?(e(),f(`span`,Ft,`搜索中…`)):J.value?(e(),f(`span`,It,`扫描 `+m(Q(J.value.scannedBytes))+`,命中 `+m(K.value.length)+` 条`,1)):p(``,!0),q.value?(e(),f(`span`,Lt,`已截断(达到 `+m(q.value.maxHits)+` 条上限)`,1)):p(``,!0)])]),Y.value?(e(),f(`div`,Rt,[y(g(ve),{class:`w-3.5 h-3.5 mr-1`}),v(` `+m(Y.value),1)])):p(``,!0),u(`div`,zt,[K.value.length===0&&!g(X).running?(e(),f(`div`,Bt,m(J.value?`无匹配`:`输入关键词后回车开始搜索`),1)):p(``,!0),u(`ul`,null,[(e(!0),f(c,null,r(K.value,(t,n)=>(e(),f(`li`,{key:n,class:`flex items-start py-0.5`},[u(`span`,{class:`text-textMuted/60 mr-3 text-right shrink-0 font-mono`,style:{"min-width":`7em`},title:`offset=${t.offset}`},`@`+m(Q(t.offset)),9,Vt),u(`span`,{class:`text-textMain/90 whitespace-pre-wrap break-all`,innerHTML:Dn(t.text)},null,8,Ht)]))),128))])])]))],64)):(e(),f(`div`,et,` 请选择左侧日志源 `))])]),y(ae,{open:Xt.value,mode:`multi`,pickKind:`file`,title:`选择日志文件(可多选)`,"onUpdate:open":i[10]||=e=>Xt.value=e,onConfirm:ln},null,8,[`open`]),y(we,{open:Zt.value,title:`移除日志源`,message:`移除后将无法继续查看该文件。日志文件本身不会被删除。`,"confirm-text":`移除`,tone:`danger`,"onUpdate:open":i[11]||=e=>Zt.value=e,onConfirm:dn},null,8,[`open`])]))}});export{Wt as default};
@@ -0,0 +1 @@
1
+ import{A as e,D as t,U as n,V as r,b as i,f as a,ft as o,h as s,m as c,mt as l,n as u,p as d,q as f,t as p,v as m,y as h}from"./createLucideIcon-BmsTm7z-.js";import{g,u as _,y as v}from"./index-BZU6i5nw.js";var y=p(`log-in`,[[`path`,{d:`m10 17 5-5-5-5`,key:`1bsop3`}],[`path`,{d:`M15 12H3`,key:`6jk70r`}],[`path`,{d:`M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4`,key:`u53s6r`}]]),b=p(`rocket`,[[`path`,{d:`M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5`,key:`qeys4`}],[`path`,{d:`M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09`,key:`u4xsad`}],[`path`,{d:`M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z`,key:`676m9`}],[`path`,{d:`M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05`,key:`92ym6u`}]]),x={class:`min-h-screen bg-base flex flex-col items-center justify-center p-4`},S={class:`w-full max-w-md`},C={class:`flex flex-col items-center justify-center mb-8`},w={class:`w-16 h-16 bg-primary/10 border border-primary/20 rounded-2xl flex items-center justify-center mb-4 shadow-[0_0_30px_rgba(59,130,246,0.15)]`},T={class:`bg-panel border border-border rounded-2xl p-6 sm:p-8 shadow-xl`},E={key:0,class:`text-danger text-xs mt-2 flex items-center`},D=[`disabled`],O={key:1,class:`animate-spin -ml-1 mr-3 h-5 w-5 text-white`,xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`},k=i({__name:`Login`,setup(i){let p=_(),k=u(),A=n(``),j=n(!1),M=n(``);t(()=>{k.adminToken&&p.replace(`/`)});let N=async()=>{if(A.value){j.value=!0,M.value=``;try{await k.login(A.value)?p.replace(`/`):M.value=`Token 校验失败,请检查配置。`}catch(e){M.value=e.message||`登录异常,请稍后重试。`}finally{j.value=!1}}};return(t,n)=>(e(),s(`div`,x,[a(`div`,S,[a(`div`,C,[a(`div`,w,[h(f(b),{class:`w-8 h-8 text-primary`})]),n[1]||=a(`h1`,{class:`text-3xl font-bold text-textMain tracking-tight`},`Kite Deploy`,-1),n[2]||=a(`p`,{class:`text-textMuted text-sm mt-2`},`云原生极简部署管理面板`,-1)]),a(`div`,T,[n[5]||=a(`h2`,{class:`text-lg font-medium text-textMain mb-6`},`管理员登录`,-1),a(`form`,{onSubmit:v(N,[`prevent`]),class:`space-y-5`},[a(`div`,null,[n[3]||=a(`label`,{class:`block text-sm font-medium text-textMuted mb-2`},`Admin Token`,-1),r(a(`input`,{"onUpdate:modelValue":n[0]||=e=>A.value=e,type:`password`,placeholder:`请输入服务端生成的 ADMIN_TOKEN`,class:o([`w-full bg-base border border-border rounded-lg px-4 py-3 text-textMain font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all placeholder:text-textMuted/50 placeholder:font-sans`,{"border-danger focus:border-danger focus:ring-danger/50":M.value}])},null,2),[[g,A.value]]),M.value?(e(),s(`p`,E,l(M.value),1)):c(``,!0)]),a(`button`,{type:`submit`,disabled:!A.value||j.value,class:`w-full flex items-center justify-center px-4 py-3 bg-primary text-white rounded-lg font-medium transition-all hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed shadow-[0_0_15px_rgba(59,130,246,0.3)]`},[j.value?(e(),s(`svg`,O,[...n[4]||=[a(`circle`,{class:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,"stroke-width":`4`},null,-1),a(`path`,{class:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z`},null,-1)]])):(e(),d(f(y),{key:0,class:`w-5 h-5 mr-2`})),m(` `+l(j.value?`验证中...`:`进入控制台`),1)],8,D)],32),n[6]||=a(`div`,{class:`mt-6 text-center`},[a(`p`,{class:`text-xs text-textMuted`},[m(` Token 可以在服务端启动目录的 `),a(`code`,{class:`font-mono bg-base px-1 py-0.5 rounded border border-border`},`.env.local`),m(` 文件中找到。 `)])],-1)])])]))}});export{k as default};
@@ -0,0 +1 @@
1
+ import{A as e,D as t,M as n,U as r,V as i,b as a,c as o,d as s,f as c,ft as l,h as u,m as d,mt as f,n as ee,p,q as m,t as h,v as g,y as _}from"./createLucideIcon-BmsTm7z-.js";import{t as te}from"./database-D6rC_24l.js";import{t as v}from"./loader-circle-OwtRa1dp.js";import{t as ne}from"./refresh-cw-OqaxwQhF.js";import{f as y,g as re,h as ie,i as b,m as x,s as S,y as ae}from"./index-BZU6i5nw.js";import{t as oe}from"./ConfirmDialog-CikXU818.js";var C=h(`download`,[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]),se=h(`file-archive`,[[`path`,{d:`M13.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v11.5`,key:`4pqfef`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 12v-1`,key:`1ej8lb`}],[`path`,{d:`M8 18v-2`,key:`qcmpov`}],[`path`,{d:`M8 7V6`,key:`1nbb54`}],[`circle`,{cx:`8`,cy:`20`,r:`2`,key:`ckkr5m`}]]),w=h(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),ce={class:`max-w-5xl mx-auto space-y-6 pb-12 p-4 sm:p-0`},le={class:`flex items-center space-x-3 mb-8`},ue={class:`bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},de={class:`px-4 sm:px-6 py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02] flex flex-col sm:flex-row sm:justify-between sm:items-center gap-3`},fe={class:`text-lg font-semibold text-textMain flex items-center`},pe=[`disabled`],me={class:`p-4 sm:p-6 space-y-6`},he={key:0,class:`p-3 rounded-lg bg-danger/10 border border-danger/30 text-danger text-sm flex items-center`},ge={class:`flex items-center justify-between mb-2`},_e={class:`text-xs text-textMuted`},ve={class:`border border-border rounded-lg overflow-x-auto`},ye={class:`w-full text-sm min-w-[640px]`},be={class:`dark:bg-white/[0.02] bg-black/[0.02] text-textMuted`},xe={class:`w-10 px-3 py-2 text-left`},T=[`checked`,`.indeterminate`],E={key:0},D={key:1},O=[`onClick`],k={class:`px-3 py-2`},A=[`checked`,`onChange`],j={class:`px-3 py-2`},M={class:`font-medium text-textMain`},Se={class:`font-mono text-xs text-textMuted`},Ce={class:`px-3 py-2`},we={key:0,class:`text-xs text-yellow-500 mt-0.5 flex items-center`},Te={class:`px-3 py-2 text-right text-textMuted`},Ee={class:`space-y-3`},De={class:`flex items-start space-x-3 cursor-pointer`},Oe={class:`flex items-start space-x-3 cursor-pointer`},ke={key:0,class:`ml-7 space-y-2`},Ae={class:`flex items-center space-x-4 text-sm`},je={class:`flex items-center space-x-2 cursor-pointer`},Me={class:`flex items-center space-x-2 cursor-pointer`},Ne=[`disabled`],Pe={class:`flex justify-end`},Fe=[`disabled`],Ie={class:`bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},Le={class:`px-4 sm:px-6 py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02]`},Re={class:`text-lg font-semibold text-textMain flex items-center`},ze={class:`p-4 sm:p-6 space-y-5`},Be={class:`flex flex-col sm:flex-row sm:items-center gap-3`},Ve={class:`self-start inline-flex items-center px-3 py-2 rounded-lg border border-border bg-base text-sm text-textMain cursor-pointer hover:border-primary`},He={key:0,class:`text-sm text-textMuted break-all`},Ue={class:`grid grid-cols-1 md:grid-cols-2 gap-4`},We={class:`flex items-center space-x-2 cursor-pointer mt-2`},Ge={key:1,class:`border border-border rounded-lg p-4 bg-base space-y-3`},Ke={class:`grid grid-cols-1 md:grid-cols-3 gap-3 text-sm`},qe={class:`p-3 rounded bg-panel border border-border`},Je={class:`mt-1 text-textMain`},Ye={class:`p-3 rounded bg-panel border border-border`},Xe={class:`mt-1 text-textMain`},Ze={class:`p-3 rounded bg-panel border border-border`},Qe={class:`mt-1 text-textMain`},$e={class:`text-sm`},et={class:`text-success`},tt={key:0,class:`space-y-1 text-xs`},nt={key:0},rt={class:`text-xs text-textMuted`},it={class:`flex justify-end`},at=[`disabled`],N=a({__name:`Migration`,setup(a){let h=ee(),N=r([]),P=r(!1),F=r(``),I=r([]),L=r({includeArtifacts:!0,includeDeployments:!0,deploymentMode:`all`,deploymentLimitPerProject:50}),R=r(!1),z=r(``),B=r(`success`),V=r(null),H=r(`skip-existing`),U=r(!0),W=r(!1),G=r(``),K=r(`success`),q=r(null),J=s(()=>N.value.length>0&&I.value.length===N.value.length),Y=s(()=>I.value.length>0&&I.value.length<N.value.length);function ot(){J.value?I.value=[]:I.value=N.value.map(e=>e.id)}function X(e){let t=I.value.indexOf(e);t>=0?I.value.splice(t,1):I.value.push(e)}async function Z(){P.value=!0,F.value=``;try{let e=await fetch(`/api/migration/projects`,{headers:{Authorization:`Bearer ${h.adminToken}`}}),t=await e.json();if(!e.ok)throw Error(t.error||`获取项目失败`);N.value=t.projects||[],I.value=N.value.map(e=>e.id)}catch(e){F.value=e.message}finally{P.value=!1}}async function st(){if(z.value=``,I.value.length===0){z.value=`请至少选择一个项目`,B.value=`error`;return}R.value=!0;try{let e={projectIds:I.value,includeArtifacts:L.value.includeArtifacts,includeDeployments:L.value.includeDeployments,deploymentLimitPerProject:L.value.includeDeployments&&L.value.deploymentMode===`limit`?Math.max(0,Math.floor(Number(L.value.deploymentLimitPerProject)||0)):0},t=await fetch(`/api/migration/export`,{method:`POST`,headers:{Authorization:`Bearer ${h.adminToken}`,"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok){let e=`HTTP ${t.status}`;try{e=(await t.json()).error||e}catch{}throw Error(e)}let n=t.headers.get(`Content-Disposition`)||``,r=/filename="?([^"]+)"?/.exec(n),i=r?r[1]:`kite-export-${Date.now()}.zip`,a=await t.blob(),o=URL.createObjectURL(a),s=document.createElement(`a`);s.href=o,s.download=i,document.body.appendChild(s),s.click(),document.body.removeChild(s),URL.revokeObjectURL(o),z.value=`导出成功:${i}(${(a.size/1024).toFixed(1)} KB)`,B.value=`success`}catch(e){z.value=`导出失败:${e.message}`,B.value=`error`}finally{R.value=!1}}function ct(e){V.value=e.target.files?.[0]||null,G.value=``,q.value=null}async function lt(){if(G.value=``,q.value=null,!V.value){G.value=`请选择要导入的 zip 文件`,K.value=`error`;return}if(H.value===`overwrite`){Q.value=!0;return}await $()}let Q=r(!1);async function ut(){Q.value=!1,await $()}async function $(){if(V.value){W.value=!0;try{let e=new FormData;e.append(`file`,V.value),e.append(`strategy`,H.value),e.append(`restoreArtifacts`,U.value?`true`:`false`);let t={Authorization:`Bearer ${h.adminToken}`};H.value===`overwrite`&&(t[`X-Confirm-Overwrite`]=`yes`);let n=await fetch(`/api/migration/import`,{method:`POST`,headers:t,body:e}),r=await n.json();if(!n.ok)throw Error(r.error||`HTTP ${n.status}`);q.value=r.summary,G.value=`导入完成`,K.value=`success`,await Z()}catch(e){G.value=`导入失败:${e.message}`,K.value=`error`}finally{W.value=!1}}}return t(Z),(t,r)=>(e(),u(`div`,ce,[c(`div`,le,[_(m(te),{class:`w-7 h-7 text-primary`}),r[9]||=c(`h1`,{class:`text-2xl font-bold text-textMain tracking-tight`},`数据迁移`,-1)]),c(`div`,ue,[c(`div`,de,[c(`div`,null,[c(`h2`,fe,[_(m(C),{class:`w-5 h-5 mr-2 text-primary`}),r[10]||=g(` 导出 `,-1)]),r[11]||=c(`p`,{class:`text-sm text-textMuted mt-1`},`选择项目并下载 zip 归档,可用于备份或迁移到另一台机器。`,-1)]),c(`button`,{onClick:Z,class:`self-start sm:self-auto flex items-center text-sm text-textMuted hover:text-primary transition-colors`,disabled:P.value},[_(m(ne),{class:l([`w-4 h-4 mr-1`,P.value?`animate-spin`:``])},null,8,[`class`]),r[12]||=g(` 刷新 `,-1)],8,pe)]),c(`div`,me,[F.value?(e(),u(`div`,he,[_(m(b),{class:`w-4 h-4 mr-2`}),g(f(F.value),1)])):d(``,!0),c(`div`,null,[c(`div`,ge,[r[13]||=c(`h3`,{class:`text-sm font-medium text-textMain`},`项目列表`,-1),c(`span`,_e,`已选 `+f(I.value.length)+` / `+f(N.value.length),1)]),c(`div`,ve,[c(`table`,ye,[c(`thead`,be,[c(`tr`,null,[c(`th`,xe,[c(`input`,{type:`checkbox`,checked:J.value,".indeterminate":Y.value,onChange:ot,class:`rounded border-border`},null,40,T)]),r[14]||=c(`th`,{class:`px-3 py-2 text-left font-medium`},`项目名 / ID`,-1),r[15]||=c(`th`,{class:`px-3 py-2 text-left font-medium`},`部署路径`,-1),r[16]||=c(`th`,{class:`px-3 py-2 text-right font-medium`},`部署日志`,-1)])]),c(`tbody`,null,[P.value?(e(),u(`tr`,E,[...r[17]||=[c(`td`,{colspan:`4`,class:`px-3 py-6 text-center text-textMuted`},`加载中...`,-1)]])):N.value.length===0?(e(),u(`tr`,D,[...r[18]||=[c(`td`,{colspan:`4`,class:`px-3 py-6 text-center text-textMuted`},`暂无项目`,-1)]])):d(``,!0),(e(!0),u(o,null,n(N.value,t=>(e(),u(`tr`,{key:t.id,class:`border-t border-border dark:hover:bg-white/[0.02] hover:bg-black/[0.02] cursor-pointer`,onClick:e=>X(t.id)},[c(`td`,k,[c(`input`,{type:`checkbox`,checked:I.value.includes(t.id),onClick:r[0]||=ae(()=>{},[`stop`]),onChange:e=>X(t.id),class:`rounded border-border`},null,40,A)]),c(`td`,j,[c(`div`,M,f(t.name),1),c(`div`,Se,f(t.id),1)]),c(`td`,Ce,[c(`div`,{class:l([`font-mono text-xs break-all`,t.deployPathExists?`text-textMain`:`text-textMuted`])},f(t.deployPath),3),t.deployPathExists?d(``,!0):(e(),u(`div`,we,[_(m(b),{class:`w-3 h-3 mr-1`}),r[19]||=g(`路径不存在,artifacts 会被跳过 `,-1)]))]),c(`td`,Te,f(t.deploymentCount),1)],8,O))),128))])])])]),c(`div`,Ee,[r[25]||=c(`h3`,{class:`text-sm font-medium text-textMain`},`导出选项`,-1),c(`label`,De,[i(c(`input`,{type:`checkbox`,"onUpdate:modelValue":r[1]||=e=>L.value.includeArtifacts=e,class:`mt-0.5 rounded border-border`},null,512),[[y,L.value.includeArtifacts]]),r[20]||=c(`div`,null,[c(`div`,{class:`text-sm text-textMain`},`包含部署 artifacts(项目 deployPath 内的文件)`),c(`div`,{class:`text-xs text-textMuted`},`关闭后仅导出数据库元数据与部署日志,体积更小。`)],-1)]),c(`label`,Oe,[i(c(`input`,{type:`checkbox`,"onUpdate:modelValue":r[2]||=e=>L.value.includeDeployments=e,class:`mt-0.5 rounded border-border`},null,512),[[y,L.value.includeDeployments]]),r[21]||=c(`div`,null,[c(`div`,{class:`text-sm text-textMain`},`包含部署日志`),c(`div`,{class:`text-xs text-textMuted`},`默认导出所有日志以保证信息完全一致。`)],-1)]),L.value.includeDeployments?(e(),u(`div`,ke,[c(`div`,Ae,[c(`label`,je,[i(c(`input`,{type:`radio`,value:`all`,"onUpdate:modelValue":r[3]||=e=>L.value.deploymentMode=e},null,512),[[x,L.value.deploymentMode]]),r[22]||=c(`span`,{class:`text-textMain`},`保留全部`,-1)]),c(`label`,Me,[i(c(`input`,{type:`radio`,value:`limit`,"onUpdate:modelValue":r[4]||=e=>L.value.deploymentMode=e},null,512),[[x,L.value.deploymentMode]]),r[23]||=c(`span`,{class:`text-textMain`},`每项目最近`,-1),i(c(`input`,{type:`number`,"onUpdate:modelValue":r[5]||=e=>L.value.deploymentLimitPerProject=e,min:`1`,class:`w-20 px-2 py-1 rounded bg-base border border-border text-sm text-textMain`,disabled:L.value.deploymentMode!==`limit`},null,8,Ne),[[re,L.value.deploymentLimitPerProject,void 0,{number:!0}]]),r[24]||=c(`span`,{class:`text-textMuted`},`条`,-1)])])])):d(``,!0)]),z.value?(e(),u(`div`,{key:1,class:l([`p-3 rounded-lg border text-sm flex items-center`,B.value===`success`?`bg-success/10 border-success/30 text-success`:`bg-danger/10 border-danger/30 text-danger`])},[B.value===`success`?(e(),p(m(S),{key:0,class:`w-4 h-4 mr-2`})):(e(),p(m(b),{key:1,class:`w-4 h-4 mr-2`})),g(` `+f(z.value),1)],2)):d(``,!0),c(`div`,Pe,[c(`button`,{onClick:st,disabled:R.value||I.value.length===0,class:`inline-flex items-center px-4 py-2 rounded-lg bg-primary text-white text-sm font-medium disabled:opacity-50 hover:opacity-90 transition-opacity`},[R.value?(e(),p(m(v),{key:0,class:`w-4 h-4 mr-2 animate-spin`})):(e(),p(m(C),{key:1,class:`w-4 h-4 mr-2`})),g(` `+f(R.value?`导出中...`:`导出选中项目`),1)],8,Fe)])])]),c(`div`,Ie,[c(`div`,Le,[c(`h2`,Re,[_(m(w),{class:`w-5 h-5 mr-2 text-primary`}),r[26]||=g(` 导入 `,-1)]),r[27]||=c(`p`,{class:`text-sm text-textMuted mt-1`},`从 kite-export-*.zip 还原项目、设置、部署日志与 artifacts。`,-1)]),c(`div`,ze,[c(`div`,null,[r[29]||=c(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`选择文件`,-1),c(`div`,Be,[c(`label`,Ve,[_(m(se),{class:`w-4 h-4 mr-2`}),r[28]||=g(` 选择 zip 文件 `,-1),c(`input`,{type:`file`,accept:`.zip,application/zip`,onChange:ct,class:`hidden`},null,32)]),V.value?(e(),u(`span`,He,f(V.value.name)+` (`+f((V.value.size/1024).toFixed(1))+` KB) `,1)):d(``,!0)])]),c(`div`,Ue,[c(`div`,null,[r[31]||=c(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`冲突策略`,-1),i(c(`select`,{"onUpdate:modelValue":r[6]||=e=>H.value=e,class:`w-full px-3 py-2 rounded-lg bg-base border border-border text-sm text-textMain`},[...r[30]||=[c(`option`,{value:`skip-existing`},`skip-existing(默认,跳过已存在)`,-1),c(`option`,{value:`merge`},`merge(仅插入新数据)`,-1),c(`option`,{value:`overwrite`},`overwrite(覆盖同 ID 数据)`,-1)]],512),[[ie,H.value]]),r[32]||=c(`p`,{class:`text-xs text-textMuted mt-1`},`overwrite 会覆盖已有项目/设置/部署日志,请谨慎使用。`,-1)]),c(`div`,null,[r[34]||=c(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`Artifacts 还原`,-1),c(`label`,We,[i(c(`input`,{type:`checkbox`,"onUpdate:modelValue":r[7]||=e=>U.value=e,class:`rounded border-border`},null,512),[[y,U.value]]),r[33]||=c(`span`,{class:`text-sm text-textMain`},`还原 artifacts 到项目 deployPath`,-1)]),r[35]||=c(`p`,{class:`text-xs text-textMuted mt-1`},`关闭则仅恢复数据库内容,不解压 artifacts。`,-1)])]),G.value?(e(),u(`div`,{key:0,class:l([`p-3 rounded-lg border text-sm flex items-center`,K.value===`success`?`bg-success/10 border-success/30 text-success`:`bg-danger/10 border-danger/30 text-danger`])},[K.value===`success`?(e(),p(m(S),{key:0,class:`w-4 h-4 mr-2`})):(e(),p(m(b),{key:1,class:`w-4 h-4 mr-2`})),g(` `+f(G.value),1)],2)):d(``,!0),q.value?(e(),u(`div`,Ge,[r[41]||=c(`div`,{class:`text-sm font-medium text-textMain`},`导入摘要`,-1),c(`div`,Ke,[c(`div`,qe,[r[36]||=c(`div`,{class:`text-textMuted text-xs`},`项目`,-1),c(`div`,Je,` 新增 `+f(q.value.projects.inserted)+` / 更新 `+f(q.value.projects.updated)+` / 跳过 `+f(q.value.projects.skipped),1)]),c(`div`,Ye,[r[37]||=c(`div`,{class:`text-textMuted text-xs`},`设置`,-1),c(`div`,Xe,` 新增 `+f(q.value.settings.inserted)+` / 更新 `+f(q.value.settings.updated)+` / 跳过 `+f(q.value.settings.skipped),1)]),c(`div`,Ze,[r[38]||=c(`div`,{class:`text-textMuted text-xs`},`部署日志`,-1),c(`div`,Qe,` 新增 `+f(q.value.deployments.inserted)+` / 更新 `+f(q.value.deployments.updated)+` / 跳过 `+f(q.value.deployments.skipped),1)])]),c(`div`,$e,[r[39]||=c(`span`,{class:`text-textMuted`},`Artifacts:`,-1),c(`span`,et,`成功 `+f(q.value.artifacts.ok),1),r[40]||=c(`span`,{class:`text-textMuted mx-1`},`/`,-1),c(`span`,{class:l(q.value.artifacts.warnings>0?`text-yellow-500`:`text-textMuted`)},` 警告 `+f(q.value.artifacts.warnings),3)]),q.value.artifacts.items.length>0?(e(),u(`div`,tt,[(e(!0),u(o,null,n(q.value.artifacts.items,t=>(e(),u(`div`,{key:t.projectId,class:l([`font-mono`,t.status===`ok`?`text-textMuted`:`text-yellow-500`])},[g(` [`+f(t.status)+`] `+f(t.projectId),1),t.message?(e(),u(`span`,nt,` — `+f(t.message),1)):d(``,!0)],2))),128))])):d(``,!0),c(`div`,rt,` 来自 schemaVersion=`+f(q.value.manifest.schemaVersion)+`,导出时间 `+f(q.value.manifest.exportedAt)+`,源 kiteVersion=`+f(q.value.manifest.kiteVersion),1)])):d(``,!0),c(`div`,it,[c(`button`,{onClick:lt,disabled:W.value||!V.value,class:`inline-flex items-center px-4 py-2 rounded-lg bg-primary text-white text-sm font-medium disabled:opacity-50 hover:opacity-90 transition-opacity`},[W.value?(e(),p(m(v),{key:0,class:`w-4 h-4 mr-2 animate-spin`})):(e(),p(m(w),{key:1,class:`w-4 h-4 mr-2`})),g(` `+f(W.value?`导入中...`:`开始导入`),1)],8,at)])])]),_(oe,{open:Q.value,"onUpdate:open":r[8]||=e=>Q.value=e,tone:`danger`,title:`确认使用 Overwrite 策略导入?`,message:`Overwrite 策略会覆盖同 ID 的现有项目、设置与部署日志。此操作不可撤销,请确认你已备份当前数据。`,"confirm-text":`确认覆盖导入`,"cancel-text":`取消`,loading:W.value,onConfirm:ut},null,8,[`open`,`loading`])]))}});export{N as default};
@@ -0,0 +1 @@
1
+ import{A as e,B as t,D as n,E as r,F as i,M as a,P as ee,U as o,V as s,_ as c,b as l,c as u,d,f,ft as p,h as m,m as h,mt as g,n as te,p as _,pt as ne,q as v,t as y,v as b,y as x,z as S}from"./createLucideIcon-BmsTm7z-.js";import{t as re}from"./activity-DZCOq6kQ.js";import{n as ie,r as ae,t as oe}from"./rotate-ccw-D8C0iiAw.js";import{t as se}from"./archive-MB1JcYug.js";import{t as ce}from"./arrow-left-CsZYc3XK.js";import{n as le,t as ue}from"./pencil-BTFuj0gA.js";import{n as de,r as fe,t as pe}from"./history-dkZbN_TB.js";import{n as C,t as me}from"./file-text-BxWt6is5.js";import{t as he}from"./copy-CNXWZJbC.js";import{n as ge,r as _e,t as ve}from"./useIntervalRaf-CXWU2lqg.js";import{t as ye}from"./eye-vRDqRzR9.js";import{t as be}from"./folder-open-DQz0XviI.js";import{t as w}from"./folder-CYPJgLMr.js";import{n as xe,t as Se}from"./save-D0NTjP8Q.js";import{n as Ce,t as we}from"./square-terminal-C1oJyHEG.js";import{t as T}from"./loader-circle-OwtRa1dp.js";import{t as Te}from"./plus-CcefsCv_.js";import{t as E}from"./refresh-cw-OqaxwQhF.js";import{t as Ee}from"./scroll-text-6UwJwqap.js";import{t as De}from"./ProjectTagsEditor-zXN_5rwP.js";import{t as Oe}from"./trash-2-20ikd6fk.js";import{_ as ke,d as D,f as Ae,g as O,h as je,i as Me,l as Ne,m as Pe,n as Fe,o as Ie,r as k,s as Le,t as A,u as Re,v as ze,y as j}from"./index-BZU6i5nw.js";import{t as Be}from"./ConfirmDialog-CikXU818.js";var Ve=y(`shield-alert`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M12 16h.01`,key:`1drbdi`}]]),M=y(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),He=y(`shield`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]]),Ue=y(`sliders-horizontal`,[[`path`,{d:`M10 5H3`,key:`1qgfaw`}],[`path`,{d:`M12 19H3`,key:`yhmn1j`}],[`path`,{d:`M14 3v4`,key:`1sua03`}],[`path`,{d:`M16 17v4`,key:`1q0r14`}],[`path`,{d:`M21 12h-9`,key:`1o4lsq`}],[`path`,{d:`M21 19h-5`,key:`1rlt1p`}],[`path`,{d:`M21 5h-7`,key:`1oszz2`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M8 12H3`,key:`a7s4jb`}]]),N={class:`select-none`},We={key:1,class:`w-4 h-4 inline-block`},Ge={class:`text-textMuted shrink-0 font-mono`},Ke=l({__name:`DeleteTreeView`,props:{node:{},depth:{},defaultExpand:{type:Boolean}},setup(t){let n=t,r=d(()=>n.depth??0),i=o(n.defaultExpand??r.value<1),s=d(()=>!!n.node.children&&n.node.children.length>0),c=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:e<1024*1024*1024?`${(e/1024/1024).toFixed(2)} MB`:`${(e/1024/1024/1024).toFixed(2)} GB`,l=d(()=>n.node.type===`dir`?s.value?n.node.willDelete?`text-danger`:`text-textMain`:`text-textMuted`:n.node.willDelete?`text-danger`:`text-success`);return(n,o)=>{let d=ee(`DeleteTreeView`,!0);return e(),m(`div`,N,[f(`div`,{class:`flex items-center gap-1.5 py-0.5 px-1 rounded text-xs hover:bg-white/[0.03] dark:hover:bg-white/[0.04]`,style:ne({paddingLeft:`${r.value*14+4}px`})},[s.value?(e(),m(`button`,{key:0,onClick:o[0]||=e=>i.value=!i.value,class:`w-4 h-4 flex items-center justify-center text-textMuted hover:text-textMain`,type:`button`},[i.value?(e(),_(v(fe),{key:0,class:`w-3 h-3`})):(e(),_(v(C),{key:1,class:`w-3 h-3`}))])):(e(),m(`span`,We)),t.node.type===`dir`?(e(),_(v(w),{key:2,class:p([`w-3.5 h-3.5 shrink-0`,l.value])},null,8,[`class`])):(e(),_(v(me),{key:3,class:p([`w-3.5 h-3.5 shrink-0`,l.value])},null,8,[`class`])),f(`span`,{class:p([`font-mono truncate flex-1`,l.value])},g(t.node.name||`/`),3),f(`span`,Ge,g(c(t.node.size)),1),t.node.willDelete&&t.node.type===`file`?(e(),_(v(Oe),{key:4,class:`w-3 h-3 text-danger/80 shrink-0`})):!t.node.willDelete&&t.node.type===`file`?(e(),_(v(M),{key:5,class:`w-3 h-3 text-success/80 shrink-0`})):h(``,!0)],4),i.value&&s.value?(e(!0),m(u,{key:0},a(t.node.children,t=>(e(),_(d,{key:t.path,node:t,depth:r.value+1},null,8,[`node`,`depth`]))),128)):h(``,!0)])}}}),qe={class:`flex-1 min-w-0`},P={class:`text-base font-semibold text-textMain`},Je={class:`font-mono`},F={key:0,class:`mx-6 mt-4 p-3 rounded-md bg-danger/10 border border-danger/30 flex items-start gap-2`},Ye={class:`px-6 py-4 grid grid-cols-3 gap-3 border-b border-border`},I={class:`bg-base border border-border rounded-md p-3`},L={class:`text-lg font-bold text-danger font-mono`},Xe={class:`text-[10px] text-textMuted`},Ze={class:`bg-base border border-border rounded-md p-3`},Qe={class:`text-lg font-bold text-success font-mono`},$e={class:`bg-base border border-border rounded-md p-3`},et={class:`text-lg font-bold text-textMain font-mono`},R={key:0,class:`text-[10px] text-yellow-400`},z={key:1,class:`text-[10px] text-textMuted`},B={key:1,class:`px-6 py-3 border-b border-border flex items-center gap-2 flex-wrap`},tt={class:`flex-1 overflow-y-auto px-4 py-3 min-h-[200px]`},V={key:0,class:`flex items-center justify-center py-10 text-textMuted`},nt={key:1,class:`text-sm text-danger py-6 text-center`},rt={key:2,class:`text-textMuted text-sm py-6 text-center`},it={class:`px-6 py-3 border-t border-border flex items-center justify-between`},at={key:0,class:`text-[11px] text-textMuted`},ot={key:1},st=A(l({__name:`CleanPreviewDialog`,props:{open:{type:Boolean},loading:{type:Boolean},error:{},preview:{},mode:{},protectPaths:{}},emits:[`update:open`],setup(n,{emit:r}){let i=n,ee=r,s=d(()=>i.mode===`clean-all`),c=d(()=>i.preview?.summary),l=d(()=>i.preview?.tree),te=e=>e==null?`-`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;function ne(){ee(`update:open`,!1)}let y=o([]);return S(()=>i.protectPaths,e=>{y.value=[...e||[]]},{immediate:!0}),(r,i)=>(e(),_(D,{name:`fade`},{default:t(()=>[n.open?(e(),m(`div`,{key:0,class:`fixed inset-0 z-[60] flex items-center justify-center bg-black/60 backdrop-blur-sm`,onClick:j(ne,[`self`])},[f(`div`,{class:p([`bg-panel border rounded-xl w-full max-w-2xl shadow-2xl flex flex-col max-h-[85vh]`,s.value?`border-danger/40`:`border-yellow-400/30`])},[f(`div`,{class:p([`px-6 py-4 border-b flex items-start gap-3`,s.value?`border-danger/30`:`border-border`])},[f(`div`,{class:p([`w-10 h-10 rounded-lg flex items-center justify-center shrink-0`,s.value?`bg-danger/10`:`bg-yellow-400/10`])},[s.value?(e(),_(v(Ve),{key:0,class:`w-5 h-5 text-danger`})):(e(),_(v(ye),{key:1,class:`w-5 h-5 text-yellow-400`}))],2),f(`div`,qe,[f(`h3`,P,[i[0]||=b(` 清理预览 — `,-1),f(`span`,Je,g(n.mode),1),i[1]||=f(`span`,{class:`ml-2 px-1.5 py-0.5 text-[10px] rounded bg-base border border-border text-textMuted align-middle font-mono`},`DRY-RUN`,-1)]),i[2]||=f(`p`,{class:`text-xs text-textMuted mt-1`},` 仅模拟,不会真正删除文件。下一次部署时会按"已保存"的策略自动执行清理。 `,-1)]),f(`button`,{onClick:ne,class:`text-textMuted hover:text-textMain p-1 rounded`,type:`button`},[x(v(k),{class:`w-4 h-4`})])],2),s.value?(e(),m(`div`,F,[x(v(Me),{class:`w-4 h-4 text-danger shrink-0 mt-0.5`}),i[3]||=f(`p`,{class:`text-xs text-danger leading-relaxed`},[f(`strong`,null,`clean-all`),b(` 会清空部署目录下除 `),f(`code`,{class:`font-mono bg-base px-1 rounded`},`.kite-*`),b(` 之外的`),f(`strong`,null,`全部内容`),b(`,请仔细确认 protectPaths 与预览结果。 `)],-1)])):h(``,!0),f(`div`,Ye,[f(`div`,I,[i[4]||=f(`p`,{class:`text-[10px] text-textMuted uppercase tracking-wider`},`将删除`,-1),f(`p`,L,g(c.value?.deleteFiles??`-`),1),f(`p`,Xe,g(te(c.value?.deleteBytes)),1)]),f(`div`,Ze,[i[5]||=f(`p`,{class:`text-[10px] text-textMuted uppercase tracking-wider`},`将保留`,-1),f(`p`,Qe,g(c.value?.protectFiles??`-`),1),i[6]||=f(`p`,{class:`text-[10px] text-textMuted`},`由 protectPaths 命中`,-1)]),f(`div`,$e,[i[7]||=f(`p`,{class:`text-[10px] text-textMuted uppercase tracking-wider`},`总计文件`,-1),f(`p`,et,g(c.value?.totalFiles??`-`),1),c.value?.truncated?(e(),m(`p`,R,`已截断 10000 行`)):(e(),m(`p`,z,`完整扫描`))])]),y.value.length?(e(),m(`div`,B,[i[8]||=f(`span`,{class:`text-xs text-textMuted shrink-0`},`protectPaths:`,-1),(e(!0),m(u,null,a(y.value,t=>(e(),m(`span`,{key:t,class:`text-[11px] px-2 py-0.5 rounded bg-success/10 border border-success/30 text-success font-mono`},g(t),1))),128))])):h(``,!0),f(`div`,tt,[n.loading?(e(),m(`div`,V,[x(v(T),{class:`w-4 h-4 mr-2 animate-spin`}),i[9]||=b(` 正在扫描部署目录... `,-1)])):n.error?(e(),m(`div`,nt,g(n.error),1)):!l.value||!l.value.children?.length?(e(),m(`div`,rt,` 部署目录为空,无需清理 `)):(e(),_(Ke,{key:3,node:l.value,depth:0,"default-expand":!0},null,8,[`node`]))]),f(`div`,it,[n.preview?.cached?(e(),m(`span`,at,`使用 30s 内缓存结果`)):(e(),m(`span`,ot)),f(`button`,{onClick:ne,class:`px-4 py-2 text-sm font-medium text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5 rounded-md transition-colors`,type:`button`},`关闭`)])],2)])):h(``,!0)]),_:1}))}}),[[`__scopeId`,`data-v-e5333666`]]),ct={key:0,class:`max-w-7xl mx-auto space-y-6 pb-12`,"aria-busy":`true`},lt={key:1,class:`max-w-7xl mx-auto space-y-6 pb-12`},ut={class:`flex items-start gap-3 sm:gap-4 mb-8`},dt={class:`min-w-0 flex-1`},ft={class:`flex items-center flex-wrap gap-2 sm:gap-3`},pt={class:`text-xl sm:text-2xl font-bold text-textMain tracking-tight truncate max-w-full`},mt={class:`text-xs sm:text-sm text-textMuted mt-1 font-mono break-all`},ht={class:`flex flex-wrap items-center gap-1 border-b border-border -mt-2`},gt=[`onClick`],_t={class:`grid grid-cols-1 lg:grid-cols-12 gap-6`},vt={key:0,class:`lg:col-span-12 bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},yt={class:`px-4 py-3 border-b border-border bg-base/40 flex items-center justify-between`},bt={class:`text-sm font-semibold text-textMain flex items-center`},xt={class:`font-mono text-textMain bg-base border border-border px-1.5 py-0.5 rounded ml-2 text-[11px]`},St=[`disabled`],Ct={class:`p-4`},wt={key:0,class:`text-xs text-textMuted`},Tt={key:1,class:`text-xs text-yellow-500 flex items-start gap-1.5`},Et={key:2,class:`text-xs text-yellow-500 flex items-start gap-1.5`},Dt={class:`font-mono text-textMain mx-1`},Ot={key:3,class:`grid grid-cols-2 sm:grid-cols-3 gap-3 text-xs`},kt={class:`flex items-center gap-2`},At={class:`text-textMain font-mono`},jt={class:`flex items-center gap-2`},Mt={class:`text-textMain font-mono`},Nt={class:`flex items-center gap-2`},Pt={class:`text-textMain font-mono`},Ft={class:`flex items-center gap-2`},It={class:`text-textMain font-mono`},Lt={class:`flex items-center gap-2`},Rt={class:`text-textMain font-mono`},zt={class:`flex items-center gap-2`},Bt={class:`text-textMain font-mono`},Vt={class:`flex items-center gap-2`},Ht={class:`text-textMain font-mono`},Ut={key:0,class:`text-danger ml-1`},Wt={class:`lg:col-span-7 bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},Gt={class:`px-4 sm:px-6 py-4 sm:py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02] flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},Kt={class:`text-lg font-semibold text-textMain flex items-center`},qt={class:`flex items-center gap-2`},Jt=[`disabled`],Yt={class:`p-6`},Xt={key:0,class:`py-10 text-center text-sm text-textMuted`},Zt={key:1,class:`py-10 text-center text-sm text-textMuted`},Qt={key:2,class:`divide-y divide-border`},$t=[`onClick`],en={class:`flex items-center gap-2 flex-wrap`},tn={key:0,class:`inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-warning/10 border border-warning/20 text-warning`,title:`该部署是一次回滚`},nn=[`title`,`onClick`,`onKeydown`],rn={key:3,class:`inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-success/10 border border-success/30 text-success`,title:`该版本为当前线上版本`},an={class:`text-xs text-textMuted truncate`},on={key:4,class:`text-xs text-textMuted`},sn=[`onClick`],cn=[`title`],ln={class:`lg:col-span-5 bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},un={class:`px-6 py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02]`},dn={class:`text-lg font-semibold text-textMain flex items-center`},fn={class:`p-6`},pn={class:`flex flex-col sm:flex-row items-stretch sm:items-center space-y-4 sm:space-y-0 sm:space-x-4`},mn={class:`relative flex-1`},hn=[`type`,`value`],gn={class:`flex items-center space-x-2`},_n=[`disabled`],vn={class:`lg:col-span-12 bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},yn=[`aria-expanded`],bn={class:`flex items-center justify-between gap-3`},xn={class:`min-w-0`},Sn={class:`text-lg font-semibold text-textMain flex items-center`},Cn={class:`text-sm text-textMuted mt-1`},wn={class:`p-6 space-y-5`},Tn={class:`rounded-lg border border-primary/20 bg-primary/5 p-4`},En={class:`flex items-center gap-3`},Dn=[`onKeydown`],On=[`disabled`,`title`],kn={class:`text-xs text-textMuted mt-2`},An={class:`font-mono text-textMain`},jn={class:`rounded-lg border border-border bg-base p-4`},Mn={class:`flex items-center gap-2`},Nn={class:`rounded-lg border border-border bg-base p-4`},Pn={class:`flex items-center gap-2 mb-4`},Fn={class:`flex-1 text-xs text-success font-mono break-all`},In={class:`text-xs text-textMuted mb-3`},Ln={class:`font-mono text-textMain bg-panel px-1 py-0.5 rounded border border-border`},Rn={class:`text-xs text-success font-mono whitespace-pre-wrap overflow-x-auto bg-panel rounded-md p-3 border border-border mb-3`},zn={class:`space-y-2 text-xs text-textMuted`},Bn={class:`pl-3 space-y-1`},Vn={class:`text-textMuted w-24 shrink-0`},Hn={class:`text-success font-mono`},Un={class:`grid grid-cols-1 md:grid-cols-2 gap-4`},Wn={class:`rounded-lg border border-border bg-base p-4`},Gn={class:`flex items-center gap-2`},Kn={class:`flex-1 text-xs text-success font-mono break-all`},qn={class:`rounded-lg border border-border bg-base p-4 space-y-3`},Jn={class:`flex items-center gap-2`},Yn={class:`flex-1 text-xs text-success font-mono break-all`},Xn={class:`flex items-center gap-2`},Zn={class:`flex-1 text-xs text-success font-mono break-all`},Qn={class:`rounded-lg border border-primary/20 bg-primary/5 p-4 space-y-3`},$n={class:`space-y-2`},er={class:`flex items-center gap-2`},tr={class:`flex-1 text-xs text-success font-mono break-all bg-base px-2 py-1 rounded border border-border`},nr=[`disabled`,`title`],rr={class:`text-xs text-textMuted pl-[120px] -mt-1`},ir={class:`font-mono`},ar={class:`flex items-center gap-2`},or={class:`flex-1 text-xs text-success font-mono break-all bg-base px-2 py-1 rounded border border-border`},sr=[`disabled`,`title`],cr={class:`flex items-center gap-2`},lr={class:`flex-1 text-xs text-success font-mono break-all bg-base px-2 py-1 rounded border border-border`},ur=[`disabled`,`title`],dr={key:0,class:`text-xs text-yellow-500`},fr={class:`grid grid-cols-1 lg:grid-cols-12 gap-6`},pr={class:`lg:col-span-5 bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},mr={class:`px-6 py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02]`},hr={class:`text-lg font-semibold text-textMain flex items-center`},gr={class:`p-6 space-y-6`},_r=[`value`],vr={class:`pt-4 border-t border-border flex justify-end`},yr=[`disabled`],br={class:`lg:col-span-7 bg-panel border border-border rounded-xl shadow-sm overflow-visible`},xr={class:`px-6 py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02]`},Sr={class:`text-lg font-semibold text-textMain flex items-center`},Cr={class:`p-6 space-y-6`},wr={class:`block text-sm font-medium text-textMain mb-2 flex items-center`},Tr={key:0,class:`ml-2 text-[10px] text-success border border-success/40 bg-success/10 px-1.5 py-0.5 rounded`},Er={key:1,class:`ml-2 text-[10px] text-textMuted border border-border bg-base px-1.5 py-0.5 rounded`},Dr={key:0,class:`relative`,"data-pm2-picker-root":``},Or={key:0,class:`absolute z-50 mt-1 w-full max-h-72 overflow-y-auto bg-panel border border-border rounded-md shadow-lg`},kr=[`onClick`],Ar={class:`flex items-center min-w-0`},jr={key:1,class:`w-3.5 h-3.5 mr-2 shrink-0`},Mr={class:`font-mono truncate`},Nr={class:`flex items-center gap-2 shrink-0 ml-3`},Pr={class:`text-[10px] text-textMuted font-mono`},Fr={key:1},Ir={id:`pm2-apps-suggest`},Lr=[`value`],Rr={key:2,class:`mt-2 flex items-start gap-2 text-xs text-yellow-500 border border-yellow-500/30 bg-yellow-500/5 rounded-md px-3 py-2`},zr={class:`leading-relaxed`},Br={key:0},Vr={class:`pt-4 border-t border-border flex justify-end`},Hr=[`disabled`],Ur={class:`lg:col-span-7 bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},Wr={class:`px-6 py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02]`},Gr={class:`text-lg font-semibold text-textMain flex items-center`},Kr={class:`p-6 space-y-6`},qr={class:`relative`},Jr={class:`relative`},Yr={class:`mt-3 flex items-start space-x-2 cursor-pointer select-none`},Xr={class:`pt-4 border-t border-border flex justify-end`},Zr=[`disabled`],Qr={class:`lg:col-span-5 bg-panel border border-border rounded-xl shadow-sm overflow-hidden`},$r={class:`px-6 py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02]`},ei={class:`text-lg font-semibold text-textMain flex items-center`},ti={class:`p-6 space-y-5`},ni={class:`grid grid-cols-1 md:grid-cols-3 gap-3`},ri=[`value`],ii={class:`text-xs text-textMuted mt-1 leading-relaxed`},ai={key:0},oi={class:`flex gap-2 mb-3`},si=[`onKeydown`],ci={key:0,class:`flex flex-wrap gap-2`},li=[`onClick`],ui={key:1,class:`text-xs text-textMuted italic`},di={key:1,class:`p-3 rounded-md bg-danger/10 border border-danger/30 flex items-start gap-2`},fi={class:`pt-3 border-t border-border flex items-center justify-end gap-3`},pi=[`disabled`],mi={class:`space-y-6`},hi={class:`bg-panel border border-danger/20 rounded-xl shadow-sm overflow-hidden`},gi={class:`px-6 py-4`},_i={class:`text-danger font-medium flex items-center`},vi={class:`bg-panel border border-danger/30 rounded-xl w-full max-w-lg p-6 shadow-2xl`},yi={class:`flex items-start space-x-3 mb-5`},bi={class:`p-2 rounded-lg bg-danger/10 border border-danger/20 shrink-0`},xi={class:`flex-1 min-w-0`},Si={class:`text-sm text-textMuted mt-1`},Ci={class:`font-mono text-textMain`},wi={class:`font-mono text-textMuted`},Ti={class:`space-y-3 mb-5`},Ei={class:`bg-danger/5 border border-danger/20 rounded-lg p-3`},Di={class:`text-xs font-medium text-danger mb-2 flex items-center`},Oi={class:`bg-success/5 border border-success/20 rounded-lg p-3`},ki={class:`text-xs font-medium text-success mb-2 flex items-center`},Ai={class:`text-xs text-textMain/90 space-y-1 list-disc list-inside marker:text-success/60`},ji={class:`font-mono text-textMain bg-base px-1 py-0.5 rounded text-[11px]`},Mi={class:`mb-2`},Ni={class:`block text-sm font-medium text-textMuted mb-1.5`},Pi={class:`font-mono text-textMain`},Fi=[`disabled`,`placeholder`,`onKeydown`],Ii={key:0,class:`text-xs text-danger mt-2`},Li={class:`mt-6 flex justify-end space-x-3`},Ri=[`disabled`],zi=[`disabled`],Bi=`npm install -g @kitecd/cli`,Vi=l({__name:`ProjectDetail`,setup(l){let ne=Ne(),y=Re(),S=te(),C=Fe(),w=ne.params.id,T=d(()=>S.getProjectById(w)),D=o({destPath:``,preDeploy:``,postDeploy:``,postDeployAsync:!1,categoryId:``,pm2AppName:``,tagIds:[]}),k=o({cleanMode:`merge`,protectPaths:[]}),A=o(``),M=o(!1),N=o(!1),We=o(!1),Ge=o(!1),Ke=o(``),qe=o(null),P=o(!1),Je=o(!1),F=o(``),Ye=o(`http://127.0.0.1:3000`),I=o(``),L=o(!1),Xe=o(!1),Ze=d(()=>`kite:cli-help-collapsed:${w}`);function Qe(){try{let e=localStorage.getItem(Ze.value);if(e===`1`||e===`0`){L.value=e===`1`,Xe.value=!0;return}}catch{}Xe.value=!1,L.value=R.value.length>0}function $e(){L.value=!L.value,Xe.value=!0;try{localStorage.setItem(Ze.value,L.value?`1`:`0`)}catch{}}let et=o(!0);n(async()=>{if(Ye.value=window.location.origin,await Promise.all([S.fetchProjects(),S.fetchCategories(),S.fetchTags(),ra()]),T.value){D.value.destPath=T.value.destPath||``,D.value.preDeploy=T.value.preDeploy||``,D.value.postDeploy=T.value.postDeploy||``,D.value.postDeployAsync=!!T.value.postDeployAsync,D.value.categoryId=T.value.categoryId||``,D.value.pm2AppName=T.value.pm2AppName||``,D.value.tagIds=Array.isArray(T.value.tagIds)?[...T.value.tagIds]:[],I.value=T.value.env||``;let e=T.value.cleanMode;k.value.cleanMode=e===`clean`||e===`clean-all`?e:`merge`;let t=T.value.protectPaths;if(typeof t==`string`&&t.length>0)try{let e=JSON.parse(t);k.value.protectPaths=Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}catch{k.value.protectPaths=[]}else k.value.protectPaths=[];et.value=!1,Promise.all([nt(),ia()]).catch(()=>{})}else et.value=!1,y.replace(`/projects`)});let R=o([]),z=o(!1),B=o(!1),tt=o(!1),V=o(null);async function nt(){z.value=!0;try{await S.fetchLogs(),R.value=S.logs.filter(e=>e.projectId===w).slice(0,10)}catch{R.value=[]}finally{z.value=!1,Xe.value||Qe()}}function rt(e){return e?e.slice(0,8):``}let it=o(``);async function at(e,t){if(t&&(t.stopPropagation(),t.preventDefault()),e)try{await navigator.clipboard.writeText(e),it.value=e,C.success(`已复制部署 ID`,rt(e)),setTimeout(()=>{it.value===e&&(it.value=``)},2e3)}catch(e){C.error(`复制失败`,e?.message||`请手动选择文本复制`)}}let ot=d(()=>[...R.value].sort((e,t)=>{let n=new Date(e.startTime).getTime()||0;return(new Date(t.startTime).getTime()||0)-n}).find(e=>e.status===`success`&&e.triggerSource!==`rollback`)?.id||``);function Vi(e){return!e||e.status===`running`||e.triggerSource===`rollback`?!1:!!e.artifactPath}function Hi(e){return e?e.status===`running`?`部署进行中,无法回滚`:e.triggerSource===`rollback`?`回滚记录不可再被回滚`:e.artifactPath?``:`该版本归档已被清理或过早,无法回滚`:``}function Ui(e){Vi(e)&&(V.value=e,B.value=!0)}async function Wi(){let e=V.value?.id;if(e){tt.value=!0;try{let t=await S.rollbackDeployment(e);C.success(`回滚已完成`,`新部署 ${rt(t.deployId)}`),B.value=!1,V.value=null,await nt()}catch(e){C.error(`回滚失败`,e?.message||`未知错误`)}finally{tt.value=!1}}}function Gi(e){e?y.push({path:`/logs`,query:{id:e.id,projectId:w}}):y.push({path:`/logs`,query:{projectId:w}})}function Ki(e){if(!e)return`—`;try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}async function qi(e,t=`配置已保存`){try{return Qi(e),await S.updateProject(w,e),C.success(t),!0}catch(e){let t=e?.data?.conflictProject;return e?.status===409&&t?C.error(`保存失败`,`部署目录已被项目「${t}」占用,请更换目录或修改对方项目`):C.error(`保存失败`,e?.message||`请稍后重试`),!1}}let H=o(!1);async function Ji(){if(!H.value){H.value=!0;try{await qi({categoryId:D.value.categoryId||null,tagIds:[...D.value.tagIds]},`项目基本信息已保存`)}finally{H.value=!1}}}let U=o(!1);async function Yi(){if(!U.value){U.value=!0;try{let e=D.value.pm2AppName.trim()||null,t=(T.value?.pm2AppName||``).trim()||null;await qi({pm2AppName:e},`PM2 应用绑定已保存`)&&(await ia(),e&&e!==t&&await Zi())}finally{U.value=!1}}}let W=o(!1);async function Xi(){if(!W.value){W.value=!0;try{await qi({destPath:D.value.destPath,preDeploy:D.value.preDeploy,postDeploy:D.value.postDeploy,postDeployAsync:D.value.postDeployAsync},`部署脚本已保存`)}finally{W.value=!1}}}async function Zi(){try{let e=await S.fetchProjectPm2(w);if(!e||e.found!==!0)return;let t=[];if(e.outLogPath&&t.push({path:e.outLogPath,kind:`stdout`}),e.errorLogPath&&t.push({path:e.errorLogPath,kind:`stderr`}),t.length===0)return;let n=await S.fetchLogSources(w),r=new Set((n?.items||[]).map(e=>e.filePath)),i=t.filter(e=>!r.has(e.path));if(i.length===0)return;let a=D.value.pm2AppName.trim()||`pm2`,ee=i.map(e=>({filePath:e.path,label:`${a} · ${e.kind}`,kind:`pm2`})),o=await S.createLogSources(w,ee),s=Array.isArray(o?.created)?o.created:[];s.length>0&&C.success(`已自动导入 ${s.length} 个 PM2 日志源`,`可在「运行日志」页面查看`)}catch{}}function Qi(e){let t=T.value;t&&(e.destPath!==void 0&&(t.destPath=e.destPath,t.deployPath=e.destPath),e.preDeploy!==void 0&&(t.preDeploy=e.preDeploy,t.preDeployScript=e.preDeploy),e.postDeploy!==void 0&&(t.postDeploy=e.postDeploy,t.postDeployScript=e.postDeploy),e.postDeployAsync!==void 0&&(t.postDeployAsync=!!e.postDeployAsync),e.categoryId!==void 0&&(t.categoryId=e.categoryId),e.env!==void 0&&(t.env=e.env),e.pm2AppName!==void 0&&(t.pm2AppName=e.pm2AppName),e.tagIds!==void 0&&(t.tagIds=Array.isArray(e.tagIds)?[...e.tagIds]:[]),e.cleanMode!==void 0&&(t.cleanMode=e.cleanMode),e.protectPaths!==void 0&&(t.protectPaths=Array.isArray(e.protectPaths)&&e.protectPaths.length?JSON.stringify(e.protectPaths):null),e.name!==void 0&&(t.name=e.name))}let $i=o(!1),ea=d(()=>I.value.trim()!==(T.value?.env||``));async function ta(){if(!(!ea.value||$i.value)){$i.value=!0;try{let e={env:I.value.trim()};Qi(e),await S.updateProject(w,e),C.success(`部署环境已保存`)}catch(e){C.error(`保存失败`,e?.message||`请稍后重试`)}finally{$i.value=!1}}}let G=o(!1),K=o([]),q=o(null),na=o(!1);async function ra(){try{if(G.value=await S.fetchPm2Available(),G.value)try{let e=await S.fetchPm2Apps();K.value=Array.isArray(e)?e.filter(e=>e.name):[]}catch{K.value=[]}}catch{G.value=!1}}async function ia(){if(!D.value.pm2AppName.trim()){q.value=null;return}na.value=!0;try{q.value=await S.fetchProjectPm2(w)}finally{na.value=!1}}ve(async()=>{D.value.pm2AppName.trim()&&await ia()},5e3);let J=o(!1),aa=o(!1);function oa(){J.value=!J.value}function sa(){J.value=!1}function ca(e){D.value.pm2AppName=e,aa.value=!1,sa()}function la(){aa.value=!0,sa()}let ua=d(()=>G.value&&K.value.length>0&&!aa.value),da=d(()=>{let e=D.value.pm2AppName.trim();return e?S.projects.filter(t=>t.id!==w&&(t.pm2AppName||``).trim()===e):[]});function fa(e){if(!J.value)return;let t=e.target;t&&t.closest(`[data-pm2-picker-root]`)||sa()}n(()=>{document.addEventListener(`click`,fa)}),r(()=>{document.removeEventListener(`click`,fa)});function pa(e){if(e==null||isNaN(e))return`—`;let t=1024;return e<t?`${e} B`:e<t*t?`${(e/t).toFixed(1)} KB`:e<t*t*t?`${(e/t/t).toFixed(1)} MB`:`${(e/t/t/t).toFixed(2)} GB`}function ma(e){if(e==null||e<0)return`—`;let t=Math.floor(e/1e3),n=Math.floor(t/86400),r=Math.floor(t%86400/3600),i=Math.floor(t%3600/60);return n>0?`${n}d ${r}h`:r>0?`${r}h ${i}m`:i>0?`${i}m`:`${t}s`}function ha(){let e=A.value.trim();if(e){if(k.value.protectPaths.includes(e)){A.value=``;return}k.value.protectPaths.push(e),A.value=``}}function ga(e){k.value.protectPaths=k.value.protectPaths.filter(t=>t!==e)}async function _a(){M.value=!0;try{let e={cleanMode:k.value.cleanMode,protectPaths:k.value.protectPaths.length?k.value.protectPaths:null};Qi(e),await S.updateProject(w,e),C.success(`清理策略已保存`,k.value.cleanMode===`merge`?`将沿用合并模式(零破坏)`:`下次部署会按 ${k.value.cleanMode} 执行`)}catch(e){C.error(`保存失败`,e?.message)}finally{M.value=!1,N.value=!1}}async function va(){if(k.value.cleanMode===`clean-all`){N.value=!0;return}await _a()}async function ya(){if(k.value.cleanMode===`merge`){C.info(`merge 模式不会删除任何文件,无需预览`);return}We.value=!0,Ge.value=!0,Ke.value=``,qe.value=null;try{qe.value=await S.cleanPreview(w,{cleanMode:k.value.cleanMode,protectPaths:k.value.protectPaths})}catch(e){Ke.value=e?.message||`预览失败`}finally{Ge.value=!1}}let ba=()=>{T.value?.token&&(navigator.clipboard.writeText(T.value.token),Je.value=!0,setTimeout(()=>Je.value=!1,2e3))},xa=e=>{try{let t=document.createElement(`textarea`);t.value=e,t.setAttribute(`readonly`,``),t.style.position=`fixed`,t.style.top=`0`,t.style.left=`0`,t.style.opacity=`0`,document.body.appendChild(t),t.focus(),t.select();let n=document.execCommand(`copy`);return document.body.removeChild(t),n}catch{return!1}},Y=(e,t)=>{if(!t)return;let n=()=>{F.value=e,setTimeout(()=>F.value=``,2e3)};if(xa(t)){n();return}navigator.clipboard&&window.isSecureContext?navigator.clipboard.writeText(t).then(n).catch(()=>{window.prompt(`请手动复制以下内容(Ctrl/Cmd + C):`,t)}):window.prompt(`请手动复制以下内容(Ctrl/Cmd + C):`,t)},Sa=d(()=>I.value.trim()?` --env ${I.value.trim()}`:``),Ca=d(()=>I.value.trim()?`kite.config.${I.value.trim()}.json`:`kite.config.json`),wa=d(()=>`kite init --project ${w}${Sa.value} --out ./dist --server ${Ye.value} --token ${T.value?.token||`<DEPLOY_TOKEN>`}`),Ta=d(()=>`kite push${Sa.value}`),Ea=d(()=>`kite push --server ${Ye.value} --project ${w}${Sa.value} --out ./dist`),Da=d(()=>`kite push --server ${Ye.value} --project ${w} --token ${T.value?.token||`<DEPLOY_TOKEN>`}${Sa.value} --out ./dist`),Oa=d(()=>T.value?.token||`<DEPLOY_TOKEN>`),ka=d(()=>I.value.trim()?`kite config:set token ${Oa.value} --env ${I.value.trim()}`:`kite config:set token ${Oa.value}`),Aa=d(()=>`kite config:set token ${Oa.value} --global`),ja=d(()=>`KITE_DEPLOY_TOKEN=${Oa.value}`),Ma=d(()=>JSON.stringify({projectId:w,outputDir:`./dist`,files:[`**/*`],postDeploy:T.value?.postDeploy||`pm2 restart your-service`},null,2)),Na=[{label:`打包所有文件`,files:[`**/*`]},{label:`只上传 dist 目录`,files:[`dist/**/*`]},{label:`指定多个目录`,files:[`dist/**/*`,`public/**/*`]},{label:`单个文件`,files:[`index.html`]},{label:`混合配置`,files:[`dist/**/*`,`server.js`,`config/*.json`]}],Pa=o(!1),Fa=o(!1),Ia=()=>{Pa.value=!0},La=async()=>{Fa.value=!0;try{await S.generateToken(w),P.value=!0,Pa.value=!1,C.success(`Token 已重新生成`,`旧 Token 已立即失效`)}catch(e){C.error(`Token 重置失败`,e?.message)}finally{Fa.value=!1}},Ra=o(!1),za=o(``),X=o(!1),Z=o(``),Q=d(()=>T.value?.name?.trim()||``),Ba=d(()=>!X.value&&Q.value.length>0&&za.value.trim()===Q.value);function Va(){za.value=``,Z.value=``,X.value=!1,Ra.value=!0}function Ha(){X.value||(Ra.value=!1,za.value=``,Z.value=``)}async function Ua(){if(Ba.value){X.value=!0,Z.value=``;try{await S.removeProject(w)?(Ra.value=!1,y.replace(`/projects`)):Z.value=`删除失败,请稍后重试`}catch(e){Z.value=e?.message||`删除失败,请稍后重试`}finally{X.value=!1}}}let Wa=d(()=>`kite:project-detail-tab:${w}`),$=o(`overview`),Ga=[{key:`overview`,label:`概览`,icon:Ce},{key:`config`,label:`配置`,icon:Ue},{key:`integration`,label:`危险区`,icon:Ve}];n(()=>{try{let e=localStorage.getItem(Wa.value);(e===`overview`||e===`config`||e===`integration`)&&($.value=e)}catch{}});function Ka(e){$.value=e;try{localStorage.setItem(Wa.value,e)}catch{}}return(n,r)=>{let o=ee(`router-link`);return et.value?(e(),m(`div`,ct,[...r[28]||=[c(`<div class="flex items-start gap-3 sm:gap-4 mb-8 animate-pulse"><div class="w-9 h-9 rounded-full bg-border/40 shrink-0"></div><div class="min-w-0 flex-1 space-y-3"><div class="flex items-center flex-wrap gap-2 sm:gap-3"><div class="h-7 w-48 rounded-md bg-border/40"></div><div class="h-5 w-16 rounded-md bg-border/30"></div><div class="h-7 w-24 rounded-md bg-border/30"></div><div class="h-7 w-24 rounded-md bg-border/30"></div><div class="h-7 w-24 rounded-md bg-border/30"></div></div><div class="h-3 w-72 rounded bg-border/30"></div></div></div><div class="flex flex-wrap items-center gap-1 border-b border-border -mt-2 animate-pulse"><div class="h-9 w-24 rounded-t-md bg-border/30 mr-2"></div><div class="h-9 w-24 rounded-t-md bg-border/20 mr-2"></div><div class="h-9 w-20 rounded-t-md bg-border/20"></div></div><div class="grid grid-cols-1 lg:grid-cols-12 gap-6 animate-pulse"><div class="lg:col-span-7 h-72 rounded-xl bg-panel border border-border"></div><div class="lg:col-span-5 h-72 rounded-xl bg-panel border border-border"></div><div class="lg:col-span-12 h-48 rounded-xl bg-panel border border-border"></div></div>`,3)]])):T.value?(e(),m(`div`,lt,[f(`div`,ut,[f(`button`,{onClick:r[0]||=e=>v(y).back(),class:`p-2 dark:hover:bg-white/10 hover:bg-black/10 rounded-full transition-colors text-textMuted hover:text-textMain shrink-0`},[x(v(ce),{class:`w-5 h-5`})]),f(`div`,dt,[f(`div`,ft,[f(`h1`,pt,g(T.value.name),1),f(`span`,{class:p([`px-2.5 py-0.5 text-xs rounded-md border shrink-0`,T.value.status===`success`?`bg-success/10 border-success/20 text-success`:`bg-primary/10 border-primary/20 text-primary`])},g(T.value.status),3),x(o,{to:`/projects/${v(w)}/files`,class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-base border border-border hover:border-primary/50 hover:text-primary text-textMuted rounded-md transition-all`},{default:t(()=>[x(v(be),{class:`w-3.5 h-3.5 mr-1.5`}),r[29]||=b(` 查看文件 `,-1)]),_:1},8,[`to`]),x(o,{to:`/projects/${v(w)}/logs`,class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-base border border-border hover:border-primary/50 hover:text-primary text-textMuted rounded-md transition-all`},{default:t(()=>[x(v(me),{class:`w-3.5 h-3.5 mr-1.5`}),r[30]||=b(` 运行日志 `,-1)]),_:1},8,[`to`]),x(o,{to:`/audit?targetId=${v(w)}`,class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-base border border-border hover:border-primary/50 hover:text-primary text-textMuted rounded-md transition-all`},{default:t(()=>[x(v(Ee),{class:`w-3.5 h-3.5 mr-1.5`}),r[31]||=b(` 操作历史 `,-1)]),_:1},8,[`to`]),x(o,{to:`/terminal?projectId=${v(w)}`,class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-base border border-border hover:border-primary/50 hover:text-primary text-textMuted rounded-md transition-all`},{default:t(()=>[x(v(we),{class:`w-3.5 h-3.5 mr-1.5`}),r[32]||=b(` 打开终端 `,-1)]),_:1},8,[`to`])]),f(`p`,mt,g(T.value.id),1)])]),f(`nav`,ht,[(e(),m(u,null,a(Ga,t=>f(`button`,{key:t.key,type:`button`,onClick:e=>Ka(t.key),class:p([`inline-flex items-center px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors`,$.value===t.key?`border-primary text-primary`:`border-transparent text-textMuted hover:text-textMain hover:border-border`])},[(e(),_(i(t.icon),{class:`w-4 h-4 mr-1.5`})),b(` `+g(t.label),1)],10,gt)),64))]),s(f(`section`,_t,[(T.value.pm2AppName||``).trim()?(e(),m(`div`,vt,[f(`div`,yt,[f(`h3`,bt,[x(v(re),{class:`w-4 h-4 mr-2 text-primary`}),r[33]||=b(` PM2 应用状态 `,-1),f(`code`,xt,g(T.value.pm2AppName),1),r[34]||=f(`span`,{class:`ml-2 text-[10px] text-textMuted`},`每 5 秒自动刷新`,-1)]),f(`button`,{onClick:ia,disabled:na.value,class:`text-textMuted hover:text-textMain text-xs flex items-center disabled:opacity-50`},[x(v(E),{class:p([`w-3 h-3 mr-1`,na.value?`animate-spin`:``])},null,8,[`class`]),r[35]||=b(` 刷新 `,-1)],8,St)]),f(`div`,Ct,[q.value?G.value?q.value.found===!1?(e(),m(`div`,Et,[x(v(Me),{class:`w-3.5 h-3.5 mt-0.5 shrink-0`}),r[36]||=b(` 未在 PM2 中找到名为 `,-1),f(`code`,Dt,g(T.value.pm2AppName),1),r[37]||=b(` 的应用。请确认 `,-1),r[38]||=f(`code`,{class:`font-mono text-textMain mx-1`},`pm2 list`,-1),r[39]||=b(` 中存在该应用名。 `,-1)])):(e(),m(`div`,Ot,[f(`div`,kt,[f(`span`,{class:p([`w-2 h-2 rounded-full`,q.value.status===`online`?`bg-success`:`bg-danger`])},null,2),r[40]||=f(`span`,{class:`text-textMuted`},`状态`,-1),f(`span`,At,g(q.value.status||`—`),1)]),f(`div`,jt,[x(v(_e),{class:`w-3.5 h-3.5 text-textMuted`}),r[41]||=f(`span`,{class:`text-textMuted`},`CPU`,-1),f(`span`,Mt,g(q.value.cpuPercent==null?`—`:q.value.cpuPercent.toFixed(1)+`%`),1)]),f(`div`,Nt,[x(v(ge),{class:`w-3.5 h-3.5 text-textMuted`}),r[42]||=f(`span`,{class:`text-textMuted`},`内存`,-1),f(`span`,Pt,g(pa(q.value.memoryBytes)),1)]),f(`div`,Ft,[r[43]||=f(`span`,{class:`text-textMuted`},`PID`,-1),f(`span`,It,g(q.value.pid??`—`),1)]),f(`div`,Lt,[r[44]||=f(`span`,{class:`text-textMuted`},`实例`,-1),f(`span`,Rt,g(q.value.instances??1)+` (`+g(q.value.execMode||`—`)+`)`,1)]),f(`div`,zt,[r[45]||=f(`span`,{class:`text-textMuted`},`运行时长`,-1),f(`span`,Bt,g(ma(q.value.uptimeMs)),1)]),f(`div`,Vt,[r[46]||=f(`span`,{class:`text-textMuted`},`重启次数`,-1),f(`span`,Ht,[b(g(q.value.restarts??0),1),q.value.unstableRestarts?(e(),m(`span`,Ut,`(不稳定 `+g(q.value.unstableRestarts)+`)`,1)):h(``,!0)])])])):(e(),m(`div`,Tt,[x(v(Me),{class:`w-3.5 h-3.5 mt-0.5 shrink-0`}),b(` `+g(q.value.message||`服务器未检测到 PM2,无法读取应用状态。`),1)])):(e(),m(`div`,wt,g(na.value?`正在拉取…`:`尚未获取到状态`),1))])])):h(``,!0),f(`div`,Wt,[f(`div`,Gt,[f(`div`,null,[f(`h2`,Kt,[x(v(pe),{class:`w-5 h-5 mr-2 text-primary`}),r[47]||=b(` 部署历史 `,-1)]),r[48]||=f(`p`,{class:`text-sm text-textMuted mt-1`},`最近 10 次部署。点击行查看完整日志,行末可对已归档版本一键回滚。`,-1)]),f(`div`,qt,[f(`button`,{onClick:nt,disabled:z.value,class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-base border border-border hover:border-primary/50 hover:text-primary text-textMuted rounded-md transition-all disabled:opacity-50`},[x(v(E),{class:p([`w-3.5 h-3.5 mr-1.5`,{"animate-spin":z.value}])},null,8,[`class`]),r[49]||=b(` 刷新 `,-1)],8,Jt),f(`button`,{onClick:r[1]||=e=>Gi(),class:`inline-flex items-center px-3 py-1.5 text-xs font-medium bg-base border border-border hover:border-primary/50 hover:text-primary text-textMuted rounded-md transition-all`},[x(v(Ee),{class:`w-3.5 h-3.5 mr-1.5`}),r[50]||=b(` 查看全部 `,-1)])])]),f(`div`,Yt,[z.value&&R.value.length===0?(e(),m(`div`,Xt,` 加载中… `)):R.value.length===0?(e(),m(`div`,Zt,` 该项目暂无部署记录。 `)):(e(),m(`ul`,Qt,[(e(!0),m(u,null,a(R.value,t=>(e(),m(`li`,{key:t.id,class:`flex items-center gap-3 py-3 hover:bg-black/[0.02] dark:hover:bg-white/[0.02] -mx-2 px-2 rounded-md transition-colors`},[f(`button`,{onClick:e=>Gi(t),class:`flex-1 min-w-0 text-left`},[f(`div`,en,[f(`span`,{class:p([`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium border`,{"bg-success/10 border-success/20 text-success":t.status===`success`,"bg-danger/10 border-danger/20 text-danger":t.status===`failed`,"bg-primary/10 border-primary/20 text-primary":t.status===`running`}])},g(t.status),3),t.triggerSource===`rollback`?(e(),m(`span`,tn,` RB `)):h(``,!0),t.artifactPath?(e(),_(v(se),{key:1,class:`w-3.5 h-3.5 text-success/70`,"aria-label":`已归档`})):(e(),_(v(ae),{key:2,class:`w-3.5 h-3.5 text-textMuted/50`,"aria-label":`无归档`})),f(`span`,{role:`button`,tabindex:`0`,class:`inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-base border border-border font-mono text-[10px] text-textMuted hover:text-primary hover:border-primary/40 transition-colors cursor-pointer`,title:`点击复制完整 ID: ${t.id}`,onClick:j(e=>at(t.id,e),[`stop`,`prevent`]),onKeydown:ze(j(e=>at(t.id,e),[`stop`,`prevent`]),[`enter`])},[it.value===t.id?(e(),_(v(ie),{key:0,class:`w-3 h-3 text-success`})):(e(),_(v(he),{key:1,class:`w-3 h-3`})),b(` `+g(rt(t.id)),1)],40,nn),t.id===ot.value?(e(),m(`span`,rn,`当前版本`)):h(``,!0),r[51]||=f(`span`,{class:`text-xs text-textMuted`},`·`,-1),f(`span`,an,g(Ki(t.startTime)),1),t.duration?(e(),m(`span`,on,`· `+g(t.duration),1)):h(``,!0)])],8,$t),Vi(t)?(e(),m(`button`,{key:0,onClick:j(e=>Ui(t),[`stop`]),class:`inline-flex items-center px-2.5 py-1 text-xs font-medium bg-warning/10 text-warning border border-warning/20 hover:bg-warning hover:text-white rounded-md transition-all`},[x(v(oe),{class:`w-3 h-3 mr-1`}),r[52]||=b(` 回滚到此版本 `,-1)],8,sn)):(e(),m(`span`,{key:1,class:`inline-flex items-center px-2.5 py-1 text-xs font-medium bg-base text-textMuted/60 border border-border rounded-md cursor-not-allowed`,title:Hi(t)},` 不可回滚 `,8,cn))]))),128))]))])]),f(`div`,ln,[f(`div`,un,[f(`h2`,dn,[x(v(xe),{class:`w-5 h-5 mr-2 text-primary`}),r[53]||=b(` 鉴权 Token 管理 `,-1)]),r[54]||=f(`p`,{class:`text-sm text-textMuted mt-1`},`用于 CLI 或 Webhook 触发自动化部署的专属凭证。`,-1)]),f(`div`,fn,[f(`div`,pn,[f(`div`,mn,[f(`input`,{type:P.value?`text`:`password`,readonly:``,value:T.value.token||`暂无 Token,请生成`,class:p([`w-full bg-base border border-border rounded-md pl-4 pr-12 py-3 text-textMain font-mono text-sm focus:outline-none focus:border-primary/50 transition-colors`,{"opacity-50 blur-[2px] select-none":!P.value&&T.value.token}])},null,10,hn),T.value.token?(e(),m(`button`,{key:0,onClick:r[2]||=e=>P.value=!P.value,class:`absolute right-3 top-1/2 -translate-y-1/2 text-textMuted hover:text-textMain text-xs font-medium px-2 py-1 rounded transition-colors`},g(P.value?`隐藏`:`显示`),1)):h(``,!0)]),f(`div`,gn,[f(`button`,{onClick:ba,disabled:!T.value.token,class:`flex items-center justify-center px-4 py-3 bg-base border border-border hover:border-primary/50 hover:text-primary text-textMain rounded-md transition-all disabled:opacity-50 disabled:cursor-not-allowed w-full sm:w-auto`},[Je.value?(e(),_(v(Le),{key:0,class:`w-4 h-4 mr-2 text-success`})):(e(),_(v(he),{key:1,class:`w-4 h-4 mr-2`})),b(` `+g(Je.value?`已复制`:`复制`),1)],8,_n),f(`button`,{onClick:Ia,class:`flex items-center justify-center px-4 py-3 bg-primary/10 text-primary border border-primary/20 hover:bg-primary hover:text-white rounded-md transition-all w-full sm:w-auto font-medium shadow-[0_0_10px_rgba(59,130,246,0.1)] hover:shadow-[0_0_15px_rgba(59,130,246,0.4)]`},[x(v(E),{class:`w-4 h-4 mr-2`}),r[55]||=b(` 重新生成 `,-1)])])]),r[56]||=f(`div`,{class:`mt-4 p-4 rounded-md bg-primary/5 border border-primary/10 text-sm`},[f(`p`,{class:`text-textMuted leading-relaxed`},[f(`strong`,{class:`text-primary font-medium`},`CLI 用法:`),b(` 将此 Token 保存到全局配置后,`),f(`code`,{class:`bg-base px-1 py-0.5 rounded font-mono text-xs text-textMain border border-border`},`kite push`),b(` 时无需再传。 `)])],-1)])]),f(`div`,vn,[f(`div`,{class:p([`px-6 py-5 border-b border-border dark:bg-white/[0.02] bg-black/[0.02] cursor-pointer select-none hover:bg-black/[0.04] dark:hover:bg-white/[0.04] transition-colors`,{"border-b-0":L.value}]),onClick:$e,role:`button`,"aria-expanded":!L.value},[f(`div`,bn,[f(`div`,xn,[f(`h2`,Sn,[x(v(we),{class:`w-5 h-5 mr-2 text-primary`}),r[57]||=b(` CLI 快速部署指引 `,-1)]),f(`p`,Cn,[L.value&&R.value.length>0?(e(),m(u,{key:0},[b(` 已有部署记录,指引已折叠 — 点击展开 `)],64)):(e(),m(u,{key:1},[b(` 三步完成部署:安装 CLI、初始化配置、推送部署。 `)],64))])]),(e(),_(i(L.value?v(fe):v(de)),{class:`w-5 h-5 text-textMuted shrink-0`}))])],10,yn),s(f(`div`,wn,[f(`div`,Tn,[r[63]||=f(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`部署环境 (可选)`,-1),f(`div`,En,[s(f(`input`,{"onUpdate:modelValue":r[3]||=e=>I.value=e,type:`text`,class:`flex-1 bg-base border border-border rounded-md px-3 py-2 text-textMain font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all`,placeholder:`留空为默认环境,或输入如 test、staging、prod`,onKeydown:ze(j(ta,[`prevent`]),[`enter`])},null,40,Dn),[[O,I.value]]),f(`button`,{onClick:ta,disabled:!ea.value||$i.value,class:`flex items-center px-3 py-2 bg-primary text-white rounded-md text-sm font-medium hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,title:ea.value?`保存当前部署环境`:`当前值未变化`},[$i.value?(e(),_(v(E),{key:0,class:`w-3.5 h-3.5 mr-1.5 animate-spin`})):(e(),_(v(Se),{key:1,class:`w-3.5 h-3.5 mr-1.5`})),r[58]||=b(` 保存 `,-1)],8,On)]),f(`p`,kn,[r[59]||=b(` 填写后下方所有指令将自动带上 `,-1),r[60]||=f(`code`,{class:`font-mono text-textMain`},`--env`,-1),r[61]||=b(` 参数,生成的配置文件为 `,-1),f(`code`,An,g(Ca.value),1),r[62]||=b(`。 适用于同一项目需要部署到不同环境(测试/预发/生产)的场景。 `,-1)])]),f(`div`,jn,[r[64]||=f(`p`,{class:`text-sm font-medium text-textMain mb-2`},`1. 安装 CLI`,-1),f(`div`,Mn,[f(`code`,{class:`flex-1 text-xs text-success font-mono break-all`},g(Bi)),f(`button`,{onClick:r[4]||=e=>Y(`install`,Bi),class:`text-xs text-primary hover:text-textMain`},g(F.value===`install`?`已复制`:`复制`),1)])]),f(`div`,Nn,[r[71]||=f(`p`,{class:`text-sm font-medium text-textMain mb-2`},`2. 初始化项目配置`,-1),f(`div`,Pn,[f(`code`,Fn,g(wa.value),1),f(`button`,{onClick:r[5]||=e=>Y(`init`,wa.value),class:`text-xs text-primary hover:text-textMain`},g(F.value===`init`?`已复制`:`复制`),1)]),f(`p`,In,[r[65]||=b(`执行后会在当前目录生成 `,-1),f(`code`,Ln,g(Ca.value),1),r[66]||=b(`,请确认生成的配置:`,-1)]),f(`pre`,Rn,g(Ma.value),1),f(`div`,zn,[r[67]||=f(`p`,null,[f(`code`,{class:`font-mono text-textMain`},`projectId`),b(` — 项目唯一标识,由服务端分配`)],-1),r[68]||=f(`p`,null,[f(`code`,{class:`font-mono text-textMain`},`outputDir`),b(` — 本地打包输出目录,默认 `),f(`code`,{class:`font-mono`},`./dist`)],-1),r[69]||=f(`p`,null,[f(`code`,{class:`font-mono text-textMain`},`files`),b(` — 要打包上传的文件 glob 模式列表,示例:`)],-1),f(`div`,Bn,[(e(),m(u,null,a(Na,e=>f(`div`,{key:e.label,class:`flex items-center gap-2`},[f(`span`,Vn,g(e.label),1),f(`code`,Hn,`"files": `+g(JSON.stringify(e.files)),1)])),64))]),r[70]||=f(`p`,null,[f(`code`,{class:`font-mono text-textMain`},`postDeploy`),b(` — 服务端解压后执行的命令,如重启服务`)],-1)])]),f(`div`,Un,[f(`div`,Wn,[r[72]||=f(`p`,{class:`text-sm font-medium text-textMain mb-2`},`3. 部署 — 使用已保存的配置`,-1),f(`div`,Gn,[f(`code`,Kn,g(Ta.value),1),f(`button`,{onClick:r[6]||=e=>Y(`push`,Ta.value),class:`text-xs text-primary hover:text-textMain`},g(F.value===`push`?`已复制`:`复制`),1)]),r[73]||=f(`p`,{class:`text-xs text-textMuted mt-2`},[b(`需先通过 `),f(`code`,{class:`font-mono`},`kite config:set token`),b(` 或 `),f(`code`,{class:`font-mono`},`--token-store global`),b(` 保存过 Token。`)],-1)]),f(`div`,qn,[r[76]||=f(`p`,{class:`text-sm font-medium text-textMain mb-2`},`3. 部署 — CLI 覆盖配置`,-1),f(`div`,Jn,[r[74]||=f(`span`,{class:`text-xs text-textMuted w-20 shrink-0`},`使用全局 Token`,-1),f(`code`,Yn,g(Ea.value),1),f(`button`,{onClick:r[7]||=e=>Y(`direct-push`,Ea.value),class:`text-xs text-primary hover:text-textMain`},g(F.value===`direct-push`?`已复制`:`复制`),1)]),f(`div`,Xn,[r[75]||=f(`span`,{class:`text-xs text-textMuted w-20 shrink-0`},`指定项目 Token`,-1),f(`code`,Zn,g(Da.value),1),f(`button`,{onClick:r[8]||=e=>Y(`direct-push-token`,Da.value),class:`text-xs text-primary hover:text-textMain`},g(F.value===`direct-push-token`?`已复制`:`复制`),1)])])]),f(`div`,Qn,[r[84]||=f(`p`,{class:`text-sm text-textMain leading-relaxed`},[f(`strong`,{class:`text-primary font-medium`},`Token 设置方式`),f(`span`,{class:`text-textMuted`},`(已自动填充本项目 Token,可一键复制):`)],-1),f(`div`,$n,[f(`div`,er,[r[77]||=f(`span`,{class:`text-xs text-textMuted w-28 shrink-0`},`按项目保存`,-1),f(`code`,tr,g(ka.value),1),f(`button`,{onClick:r[9]||=e=>Y(`token-set-project`,ka.value),disabled:!T.value?.token,class:`text-xs text-primary hover:text-textMain disabled:opacity-40 disabled:cursor-not-allowed shrink-0`,title:T.value?.token?`复制命令`:`请先生成 Token`},g(F.value===`token-set-project`?`已复制`:`复制`),9,nr)]),f(`p`,rr,[r[78]||=b(`需在含 `,-1),f(`code`,ir,g(Ca.value),1),r[79]||=b(` 的目录执行,token 会写入 `,-1),r[80]||=f(`code`,{class:`font-mono`},`~/.kite/config.json`,-1),r[81]||=b(` 的项目命名空间。`,-1)]),f(`div`,ar,[r[82]||=f(`span`,{class:`text-xs text-textMuted w-28 shrink-0`},`全局 fallback`,-1),f(`code`,or,g(Aa.value),1),f(`button`,{onClick:r[10]||=e=>Y(`token-set-global`,Aa.value),disabled:!T.value?.token,class:`text-xs text-primary hover:text-textMain disabled:opacity-40 disabled:cursor-not-allowed shrink-0`,title:T.value?.token?`复制命令`:`请先生成 Token`},g(F.value===`token-set-global`?`已复制`:`复制`),9,sr)]),f(`div`,cr,[r[83]||=f(`span`,{class:`text-xs text-textMuted w-28 shrink-0`},`.env.local`,-1),f(`code`,lr,g(ja.value),1),f(`button`,{onClick:r[11]||=e=>Y(`token-env-local`,ja.value),disabled:!T.value?.token,class:`text-xs text-primary hover:text-textMain disabled:opacity-40 disabled:cursor-not-allowed shrink-0`,title:T.value?.token?`复制 .env.local 行`:`请先生成 Token`},g(F.value===`token-env-local`?`已复制`:`复制`),9,ur)])]),T.value?.token?h(``,!0):(e(),m(`p`,dr,` 当前项目尚未生成 Token,请先在上方「项目 Token」区域生成后再复制。 `)),r[85]||=c(`<p class="text-sm text-textMuted leading-relaxed"> 配置优先级:<strong class="text-primary">CLI 参数</strong> &gt; <strong class="text-primary">.env.local</strong> &gt; <strong class="text-primary">项目级 Token</strong> &gt; <strong class="text-primary">全局 Token</strong>。未在 CLI 传入的部署脚本,会回退到本页保存的云端默认脚本。 </p>`,1)])],512),[[ke,!L.value]])])],512),[[ke,$.value===`overview`]]),s(f(`section`,fr,[f(`div`,pr,[f(`div`,mr,[f(`h2`,hr,[x(v(me),{class:`w-5 h-5 mr-2 text-primary`}),r[86]||=b(` 项目基本信息 `,-1)]),r[87]||=f(`p`,{class:`text-sm text-textMuted mt-1`},`项目的分类与标签,用于在项目列表中筛选与归档。`,-1)]),f(`div`,gr,[f(`div`,null,[r[89]||=f(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`所属分类`,-1),s(f(`select`,{"onUpdate:modelValue":r[12]||=e=>D.value.categoryId=e,class:`w-full bg-base border border-border rounded-md px-4 py-3 text-textMain text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all`},[r[88]||=f(`option`,{value:``},`默认(未分类)`,-1),(e(!0),m(u,null,a(v(S).categories,t=>(e(),m(`option`,{key:t.id,value:t.id},g(t.name),9,_r))),128))],512),[[je,D.value.categoryId]]),r[90]||=f(`p`,{class:`text-xs text-textMuted mt-2`},`用于在项目列表中按分类筛选。在「项目管理 → 管理分类」中创建更多分类。`,-1)]),f(`div`,null,[r[91]||=f(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`标签(可多选)`,-1),x(De,{"model-value":D.value.tagIds,size:`md`,"read-only-save":``,"aria-label":`编辑当前项目的标签`,"onUpdate:modelValue":r[13]||=e=>D.value.tagIds=e},null,8,[`model-value`]),r[92]||=f(`p`,{class:`text-xs text-textMuted mt-2`},`点击「+ 标签」选择或直接新建;颜色和排序请在「项目管理 → 管理标签」里调整。`,-1)]),f(`div`,vr,[f(`button`,{onClick:Ji,disabled:H.value,class:`flex items-center px-5 py-2 text-sm bg-primary hover:bg-primary/90 text-white rounded-md transition-all font-medium disabled:opacity-50`},[H.value?(e(),_(v(E),{key:0,class:`w-4 h-4 mr-2 animate-spin`})):(e(),_(v(Se),{key:1,class:`w-4 h-4 mr-2`})),b(` `+g(H.value?`保存中...`:`保存基本信息`),1)],8,yr)])])]),f(`div`,br,[f(`div`,xr,[f(`h2`,Sr,[x(v(re),{class:`w-5 h-5 mr-2 text-primary`}),r[93]||=b(` PM2 应用绑定 `,-1)]),r[94]||=f(`p`,{class:`text-sm text-textMuted mt-1`},`将本项目关联到一个 PM2 应用,启用顶部实时资源监控与状态面板;保存后会自动尝试导入该应用的 stdout / stderr 日志源。`,-1)]),f(`div`,Cr,[f(`div`,null,[f(`label`,wr,[r[95]||=b(` PM2 应用名(可选) `,-1),G.value?(e(),m(`span`,Tr,`PM2 已检测`)):(e(),m(`span`,Er,`PM2 未检测`))]),ua.value?(e(),m(`div`,Dr,[f(`button`,{type:`button`,onClick:j(oa,[`stop`]),class:`w-full flex items-center justify-between bg-base border border-border rounded-md px-4 py-3 text-textMain font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all`},[f(`span`,{class:p(D.value.pm2AppName.trim()?`text-textMain`:`text-textMuted font-sans`)},g(D.value.pm2AppName.trim()||`从 pm2 list 选择应用…`),3),x(v(fe),{class:p([`w-4 h-4 text-textMuted shrink-0`,J.value?`rotate-180`:``])},null,8,[`class`])]),J.value?(e(),m(`div`,Or,[D.value.pm2AppName.trim()?(e(),m(`button`,{key:0,type:`button`,onClick:r[14]||=j(e=>ca(``),[`stop`]),class:`flex items-center w-full px-3 py-2 text-sm text-textMuted hover:bg-white/5 transition-colors border-b border-border`},[x(v(Ie),{class:`w-3.5 h-3.5 mr-2`}),r[96]||=b(` 解除绑定 `,-1)])):h(``,!0),(e(!0),m(u,null,a(K.value,t=>(e(),m(`button`,{key:t.pmId+`:`+t.name,type:`button`,onClick:j(e=>ca(t.name),[`stop`]),class:`flex items-center justify-between w-full px-3 py-2 text-sm text-textMain hover:bg-white/5 transition-colors`},[f(`span`,Ar,[D.value.pm2AppName.trim()===t.name?(e(),_(v(le),{key:0,class:`w-3.5 h-3.5 mr-2 text-primary shrink-0`})):(e(),m(`span`,jr)),f(`span`,Mr,g(t.name),1)]),f(`span`,Nr,[f(`span`,Pr,`#`+g(t.pmId),1),f(`span`,{class:p([`text-[10px] px-1.5 py-0.5 rounded border`,t.status===`online`?`text-success border-success/40 bg-success/10`:`text-textMuted border-border bg-base`])},g(t.status),3)])],8,kr))),128)),f(`button`,{type:`button`,onClick:j(la,[`stop`]),class:`flex items-center w-full px-3 py-2 text-sm text-textMuted hover:bg-white/5 transition-colors border-t border-border`},[x(v(ue),{class:`w-3.5 h-3.5 mr-2`}),r[97]||=b(` 手动输入… `,-1)])])):h(``,!0)])):(e(),m(`div`,Fr,[s(f(`input`,{"onUpdate:modelValue":r[15]||=e=>D.value.pm2AppName=e,type:`text`,list:`pm2-apps-suggest`,spellcheck:`false`,class:`w-full bg-base border border-border rounded-md px-4 py-3 text-textMain font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all`,placeholder:`e.g. my-api / web-server`},null,512),[[O,D.value.pm2AppName]]),f(`datalist`,Ir,[(e(!0),m(u,null,a(K.value,t=>(e(),m(`option`,{key:t.pmId+`:`+t.name,value:t.name},null,8,Lr))),128))]),G.value&&K.value.length>0?(e(),m(`button`,{key:0,type:`button`,onClick:r[16]||=e=>aa.value=!1,class:`mt-2 text-xs text-primary hover:text-textMain inline-flex items-center`},[x(v(fe),{class:`w-3.5 h-3.5 mr-1`}),r[98]||=b(` 改用下拉选择 `,-1)])):h(``,!0)])),da.value.length>0?(e(),m(`div`,Rr,[x(v(Me),{class:`w-3.5 h-3.5 mt-0.5 shrink-0`}),f(`div`,zr,[r[99]||=b(` 该 PM2 应用名已被 `,-1),(e(!0),m(u,null,a(da.value,(n,r)=>(e(),m(u,{key:n.id},[x(o,{to:`/projects/${n.id}`,class:`font-medium text-yellow-500 hover:text-yellow-400 underline underline-offset-2 mx-0.5`},{default:t(()=>[b(`「`+g(n.name)+`」`,1)]),_:2},1032,[`to`]),r<da.value.length-1?(e(),m(`span`,Br,`、`)):h(``,!0)],64))),128)),r[100]||=b(` 绑定。继续保存不会被阻止,但状态与日志会同时归属于多个项目,请确认无误后再绑定。 `,-1)])])):h(``,!0),r[101]||=f(`p`,{class:`text-xs text-textMuted mt-2`},[b(` 绑定后,可在页面顶部实时查看该 PM2 应用的资源占用与运行状态。需要服务器上安装 PM2,且当前 Kite 进程可执行 `),f(`code`,{class:`font-mono`},`pm2 jlist`),b(`。 `)],-1)]),f(`div`,Vr,[f(`button`,{onClick:Yi,disabled:U.value,class:`flex items-center px-5 py-2 text-sm bg-primary hover:bg-primary/90 text-white rounded-md transition-all font-medium disabled:opacity-50`},[U.value?(e(),_(v(E),{key:0,class:`w-4 h-4 mr-2 animate-spin`})):(e(),_(v(Se),{key:1,class:`w-4 h-4 mr-2`})),b(` `+g(U.value?`保存中...`:`保存 PM2 绑定`),1)],8,Hr)])])]),f(`div`,Ur,[f(`div`,Wr,[f(`h2`,Gr,[x(v(we),{class:`w-5 h-5 mr-2 text-primary`}),r[102]||=b(` 部署脚本配置 (云端默认) `,-1)]),r[103]||=f(`p`,{class:`text-sm text-textMuted mt-1`},`配置此项目在服务端接收到文件后,默认执行的 Shell 指令。可被 CLI 参数覆盖。`,-1)]),f(`div`,Kr,[f(`div`,null,[r[104]||=f(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`部署目录 (Destination Path)`,-1),s(f(`input`,{"onUpdate:modelValue":r[17]||=e=>D.value.destPath=e,type:`text`,class:`w-full bg-base border border-border rounded-md px-4 py-3 text-textMain font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all`,placeholder:`e.g. /var/www/my-project`},null,512),[[O,D.value.destPath]]),r[105]||=f(`p`,{class:`text-xs text-textMuted mt-2`},`在服务端解压和部署该项目文件的绝对路径。`,-1)]),f(`div`,null,[r[107]||=f(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`前置脚本 (Pre-Deploy)`,-1),f(`div`,qr,[r[106]||=f(`div`,{class:`absolute left-0 top-0 bottom-0 w-8 bg-base border-r border-border rounded-l-md flex flex-col items-center py-3 text-textMuted font-mono text-xs select-none`},[f(`span`,null,`1`)],-1),s(f(`textarea`,{"onUpdate:modelValue":r[18]||=e=>D.value.preDeploy=e,class:`w-full bg-base border border-border rounded-md pl-11 pr-4 py-3 text-success font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all min-h-[100px] resize-y`,placeholder:`# e.g. npm install && npm run build`,spellcheck:`false`},null,512),[[O,D.value.preDeploy]])]),r[108]||=f(`p`,{class:`text-xs text-textMuted mt-2`},`在打包上传之前,于本地执行的构建命令(通常配置在本地 CLI,此处作为备用参考)。`,-1)]),f(`div`,null,[r[111]||=f(`label`,{class:`block text-sm font-medium text-textMain mb-2`},`后置脚本 (Post-Deploy)`,-1),f(`div`,Jr,[r[109]||=f(`div`,{class:`absolute left-0 top-0 bottom-0 w-8 bg-base border-r border-border rounded-l-md flex flex-col items-center py-3 text-textMuted font-mono text-xs select-none`},[f(`span`,null,`1`)],-1),s(f(`textarea`,{"onUpdate:modelValue":r[19]||=e=>D.value.postDeploy=e,class:`w-full bg-base border border-border rounded-md pl-11 pr-4 py-3 text-success font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all min-h-[100px] resize-y`,placeholder:`# e.g. pm2 restart api-server`,spellcheck:`false`},null,512),[[O,D.value.postDeploy]])]),r[112]||=f(`p`,{class:`text-xs text-textMuted mt-2`},`服务端解压文件后,在目标目录执行的重启或服务加载命令。`,-1),f(`label`,Yr,[s(f(`input`,{"onUpdate:modelValue":r[20]||=e=>D.value.postDeployAsync=e,type:`checkbox`,class:`mt-0.5 w-4 h-4 rounded border-border bg-base text-primary focus:ring-1 focus:ring-primary/50`},null,512),[[Ae,D.value.postDeployAsync]]),r[110]||=c(`<span class="text-xs text-textMuted leading-relaxed"><span class="text-textMain font-medium">异步执行(不等待)</span> — 开启后,postDeploy 触发即认为部署成功;脚本输出仍可在部署日志中查看。适合启动常驻进程 / pm2 restart / 延迟任务。 <span class="text-danger">注意:Kite 进程退出时子进程会被回收,需常驻请配合 <code class="font-mono">nohup</code> / <code class="font-mono">pm2</code> / <code class="font-mono">setsid</code> 自行守护。</span></span>`,1)])]),f(`div`,Xr,[f(`button`,{onClick:Xi,disabled:W.value,class:`flex items-center px-6 py-2.5 bg-primary hover:bg-primary/90 text-white rounded-md transition-all font-medium shadow-[0_0_15px_rgba(59,130,246,0.3)] disabled:opacity-50`},[W.value?(e(),_(v(E),{key:0,class:`w-4 h-4 mr-2 animate-spin`})):(e(),_(v(Se),{key:1,class:`w-4 h-4 mr-2`})),b(` `+g(W.value?`保存中...`:`保存部署脚本`),1)],8,Zr)])])]),f(`div`,Qr,[f(`div`,$r,[f(`h2`,ei,[x(v(He),{class:`w-5 h-5 mr-2 text-primary`}),r[113]||=b(` 部署清理策略 `,-1)]),r[114]||=f(`p`,{class:`text-sm text-textMuted mt-1`},[b(`每次部署解压前,对目标目录执行的清理动作。默认 `),f(`code`,{class:`font-mono text-textMain`},`merge`),b(` 沿用旧行为(零破坏)。`)],-1)]),f(`div`,ti,[f(`div`,ni,[(e(),m(u,null,a([{value:`merge`,title:`merge`,desc:`不清理,直接覆盖。旧行为,零破坏。`,tone:`primary`},{value:`clean`,title:`clean`,desc:`清空目录,但保留 protectPaths 命中的文件,以及 .kite-* 内部目录。`,tone:`warning`},{value:`clean-all`,title:`clean-all`,desc:`清空全部内容(仅保留 .kite-*),protectPaths 也被忽略。`,tone:`danger`}],t=>f(`label`,{key:t.value,class:p([`relative flex flex-col p-4 rounded-lg border-2 cursor-pointer transition-all`,k.value.cleanMode===t.value?t.tone===`danger`?`border-danger bg-danger/5`:t.tone===`warning`?`border-yellow-400 bg-yellow-400/5`:`border-primary bg-primary/5`:`border-border hover:border-textMuted/50 bg-base`])},[s(f(`input`,{type:`radio`,"onUpdate:modelValue":r[21]||=e=>k.value.cleanMode=e,value:t.value,class:`sr-only`},null,8,ri),[[Pe,k.value.cleanMode]]),f(`span`,{class:p([`text-sm font-semibold font-mono`,t.tone===`danger`?`text-danger`:t.tone===`warning`?`text-yellow-400`:`text-primary`])},g(t.title),3),f(`span`,ii,g(t.desc),1),k.value.cleanMode===t.value?(e(),_(v(Le),{key:0,class:p([`absolute top-2 right-2 w-4 h-4`,t.tone===`danger`?`text-danger`:t.tone===`warning`?`text-yellow-400`:`text-primary`])},null,8,[`class`])):h(``,!0)],2)),64))]),k.value.cleanMode===`clean`?(e(),m(`div`,ai,[r[116]||=c(`<label class="block text-sm font-medium text-textMain mb-2">保护路径 (protectPaths)</label><p class="text-xs text-textMuted mb-2"> 支持 minimatch glob,命中文件不会被删除。<code class="font-mono text-textMain">.kite-*</code> 始终自动保护,无需添加。 常见示例:<code class="font-mono text-textMain">uploads/**</code>、<code class="font-mono text-textMain">.env</code>、<code class="font-mono text-textMain">config/*.json</code></p>`,2),f(`div`,oi,[s(f(`input`,{"onUpdate:modelValue":r[22]||=e=>A.value=e,type:`text`,class:`flex-1 bg-base border border-border rounded-md px-3 py-2 text-textMain font-mono text-sm focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/50 transition-all`,placeholder:`如 uploads/**`,onKeydown:ze(j(ha,[`prevent`]),[`enter`])},null,40,si),[[O,A.value]]),f(`button`,{onClick:ha,type:`button`,class:`flex items-center px-3 bg-base border border-border hover:border-primary/50 hover:text-primary text-textMain rounded-md transition-all`},[x(v(Te),{class:`w-4 h-4 mr-1`}),r[115]||=b(` 添加 `,-1)])]),k.value.protectPaths.length?(e(),m(`div`,ci,[(e(!0),m(u,null,a(k.value.protectPaths,t=>(e(),m(`span`,{key:t,class:`inline-flex items-center gap-1 text-xs px-2 py-1 rounded bg-success/10 border border-success/30 text-success font-mono`},[b(g(t)+` `,1),f(`button`,{onClick:e=>ga(t),type:`button`,class:`text-success/70 hover:text-danger`},[x(v(Ie),{class:`w-3 h-3`})],8,li)]))),128))])):(e(),m(`p`,ui,`尚未设置保护路径。clean 模式下会清空整个部署目录(仅保留 .kite-*)。`))])):h(``,!0),k.value.cleanMode===`clean-all`?(e(),m(`div`,di,[x(v(Ve),{class:`w-4 h-4 text-danger shrink-0 mt-0.5`}),r[117]||=f(`p`,{class:`text-xs text-danger leading-relaxed`},[b(` clean-all 会清空目标目录下`),f(`strong`,null,`所有`),b(`文件(仅保留 `),f(`code`,{class:`font-mono bg-base px-1 rounded`},`.kite-*`),b(`)。protectPaths 设置在此模式下被忽略。请务必通过预览确认。 `)],-1)])):h(``,!0),f(`div`,fi,[k.value.cleanMode===`merge`?h(``,!0):(e(),m(`button`,{key:0,onClick:ya,type:`button`,class:`flex items-center px-4 py-2 text-sm bg-base border border-border hover:border-yellow-400/50 hover:text-yellow-400 text-textMain rounded-md transition-all`},[x(v(ye),{class:`w-4 h-4 mr-2`}),r[118]||=b(` 预览将删除的文件 (DRY-RUN) `,-1)])),f(`button`,{onClick:va,disabled:M.value,class:p([`flex items-center px-6 py-2.5 text-sm font-medium rounded-md transition-all disabled:opacity-50`,k.value.cleanMode===`clean-all`?`bg-danger text-white hover:bg-danger/90`:`bg-primary text-white hover:bg-primary/90 shadow-[0_0_15px_rgba(59,130,246,0.3)]`])},[x(v(Se),{class:`w-4 h-4 mr-2`}),b(` `+g(M.value?`保存中...`:`保存清理策略`),1)],10,pi)])])])],512),[[ke,$.value===`config`]]),s(f(`section`,mi,[f(`div`,hi,[f(`div`,gi,[f(`h3`,_i,[x(v(Oe),{class:`w-4 h-4 mr-2`}),r[119]||=b(` 危险操作区 `,-1)]),f(`div`,{class:`mt-4 flex items-start justify-between gap-4`},[r[120]||=f(`div`,{class:`text-sm text-textMuted space-y-1`},[f(`p`,null,`删除该项目将同时清空数据库中的项目配置与全部部署历史日志,且不可恢复。`),f(`p`,{class:`text-textMuted/80`},`部署目录中的实际文件不会被删除,需要时请手动清理。`)],-1),f(`button`,{onClick:Va,class:`shrink-0 px-4 py-2 bg-danger/10 hover:bg-danger text-danger hover:text-white border border-danger/20 hover:border-danger rounded-md transition-colors text-sm font-medium`},` 删除项目 `)])])])],512),[[ke,$.value===`integration`]]),Ra.value?(e(),m(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm`,onClick:j(Ha,[`self`])},[f(`div`,vi,[f(`div`,yi,[f(`div`,bi,[x(v(Me),{class:`w-5 h-5 text-danger`})]),f(`div`,xi,[r[124]||=f(`h2`,{class:`text-lg font-semibold text-textMain`},`确认删除项目`,-1),f(`p`,Si,[r[121]||=b(` 即将删除项目 `,-1),f(`span`,Ci,g(T.value?.name),1),r[122]||=b(` (`,-1),f(`span`,wi,g(v(w)),1),r[123]||=b(`),此操作不可恢复。 `,-1)])])]),f(`div`,Ti,[f(`div`,Ei,[f(`p`,Di,[x(v(Ie),{class:`w-3.5 h-3.5 mr-1.5`}),r[125]||=b(` 将被永久删除的内容 `,-1)]),r[126]||=f(`ul`,{class:`text-xs text-textMain/90 space-y-1 list-disc list-inside marker:text-danger/60`},[f(`li`,null,`该项目在数据库中的配置(名称、描述、部署目录、部署脚本、Token、环境标识等)`),f(`li`,null,[b(`该项目的`),f(`span`,{class:`font-medium`},`全部部署历史日志`),b(`(部署日志面板中将不再可见)`)])],-1)]),f(`div`,Oi,[f(`p`,ki,[x(v(Le),{class:`w-3.5 h-3.5 mr-1.5`}),r[127]||=b(` 不会被删除的内容 `,-1)]),f(`ul`,Ai,[f(`li`,null,[r[128]||=b(` 部署目录 `,-1),f(`code`,ji,g(T.value?.destPath||`—`),1),r[129]||=b(` 下的所有实际文件 `,-1)]),r[130]||=f(`li`,null,`其他项目的数据、全局设置、Admin Token`,-1),r[131]||=f(`li`,null,[b(`项目源码中的 `),f(`code`,{class:`font-mono text-textMain bg-base px-1 py-0.5 rounded text-[11px]`},`kite.config*.json`),b(` / `),f(`code`,{class:`font-mono text-textMain bg-base px-1 py-0.5 rounded text-[11px]`},`.env.local`),b(` 等本地配置`)],-1)])])]),f(`div`,Mi,[f(`label`,Ni,[r[132]||=b(` 请输入项目名称 `,-1),f(`span`,Pi,g(Q.value),1),r[133]||=b(` 以确认删除 `,-1)]),s(f(`input`,{"onUpdate:modelValue":r[23]||=e=>za.value=e,type:`text`,disabled:X.value,placeholder:Q.value,class:`w-full bg-base border border-border rounded-md px-3 py-2 text-textMain font-mono focus:outline-none focus:border-danger focus:ring-1 focus:ring-danger/50 transition-all text-sm disabled:opacity-60`,onKeydown:ze(j(Ua,[`prevent`]),[`enter`])},null,40,Fi),[[O,za.value]])]),Z.value?(e(),m(`p`,Ii,g(Z.value),1)):h(``,!0),f(`div`,Li,[f(`button`,{onClick:Ha,disabled:X.value,class:`px-4 py-2 text-sm font-medium text-textMuted hover:text-textMain dark:hover:bg-white/5 hover:bg-black/5 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed`},` 取消 `,8,Ri),f(`button`,{onClick:Ua,disabled:!Ba.value,class:`px-4 py-2 text-sm font-medium bg-danger text-white rounded-md hover:bg-danger/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center`},[X.value?(e(),_(v(E),{key:0,class:`w-4 h-4 mr-2 animate-spin`})):(e(),_(v(Oe),{key:1,class:`w-4 h-4 mr-2`})),b(` `+g(X.value?`正在删除...`:`永久删除`),1)],8,zi)])])])):h(``,!0),x(Be,{open:Pa.value,"onUpdate:open":r[24]||=e=>Pa.value=e,tone:`warning`,title:`重新生成项目 Token?`,message:`旧 Token 将立即失效。所有正在使用旧 Token 的 CLI / Webhook 调用都会被拒绝,请记得同步更新。`,"confirm-text":`重新生成`,"cancel-text":`取消`,loading:Fa.value,onConfirm:La},null,8,[`open`,`loading`]),x(st,{open:We.value,"onUpdate:open":r[25]||=e=>We.value=e,loading:Ge.value,error:Ke.value,preview:qe.value,mode:k.value.cleanMode===`merge`?`clean`:k.value.cleanMode,"protect-paths":k.value.protectPaths},null,8,[`open`,`loading`,`error`,`preview`,`mode`,`protect-paths`]),x(Be,{open:N.value,"onUpdate:open":r[26]||=e=>N.value=e,tone:`danger`,title:`确认启用 clean-all 模式?`,message:`后续每次部署都会清空部署目录下除 .kite-* 之外的全部内容,protectPaths 在此模式下被忽略。请输入项目名以确认。`,"confirm-text":`启用 clean-all`,"cancel-text":`取消`,"require-text":Q.value,"require-text-hint":`请输入项目名 ${Q.value} 以确认`,loading:M.value,onConfirm:_a},null,8,[`open`,`require-text`,`require-text-hint`,`loading`]),x(Be,{open:B.value,"onUpdate:open":r[27]||=e=>B.value=e,tone:`warning`,title:`确认回滚到此版本?`,message:V.value?`将以归档 ${rt(V.value.id)} 重新部署到项目 ${V.value.projectName}。会按当前项目的 cleanMode / protectPaths 执行清理后再解压,运行时数据按保护规则保留。`:``,"confirm-text":`确认回滚`,"cancel-text":`取消`,loading:tt.value,onConfirm:Wi},null,8,[`open`,`message`,`loading`])])):h(``,!0)}}});export{Vi as default};