@jingyi0605/codingns 0.5.0 → 0.5.1

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 (76) hide show
  1. package/dist/public/assets/AdaptiveButlerPage-SffCV4Vb.js +3 -0
  2. package/dist/public/assets/App-WOLwMld_.js +30 -0
  3. package/dist/public/assets/{BootstrapPage-Vu5oEJ8z.js → BootstrapPage--zExdgfM.js} +1 -1
  4. package/dist/public/assets/{ConversationPage-Cjpg6g0J.js → ConversationPage-D9pzRmOg.js} +2 -2
  5. package/dist/public/assets/{DesktopDetachPreviewPage-BgeEqbc5.js → DesktopDetachPreviewPage-DvI9CIKi.js} +1 -1
  6. package/dist/public/assets/{DesktopWindowPage-1WelvxdH.js → DesktopWindowPage-D8FpOSLE.js} +1 -1
  7. package/dist/public/assets/FileContextPanel-C8T7oqRN.js +1 -0
  8. package/dist/public/assets/GitSidebar-Bze7DNnc.js +6 -0
  9. package/dist/public/assets/{MobileCreateSessionSheet-DLq5qPkx.js → MobileCreateSessionSheet-CXSKMnYn.js} +1 -1
  10. package/dist/public/assets/MobileSheet-Gzc14EpR.js +1 -0
  11. package/dist/public/assets/{MobileTopHeaderFrame-DArgZI7L.js → MobileTopHeaderFrame-BWorAJ1C.js} +1 -1
  12. package/dist/public/assets/{MobileWorkspaceSwitcherHeader-0ywJKfBQ.js → MobileWorkspaceSwitcherHeader-DOr4pTUq.js} +1 -1
  13. package/dist/public/assets/{ServerSettingsModal-izoYMx9U.js → ServerSettingsModal-BYB0GvTl.js} +1 -1
  14. package/dist/public/assets/{SessionIndexPage-C5aG8FIv.js → SessionIndexPage-CR3IARXX.js} +1 -1
  15. package/dist/public/assets/SettingsPage-B_BQtnwE.js +1 -0
  16. package/dist/public/assets/TerminalManagerPanel-PQ-EM64j.js +1 -0
  17. package/dist/public/assets/{TerminalPage-CtKXIU0h.js → TerminalPage-CvnHXBhw.js} +12 -12
  18. package/dist/public/assets/{TerminalRuntimeFallbackModal-CRhOQOsT.js → TerminalRuntimeFallbackModal-D7Aq186N.js} +1 -1
  19. package/dist/public/assets/{ToolFilesPage-DcYPsS-e.js → ToolFilesPage-Qzkc6K2I.js} +1 -1
  20. package/dist/public/assets/{ToolGitPage-CsPl89ty.js → ToolGitPage-BdNDN-cV.js} +1 -1
  21. package/dist/public/assets/{ToolProcessesPage-D0dvR8xK.js → ToolProcessesPage-EXJ9DHWI.js} +1 -1
  22. package/dist/public/assets/{ToolsHomePage-4fP-KRiv.js → ToolsHomePage-CjF3CWzR.js} +1 -1
  23. package/dist/public/assets/{WorkbenchLandingPage-kvlfyxRo.js → WorkbenchLandingPage-DZPk4SmX.js} +1 -1
  24. package/dist/public/assets/WorkbenchLayout-rwQib5In.js +3 -0
  25. package/dist/public/assets/{WorkbenchModal-Ctob14VR.js → WorkbenchModal-B09hC9b5.js} +1 -1
  26. package/dist/public/assets/WorkbenchShellRoute-Cerk5uK7.js +1 -0
  27. package/dist/public/assets/WorkbenchShellRoute-DsW4mBTX.css +1 -0
  28. package/dist/public/assets/{WorkspaceDebugDetailPage-Com5kEXJ.js → WorkspaceDebugDetailPage-Bcq8s-Ma.js} +1 -1
  29. package/dist/public/assets/WorkspaceDetailPage-DNAa8pKr.js +1 -0
  30. package/dist/public/assets/WorkspaceHomePage-BoiLuACV.js +1 -0
  31. package/dist/public/assets/client-runtime-manager-CRQ-F5d2.js +1 -0
  32. package/dist/public/assets/{default-session-permission-mode-CcGwR4Kk.js → default-session-permission-mode-D0wZ9Jek.js} +1 -1
  33. package/dist/public/assets/{file-tree-icon-UFVoVzhM.js → file-tree-icon-Dp_xhVfD.js} +14 -14
  34. package/dist/public/assets/index-C2G8Gmf1.js +42 -0
  35. package/dist/public/assets/{index-_52jxu4a.css → index-CpPTUeA3.css} +1 -1
  36. package/dist/public/assets/{preferences-service-KIYeE2gk.js → preferences-service-gOt2ZjKZ.js} +1 -1
  37. package/dist/public/assets/{session-runtime-machine-0KNSSPp5.js → session-runtime-machine-Dq3pW-UF.js} +8 -8
  38. package/dist/public/assets/{terminal-runtime-meta-AWXJpN4r.js → terminal-runtime-meta-BMT-rSEe.js} +1 -1
  39. package/dist/public/assets/{useRegisteredDebugTemplates-DBDRdptr.js → useRegisteredDebugTemplates-zMcEOGca.js} +1 -1
  40. package/dist/public/index.html +2 -2
  41. package/dist/server/modules/client/client-controller.js +1 -1
  42. package/dist/server/modules/client/client-controller.js.map +1 -1
  43. package/dist/server/modules/client/client-service.d.ts +16 -2
  44. package/dist/server/modules/client/client-service.js +21 -3
  45. package/dist/server/modules/client/client-service.js.map +1 -1
  46. package/dist/server/modules/relay-tunnel/relay-tunnel-service.d.ts +2 -1
  47. package/dist/server/modules/relay-tunnel/relay-tunnel-service.js +203 -8
  48. package/dist/server/modules/relay-tunnel/relay-tunnel-service.js.map +1 -1
  49. package/dist/server/modules/workbench/snapshot-revision.d.ts +4 -0
  50. package/dist/server/modules/workbench/snapshot-revision.js +13 -0
  51. package/dist/server/modules/workbench/snapshot-revision.js.map +1 -0
  52. package/dist/server/modules/workbench/workbench-service.d.ts +1 -0
  53. package/dist/server/modules/workbench/workbench-service.js +3 -2
  54. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  55. package/dist/server/modules/workbench/workspace-panel-snapshot-service.d.ts +6 -1
  56. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +10 -8
  57. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  58. package/dist/server/server/create-server.js +1 -1
  59. package/dist/server/server/create-server.js.map +1 -1
  60. package/dist/server/types/domain.d.ts +9 -0
  61. package/dist/server/ws/workbench-ws-hub.js +135 -33
  62. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  63. package/package.json +1 -1
  64. package/dist/public/assets/AdaptiveButlerPage-R-XZw7pd.js +0 -3
  65. package/dist/public/assets/App-DkvE5EyM.js +0 -30
  66. package/dist/public/assets/FileContextPanel-D_ghXJuW.js +0 -1
  67. package/dist/public/assets/GitSidebar-D9f9Jxwr.js +0 -6
  68. package/dist/public/assets/MobileSheet-DLg-gX1t.js +0 -1
  69. package/dist/public/assets/SettingsPage-HJIC-P-4.js +0 -1
  70. package/dist/public/assets/TerminalManagerPanel-DpyUTo9k.js +0 -1
  71. package/dist/public/assets/WorkbenchLayout-ByFw4eeu.js +0 -3
  72. package/dist/public/assets/WorkbenchShellRoute-BUITtdAg.css +0 -1
  73. package/dist/public/assets/WorkbenchShellRoute-Kw7JEZI3.js +0 -1
  74. package/dist/public/assets/WorkspaceDetailPage-D0Lrx4Uz.js +0 -1
  75. package/dist/public/assets/WorkspaceHomePage-wR8d3aP9.js +0 -1
  76. package/dist/public/assets/index-Byp9hJ0c.js +0 -42
@@ -1 +1 @@
1
- import{z as n,t}from"./index-Byp9hJ0c.js";function o(){return n.request("/api/terminals/shells")}function m(e){return n.request(`/api/terminals?workspaceId=${encodeURIComponent(e)}`)}function l(e){return n.request(`/api/terminals/templates/runtime-status?workspaceId=${encodeURIComponent(e)}`)}function u(e){return n.request(`/api/terminals/templates/${encodeURIComponent(e)}/stop`,{method:"POST"})}function p(e){return n.request("/api/terminals",{method:"POST",body:JSON.stringify(e)})}function c(e){return n.request(`/api/terminals/${encodeURIComponent(e)}`,{method:"DELETE"})}function d(e){return n.request(`/api/terminals/${encodeURIComponent(e)}/record`,{method:"DELETE"})}function f(e,r={}){const i=new URLSearchParams;typeof r.beforeSeq=="number"&&i.set("beforeSeq",String(r.beforeSeq)),typeof r.limit=="number"&&i.set("limit",String(r.limit));const a=i.toString();return n.request(`/api/terminals/${encodeURIComponent(e)}/history${a?`?${a}`:""}`)}function b(e){return n.request(`/api/terminals/templates?workspaceId=${encodeURIComponent(e)}`)}function h(e){return n.request("/api/terminals/templates",{method:"POST",body:JSON.stringify(e)})}function S(e,r){return n.request(`/api/terminals/templates/${encodeURIComponent(e)}`,{method:"PUT",body:JSON.stringify(r)})}function T(e){return n.request(`/api/terminals/templates/${encodeURIComponent(e)}`,{method:"DELETE"})}function q(e,r){return n.request(`/api/terminals/templates/${encodeURIComponent(e)}/run`,{method:"POST",body:JSON.stringify(r)})}function w(e){return[{value:"",label:t("terminal.runtimeAutoOption"),description:t("terminal.runtimeAutoDescription")},{value:"tmux",label:e==="windows"?t("terminal.runtimePersistentLabel"):"tmux",description:e==="windows"?t("terminal.runtimeWindowsPersistentDescription"):t("terminal.runtimeTmuxDescription")},{value:"embedded-pty",label:"embedded-pty",description:t("terminal.runtimeEmbeddedDescription")}]}function R(e,r){return e?e==="conpty-powershell"?t("terminal.runtimeConptyPowerShellLabel"):e==="conpty-cmd"?t("terminal.runtimeConptyCmdLabel"):e==="conpty-git-bash"?t("terminal.runtimeConptyGitBashLabel"):e==="tmux"&&r==="windows"?t("terminal.runtimePersistentLabel"):e:t("terminal.runtimeAutoOption")}function C(e,r){return e?e==="embedded-pty"?"pty":e==="conpty-powershell"||e==="conpty-cmd"||e==="conpty-git-bash"||e==="tmux"&&r==="windows"?t("terminal.runtimePersistentShortLabel"):e:t("terminal.runtimeAutoShortLabel")}export{l as a,w as b,m as c,o as d,C as e,c as f,R as g,f as h,p as i,d as j,h as k,b as l,T as m,q as r,u as s,S as u};
1
+ import{B as n,t}from"./index-C2G8Gmf1.js";function o(){return n.request("/api/terminals/shells")}function m(e){return n.request(`/api/terminals?workspaceId=${encodeURIComponent(e)}`)}function l(e){return n.request(`/api/terminals/templates/runtime-status?workspaceId=${encodeURIComponent(e)}`)}function u(e){return n.request(`/api/terminals/templates/${encodeURIComponent(e)}/stop`,{method:"POST"})}function p(e){return n.request("/api/terminals",{method:"POST",body:JSON.stringify(e)})}function c(e){return n.request(`/api/terminals/${encodeURIComponent(e)}`,{method:"DELETE"})}function d(e){return n.request(`/api/terminals/${encodeURIComponent(e)}/record`,{method:"DELETE"})}function f(e,r={}){const i=new URLSearchParams;typeof r.beforeSeq=="number"&&i.set("beforeSeq",String(r.beforeSeq)),typeof r.limit=="number"&&i.set("limit",String(r.limit));const a=i.toString();return n.request(`/api/terminals/${encodeURIComponent(e)}/history${a?`?${a}`:""}`)}function b(e){return n.request(`/api/terminals/templates?workspaceId=${encodeURIComponent(e)}`)}function h(e){return n.request("/api/terminals/templates",{method:"POST",body:JSON.stringify(e)})}function S(e,r){return n.request(`/api/terminals/templates/${encodeURIComponent(e)}`,{method:"PUT",body:JSON.stringify(r)})}function T(e){return n.request(`/api/terminals/templates/${encodeURIComponent(e)}`,{method:"DELETE"})}function q(e,r){return n.request(`/api/terminals/templates/${encodeURIComponent(e)}/run`,{method:"POST",body:JSON.stringify(r)})}function w(e){return[{value:"",label:t("terminal.runtimeAutoOption"),description:t("terminal.runtimeAutoDescription")},{value:"tmux",label:e==="windows"?t("terminal.runtimePersistentLabel"):"tmux",description:e==="windows"?t("terminal.runtimeWindowsPersistentDescription"):t("terminal.runtimeTmuxDescription")},{value:"embedded-pty",label:"embedded-pty",description:t("terminal.runtimeEmbeddedDescription")}]}function R(e,r){return e?e==="conpty-powershell"?t("terminal.runtimeConptyPowerShellLabel"):e==="conpty-cmd"?t("terminal.runtimeConptyCmdLabel"):e==="conpty-git-bash"?t("terminal.runtimeConptyGitBashLabel"):e==="tmux"&&r==="windows"?t("terminal.runtimePersistentLabel"):e:t("terminal.runtimeAutoOption")}function C(e,r){return e?e==="embedded-pty"?"pty":e==="conpty-powershell"||e==="conpty-cmd"||e==="conpty-git-bash"||e==="tmux"&&r==="windows"?t("terminal.runtimePersistentShortLabel"):e:t("terminal.runtimeAutoShortLabel")}export{l as a,w as b,m as c,o as d,C as e,c as f,R as g,f as h,p as i,d as j,h as k,b as l,T as m,q as r,u as s,S as u};
@@ -1 +1 @@
1
- import{j as l,t as s,b as u}from"./index-Byp9hJ0c.js";import{b as x,d as k}from"./MobileSheet-DLg-gX1t.js";import{l as j,a as p}from"./terminal-runtime-meta-AWXJpN4r.js";function O({workspace:e,state:r,variant:t}){return e?t==="mobile"?l.jsx(v,{workspace:e,state:r}):l.jsx(P,{workspace:e,state:r}):l.jsx("p",{className:"workbench-section-empty",children:s("shell.workspaceDetailMissingBody")})}function v({workspace:e,state:r}){const t=r.primaryAnalysis,o=r.analyses.length;return l.jsx(l.Fragment,{children:l.jsxs("section",{className:"mobile-feature-panel surface-card mobile-workspace-composition-panel",children:[l.jsx("div",{className:"mobile-feature-section-header",children:l.jsx("div",{children:l.jsx("h2",{children:s("shell.workspaceDetailRegisteredDebugAnalysisTitle")})})}),r.loading&&t===null?l.jsx("p",{children:s("common.loading")}):null,r.error?l.jsx("p",{className:"status-text","data-tone":"error",children:r.error}):null,t?l.jsxs("div",{className:"mobile-detail-grid mobile-workspace-detail-grid",children:[l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugFrameworkLabel")}),l.jsx("strong",{children:t.primaryFramework??s("common.unknown")})]}),l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugConfidenceLabel")}),l.jsx("strong",{children:y(t.confidence)})]}),l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugSummaryServiceCountLabel")}),l.jsx("strong",{children:o})]}),l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugCompatibilityLabel")}),l.jsx("strong",{children:D(t.compatibilityLevel)})]}),l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugLastAnalyzedAtLabel")}),l.jsx("strong",{children:r.lastAnalyzedAt??s("shell.workspaceDetailDebugFrameworkNoteEmpty")})]}),l.jsxs("div",{className:"mobile-detail-metric mobile-detail-metric-wide",children:[l.jsx("span",{children:s("shell.manageWorkspacePathLabel")}),l.jsx("strong",{children:e.path})]})]}):null]})})}function P({workspace:e,state:r}){const t=r.primaryAnalysis,o=r.analyses.length;return l.jsxs("section",{className:"debug-readiness-section surface-card",children:[l.jsx("div",{className:"debug-readiness-section-header",children:l.jsxs("div",{children:[l.jsx("h3",{children:s("shell.workspaceDetailRegisteredDebugAnalysisTitle")}),l.jsx("p",{children:s("shell.workspaceDetailRegisteredDebugAnalysisDescription")})]})}),r.loading&&t===null?l.jsx("p",{className:"workbench-section-empty",children:s("common.loading")}):null,r.error?l.jsx("p",{className:"workbench-manage-status status-text","data-tone":"error",children:r.error}):null,t?l.jsxs("div",{className:"debug-readiness-summary-grid",children:[l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugFrameworkLabel")}),l.jsx("strong",{children:t.primaryFramework??s("common.unknown")})]}),l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugConfidenceLabel")}),l.jsx("strong",{children:y(t.confidence)}),l.jsx("small",{children:r.lastAnalyzedAt??s("shell.workspaceDetailDebugFrameworkNoteEmpty")})]}),l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugSummaryServiceCountLabel")}),l.jsx("strong",{children:o})]}),l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugCompatibilityLabel")}),l.jsx("strong",{children:D(t.compatibilityLevel)})]}),l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.manageWorkspacePathLabel")}),l.jsx("strong",{title:e.path,children:e.path})]})]}):null]})}function D(e){switch(e){case"supported":return s("shell.workspaceDetailDebugCompatibilitySupported");case"conditional":return s("shell.workspaceDetailDebugCompatibilityConditional");case"unsupported":return s("shell.workspaceDetailDebugCompatibilityUnsupported");default:return s("shell.workspaceDetailDebugCompatibilityUnknown")}}function y(e){switch(e){case"high":return s("shell.workspaceDetailDebugConfidenceHigh");case"medium":return s("shell.workspaceDetailDebugConfidenceMedium");case"low":return s("shell.workspaceDetailDebugConfidenceLow");default:return s("common.unknown")}}function F(e,r,t){const o=new Map(r.map(i=>[i.templateId,i])),c=new Map(((t==null?void 0:t.services)??[]).map(i=>[i.serviceId,i])),a=new Map;for(const i of e)i.port!==null&&a.set(i.port,(a.get(i.port)??0)+1);const n=e.map(i=>{const g=o.get(i.id)??null,m=c.get(i.id)??null;if(m){const w=m.autoStartAllowed?m.leasedPort!==null&&m.leasedPort!==i.port?"orchestrated":"runnable":"blocked";return{template:i,runtimeStatus:g,planItem:m,decision:w,assignedPort:m.leasedPort,reason:A(i,m)}}return i.port===null?{template:i,runtimeStatus:g,planItem:null,decision:"blocked",assignedPort:null,reason:s("shell.workspaceDetailRegisteredDebugPlanReasonPortMissing")}:(a.get(i.port)??0)>1||g!=null&&g.occupied?{template:i,runtimeStatus:g,planItem:null,decision:"orchestrated",assignedPort:i.port,reason:(a.get(i.port)??0)>1?s("shell.workspaceDetailRegisteredDebugPlanReasonDuplicatePortWillOrchestrate"):s("shell.workspaceDetailRegisteredDebugPlanReasonPortOccupiedWillOrchestrate")}:{template:i,runtimeStatus:g,planItem:null,decision:"runnable",assignedPort:i.port,reason:s("shell.workspaceDetailRegisteredDebugPlanReasonRunnable")}}),h=n.filter(i=>i.decision==="runnable").length,b=n.filter(i=>i.decision==="orchestrated").length,d=n.filter(i=>i.decision==="blocked").length;return{generatedAt:(t==null?void 0:t.runtimeSession.createdAt)??new Date().toISOString(),autoStartAllowed:(t==null?void 0:t.autoStartAllowed)??(n.length>0&&d===0),runnableCount:h,orchestratedCount:b,blockedCount:d,items:n}}function R(e){return e.autoStartAllowed&&e.blockedCount===0}function E(e,r){return r===0?"danger":R(e)?"success":"warn"}function z(e,r){return r===0?s("shell.workspaceDetailRegisteredDebugOverallStatusEmpty"):R(e)?s("shell.workspaceDetailRegisteredDebugOverallStatusReady"):s("shell.workspaceDetailRegisteredDebugOverallStatusPartial")}function W(e,r){return r===0?s("shell.workspaceDetailRegisteredDebugTemplatesEmpty"):s("shell.workspaceDetailRegisteredDebugOverallSummary",{runnable:e.runnableCount,orchestrated:e.orchestratedCount,blocked:e.blockedCount})}function $(e){const r=e.args.join(" ").trim();return r?`${e.command} ${r}`:e.command}function B(e,r){const t=r.replace(/[\\/]+$/,"");return e===t?".":e.startsWith(`${t}/`)||e.startsWith(`${t}\\`)?e.slice(t.length+1):e}function V(e){return e===null?s("shell.workspaceDetailRegisteredDebugTemplatePortMissing"):String(e)}function U(e){if(!e)return s("shell.workspaceDetailDebugPortEmpty");const r=new Date(e);return Number.isNaN(r.getTime())?e:new Intl.DateTimeFormat("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}).format(r)}function q(e,r){if(e.port!==null)return r!=null&&r.occupied?"warn":"success"}function H(e,r){return e.port===null?s("shell.workspaceDetailRegisteredDebugTemplateStatusUntracked"):r!=null&&r.occupied?s("shell.workspaceDetailRegisteredDebugTemplateStatusOccupied"):s("shell.workspaceDetailRegisteredDebugTemplateStatusIdle")}function _(e){return e!=null&&e.occupied?e.processId&&e.processName?`PID ${e.processId} · ${e.processName}`:e.processId?`PID ${e.processId}`:e.processName??s("shell.workspaceDetailRegisteredDebugRuntimeUnknown"):s("shell.workspaceDetailRegisteredDebugRuntimeIdle")}function G(e,r){return e.port===null?s("shell.workspaceDetailRegisteredDebugPlanReasonPortMissing"):r!=null&&r.occupied?s("shell.workspaceDetailRegisteredDebugPlanReasonPortOccupiedWillOrchestrate"):s("shell.workspaceDetailRegisteredDebugPlanReasonRunnable")}function J(e){switch(e){case"runnable":return s("shell.workspaceDetailRegisteredDebugPlanActionStart");case"orchestrated":return s("shell.workspaceDetailRegisteredDebugPlanActionOrchestrated");default:return s("shell.workspaceDetailRegisteredDebugPlanActionBlocked")}}function A(e,r){var t;return r.missingRequirements.length>0?r.missingRequirements.map(o=>C(o)).join(";"):(t=r.aiFallback)!=null&&t.eligible?r.aiFallback.reason:r.leasedPort!==null&&r.leasedPort!==e.port?s("shell.workspaceDetailRegisteredDebugPlanReasonPortOrchestrated",{port:r.leasedPort}):Object.keys(r.envPatch).length>0?s("shell.workspaceDetailRegisteredDebugPlanReasonServiceDiscoveryInjected"):s("shell.workspaceDetailRegisteredDebugPlanReasonRunnable")}function C(e){switch(e){case"analysis":return s("shell.workspaceDetailRegisteredDebugPlanReasonAnalysisMissing");case"service_discovery":return s("shell.workspaceDetailRegisteredDebugPlanReasonServiceDiscoveryMissing");case"callback":return s("shell.workspaceDetailRegisteredDebugPlanReasonCallbackMissing");case"port":return s("shell.workspaceDetailRegisteredDebugPlanReasonPortMissing");default:return e}}function K(e){const[r,t]=u.useState({loading:!1,error:null,targetId:null,targetSourceType:null,services:[],analyses:[],matrixItems:[]}),[o,c]=u.useState(0),a=u.useCallback(()=>{c(d=>d+1)},[]);u.useEffect(()=>{if(!(e!=null&&e.id)||!e.path){t({loading:!1,error:null,targetId:null,targetSourceType:null,services:[],analyses:[],matrixItems:[]});return}let d=!1;return t(i=>({...i,loading:!0,error:null})),(async()=>{try{const[i,g]=await Promise.all([x({workspaceId:e.id,rootPath:e.path}),k()]);if(d)return;t({loading:!1,error:null,targetId:i.target.id,targetSourceType:i.target.sourceType,services:i.services,analyses:i.analyses,matrixItems:g.items})}catch(i){if(d)return;t({loading:!1,error:i instanceof Error?i.message:s("shell.workspaceDetailDebugAnalyzeFailed"),targetId:null,targetSourceType:null,services:[],analyses:[],matrixItems:[]})}})(),()=>{d=!0}},[o,e==null?void 0:e.id,e==null?void 0:e.path]);const n=u.useMemo(()=>N(r.services,r.analyses),[r.analyses,r.services]),h=u.useMemo(()=>r.matrixItems.find(d=>d.framework===((n==null?void 0:n.primaryFramework)??"unknown"))??null,[n==null?void 0:n.primaryFramework,r.matrixItems]),b=u.useMemo(()=>{var d;return((d=r.analyses[0])==null?void 0:d.createdAt)??null},[r.analyses]);return{...r,primaryAnalysis:n,currentCompatibilityItem:h,lastAnalyzedAt:b,refresh:a}}function N(e,r){if(r.length===0)return null;const t=new Map(r.filter(c=>c.serviceId).map(c=>[c.serviceId,c]));return[...e].sort((c,a)=>I(c,a)).map(c=>t.get(c.id)??null).find(c=>c!==null)??r[0]??null}function I(e,r){const t=f(e.role)-f(r.role);return t!==0?t:e.name.localeCompare(r.name)}function f(e){switch(e){case"frontend":return 0;case"backend":return 1;case"worker":return 2;case"mock":return 3;default:return 4}}function Q(e){const[r,t]=u.useState({loading:!1,error:null,templates:[],runtimeStatuses:[],lastRefreshedAt:null}),o=u.useCallback(async()=>{if(!(e!=null&&e.id)){t({loading:!1,error:null,templates:[],runtimeStatuses:[],lastRefreshedAt:null});return}t(a=>({...a,loading:!0,error:null}));try{const[a,n]=await Promise.all([j(e.id),p(e.id)]);t({loading:!1,error:null,templates:T(a.items),runtimeStatuses:n.items,lastRefreshedAt:new Date().toISOString()})}catch(a){throw t(n=>({...n,loading:!1,error:a instanceof Error?a.message:s("shell.workspaceDetailRegisteredDebugLoadFailed")})),a}},[e==null?void 0:e.id]),c=u.useCallback(async()=>{if(e!=null&&e.id){t(a=>({...a,loading:!0,error:null}));try{const a=await p(e.id);t(n=>({...n,loading:!1,error:null,runtimeStatuses:a.items,lastRefreshedAt:new Date().toISOString()}))}catch(a){throw t(n=>({...n,loading:!1,error:a instanceof Error?a.message:s("shell.workspaceDetailRegisteredDebugActionRefreshFailed")})),a}}},[e==null?void 0:e.id]);return u.useEffect(()=>{o().catch(()=>{})},[o]),{...r,refreshAll:o,refreshRuntime:c}}function T(e){return[...e].sort((r,t)=>{const o=r.cwd.localeCompare(t.cwd);return o!==0?o:r.name.localeCompare(t.name)})}export{O as D,U as a,F as b,H as c,B as d,V as e,z as f,_ as g,$ as h,G as i,Q as j,W as k,J as l,q as m,E as r,K as u};
1
+ import{j as l,t as s,b as u}from"./index-C2G8Gmf1.js";import{b as x,d as k}from"./MobileSheet-Gzc14EpR.js";import{l as j,a as p}from"./terminal-runtime-meta-BMT-rSEe.js";function O({workspace:e,state:r,variant:t}){return e?t==="mobile"?l.jsx(v,{workspace:e,state:r}):l.jsx(P,{workspace:e,state:r}):l.jsx("p",{className:"workbench-section-empty",children:s("shell.workspaceDetailMissingBody")})}function v({workspace:e,state:r}){const t=r.primaryAnalysis,o=r.analyses.length;return l.jsx(l.Fragment,{children:l.jsxs("section",{className:"mobile-feature-panel surface-card mobile-workspace-composition-panel",children:[l.jsx("div",{className:"mobile-feature-section-header",children:l.jsx("div",{children:l.jsx("h2",{children:s("shell.workspaceDetailRegisteredDebugAnalysisTitle")})})}),r.loading&&t===null?l.jsx("p",{children:s("common.loading")}):null,r.error?l.jsx("p",{className:"status-text","data-tone":"error",children:r.error}):null,t?l.jsxs("div",{className:"mobile-detail-grid mobile-workspace-detail-grid",children:[l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugFrameworkLabel")}),l.jsx("strong",{children:t.primaryFramework??s("common.unknown")})]}),l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugConfidenceLabel")}),l.jsx("strong",{children:y(t.confidence)})]}),l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugSummaryServiceCountLabel")}),l.jsx("strong",{children:o})]}),l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugCompatibilityLabel")}),l.jsx("strong",{children:D(t.compatibilityLevel)})]}),l.jsxs("div",{className:"mobile-detail-metric",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugLastAnalyzedAtLabel")}),l.jsx("strong",{children:r.lastAnalyzedAt??s("shell.workspaceDetailDebugFrameworkNoteEmpty")})]}),l.jsxs("div",{className:"mobile-detail-metric mobile-detail-metric-wide",children:[l.jsx("span",{children:s("shell.manageWorkspacePathLabel")}),l.jsx("strong",{children:e.path})]})]}):null]})})}function P({workspace:e,state:r}){const t=r.primaryAnalysis,o=r.analyses.length;return l.jsxs("section",{className:"debug-readiness-section surface-card",children:[l.jsx("div",{className:"debug-readiness-section-header",children:l.jsxs("div",{children:[l.jsx("h3",{children:s("shell.workspaceDetailRegisteredDebugAnalysisTitle")}),l.jsx("p",{children:s("shell.workspaceDetailRegisteredDebugAnalysisDescription")})]})}),r.loading&&t===null?l.jsx("p",{className:"workbench-section-empty",children:s("common.loading")}):null,r.error?l.jsx("p",{className:"workbench-manage-status status-text","data-tone":"error",children:r.error}):null,t?l.jsxs("div",{className:"debug-readiness-summary-grid",children:[l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugFrameworkLabel")}),l.jsx("strong",{children:t.primaryFramework??s("common.unknown")})]}),l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugConfidenceLabel")}),l.jsx("strong",{children:y(t.confidence)}),l.jsx("small",{children:r.lastAnalyzedAt??s("shell.workspaceDetailDebugFrameworkNoteEmpty")})]}),l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugSummaryServiceCountLabel")}),l.jsx("strong",{children:o})]}),l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.workspaceDetailDebugCompatibilityLabel")}),l.jsx("strong",{children:D(t.compatibilityLevel)})]}),l.jsxs("article",{className:"debug-readiness-summary-card",children:[l.jsx("span",{children:s("shell.manageWorkspacePathLabel")}),l.jsx("strong",{title:e.path,children:e.path})]})]}):null]})}function D(e){switch(e){case"supported":return s("shell.workspaceDetailDebugCompatibilitySupported");case"conditional":return s("shell.workspaceDetailDebugCompatibilityConditional");case"unsupported":return s("shell.workspaceDetailDebugCompatibilityUnsupported");default:return s("shell.workspaceDetailDebugCompatibilityUnknown")}}function y(e){switch(e){case"high":return s("shell.workspaceDetailDebugConfidenceHigh");case"medium":return s("shell.workspaceDetailDebugConfidenceMedium");case"low":return s("shell.workspaceDetailDebugConfidenceLow");default:return s("common.unknown")}}function F(e,r,t){const o=new Map(r.map(i=>[i.templateId,i])),c=new Map(((t==null?void 0:t.services)??[]).map(i=>[i.serviceId,i])),a=new Map;for(const i of e)i.port!==null&&a.set(i.port,(a.get(i.port)??0)+1);const n=e.map(i=>{const g=o.get(i.id)??null,m=c.get(i.id)??null;if(m){const w=m.autoStartAllowed?m.leasedPort!==null&&m.leasedPort!==i.port?"orchestrated":"runnable":"blocked";return{template:i,runtimeStatus:g,planItem:m,decision:w,assignedPort:m.leasedPort,reason:A(i,m)}}return i.port===null?{template:i,runtimeStatus:g,planItem:null,decision:"blocked",assignedPort:null,reason:s("shell.workspaceDetailRegisteredDebugPlanReasonPortMissing")}:(a.get(i.port)??0)>1||g!=null&&g.occupied?{template:i,runtimeStatus:g,planItem:null,decision:"orchestrated",assignedPort:i.port,reason:(a.get(i.port)??0)>1?s("shell.workspaceDetailRegisteredDebugPlanReasonDuplicatePortWillOrchestrate"):s("shell.workspaceDetailRegisteredDebugPlanReasonPortOccupiedWillOrchestrate")}:{template:i,runtimeStatus:g,planItem:null,decision:"runnable",assignedPort:i.port,reason:s("shell.workspaceDetailRegisteredDebugPlanReasonRunnable")}}),h=n.filter(i=>i.decision==="runnable").length,b=n.filter(i=>i.decision==="orchestrated").length,d=n.filter(i=>i.decision==="blocked").length;return{generatedAt:(t==null?void 0:t.runtimeSession.createdAt)??new Date().toISOString(),autoStartAllowed:(t==null?void 0:t.autoStartAllowed)??(n.length>0&&d===0),runnableCount:h,orchestratedCount:b,blockedCount:d,items:n}}function R(e){return e.autoStartAllowed&&e.blockedCount===0}function E(e,r){return r===0?"danger":R(e)?"success":"warn"}function z(e,r){return r===0?s("shell.workspaceDetailRegisteredDebugOverallStatusEmpty"):R(e)?s("shell.workspaceDetailRegisteredDebugOverallStatusReady"):s("shell.workspaceDetailRegisteredDebugOverallStatusPartial")}function W(e,r){return r===0?s("shell.workspaceDetailRegisteredDebugTemplatesEmpty"):s("shell.workspaceDetailRegisteredDebugOverallSummary",{runnable:e.runnableCount,orchestrated:e.orchestratedCount,blocked:e.blockedCount})}function $(e){const r=e.args.join(" ").trim();return r?`${e.command} ${r}`:e.command}function B(e,r){const t=r.replace(/[\\/]+$/,"");return e===t?".":e.startsWith(`${t}/`)||e.startsWith(`${t}\\`)?e.slice(t.length+1):e}function V(e){return e===null?s("shell.workspaceDetailRegisteredDebugTemplatePortMissing"):String(e)}function U(e){if(!e)return s("shell.workspaceDetailDebugPortEmpty");const r=new Date(e);return Number.isNaN(r.getTime())?e:new Intl.DateTimeFormat("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}).format(r)}function q(e,r){if(e.port!==null)return r!=null&&r.occupied?"warn":"success"}function H(e,r){return e.port===null?s("shell.workspaceDetailRegisteredDebugTemplateStatusUntracked"):r!=null&&r.occupied?s("shell.workspaceDetailRegisteredDebugTemplateStatusOccupied"):s("shell.workspaceDetailRegisteredDebugTemplateStatusIdle")}function _(e){return e!=null&&e.occupied?e.processId&&e.processName?`PID ${e.processId} · ${e.processName}`:e.processId?`PID ${e.processId}`:e.processName??s("shell.workspaceDetailRegisteredDebugRuntimeUnknown"):s("shell.workspaceDetailRegisteredDebugRuntimeIdle")}function G(e,r){return e.port===null?s("shell.workspaceDetailRegisteredDebugPlanReasonPortMissing"):r!=null&&r.occupied?s("shell.workspaceDetailRegisteredDebugPlanReasonPortOccupiedWillOrchestrate"):s("shell.workspaceDetailRegisteredDebugPlanReasonRunnable")}function J(e){switch(e){case"runnable":return s("shell.workspaceDetailRegisteredDebugPlanActionStart");case"orchestrated":return s("shell.workspaceDetailRegisteredDebugPlanActionOrchestrated");default:return s("shell.workspaceDetailRegisteredDebugPlanActionBlocked")}}function A(e,r){var t;return r.missingRequirements.length>0?r.missingRequirements.map(o=>C(o)).join(";"):(t=r.aiFallback)!=null&&t.eligible?r.aiFallback.reason:r.leasedPort!==null&&r.leasedPort!==e.port?s("shell.workspaceDetailRegisteredDebugPlanReasonPortOrchestrated",{port:r.leasedPort}):Object.keys(r.envPatch).length>0?s("shell.workspaceDetailRegisteredDebugPlanReasonServiceDiscoveryInjected"):s("shell.workspaceDetailRegisteredDebugPlanReasonRunnable")}function C(e){switch(e){case"analysis":return s("shell.workspaceDetailRegisteredDebugPlanReasonAnalysisMissing");case"service_discovery":return s("shell.workspaceDetailRegisteredDebugPlanReasonServiceDiscoveryMissing");case"callback":return s("shell.workspaceDetailRegisteredDebugPlanReasonCallbackMissing");case"port":return s("shell.workspaceDetailRegisteredDebugPlanReasonPortMissing");default:return e}}function K(e){const[r,t]=u.useState({loading:!1,error:null,targetId:null,targetSourceType:null,services:[],analyses:[],matrixItems:[]}),[o,c]=u.useState(0),a=u.useCallback(()=>{c(d=>d+1)},[]);u.useEffect(()=>{if(!(e!=null&&e.id)||!e.path){t({loading:!1,error:null,targetId:null,targetSourceType:null,services:[],analyses:[],matrixItems:[]});return}let d=!1;return t(i=>({...i,loading:!0,error:null})),(async()=>{try{const[i,g]=await Promise.all([x({workspaceId:e.id,rootPath:e.path}),k()]);if(d)return;t({loading:!1,error:null,targetId:i.target.id,targetSourceType:i.target.sourceType,services:i.services,analyses:i.analyses,matrixItems:g.items})}catch(i){if(d)return;t({loading:!1,error:i instanceof Error?i.message:s("shell.workspaceDetailDebugAnalyzeFailed"),targetId:null,targetSourceType:null,services:[],analyses:[],matrixItems:[]})}})(),()=>{d=!0}},[o,e==null?void 0:e.id,e==null?void 0:e.path]);const n=u.useMemo(()=>N(r.services,r.analyses),[r.analyses,r.services]),h=u.useMemo(()=>r.matrixItems.find(d=>d.framework===((n==null?void 0:n.primaryFramework)??"unknown"))??null,[n==null?void 0:n.primaryFramework,r.matrixItems]),b=u.useMemo(()=>{var d;return((d=r.analyses[0])==null?void 0:d.createdAt)??null},[r.analyses]);return{...r,primaryAnalysis:n,currentCompatibilityItem:h,lastAnalyzedAt:b,refresh:a}}function N(e,r){if(r.length===0)return null;const t=new Map(r.filter(c=>c.serviceId).map(c=>[c.serviceId,c]));return[...e].sort((c,a)=>I(c,a)).map(c=>t.get(c.id)??null).find(c=>c!==null)??r[0]??null}function I(e,r){const t=f(e.role)-f(r.role);return t!==0?t:e.name.localeCompare(r.name)}function f(e){switch(e){case"frontend":return 0;case"backend":return 1;case"worker":return 2;case"mock":return 3;default:return 4}}function Q(e){const[r,t]=u.useState({loading:!1,error:null,templates:[],runtimeStatuses:[],lastRefreshedAt:null}),o=u.useCallback(async()=>{if(!(e!=null&&e.id)){t({loading:!1,error:null,templates:[],runtimeStatuses:[],lastRefreshedAt:null});return}t(a=>({...a,loading:!0,error:null}));try{const[a,n]=await Promise.all([j(e.id),p(e.id)]);t({loading:!1,error:null,templates:T(a.items),runtimeStatuses:n.items,lastRefreshedAt:new Date().toISOString()})}catch(a){throw t(n=>({...n,loading:!1,error:a instanceof Error?a.message:s("shell.workspaceDetailRegisteredDebugLoadFailed")})),a}},[e==null?void 0:e.id]),c=u.useCallback(async()=>{if(e!=null&&e.id){t(a=>({...a,loading:!0,error:null}));try{const a=await p(e.id);t(n=>({...n,loading:!1,error:null,runtimeStatuses:a.items,lastRefreshedAt:new Date().toISOString()}))}catch(a){throw t(n=>({...n,loading:!1,error:a instanceof Error?a.message:s("shell.workspaceDetailRegisteredDebugActionRefreshFailed")})),a}}},[e==null?void 0:e.id]);return u.useEffect(()=>{o().catch(()=>{})},[o]),{...r,refreshAll:o,refreshRuntime:c}}function T(e){return[...e].sort((r,t)=>{const o=r.cwd.localeCompare(t.cwd);return o!==0?o:r.name.localeCompare(t.name)})}export{O as D,U as a,F as b,H as c,B as d,V as e,z as f,_ as g,$ as h,G as i,Q as j,W as k,J as l,q as m,E as r,K as u};
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
6
  <title>CodingNS</title>
7
- <script type="module" crossorigin src="/assets/index-Byp9hJ0c.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-_52jxu4a.css">
7
+ <script type="module" crossorigin src="/assets/index-C2G8Gmf1.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-CpPTUeA3.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -13,7 +13,7 @@ export class ClientController {
13
13
  });
14
14
  }
15
15
  const platform = normalizePlatform(request.query);
16
- reply.send(this.clientService.getRuntimeConfig(platform, {
16
+ reply.send(await this.clientService.getRuntimeConfig(platform, {
17
17
  protocol: readRequestProtocol(request),
18
18
  host: request.headers.host ?? null
19
19
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"client-controller.js","sourceRoot":"","sources":["../../../../src/modules/client/client-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client-controller.js","sourceRoot":"","sources":["../../../../src/modules/client/client-controller.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import type { HostConfig } from "../../config/env.js";
2
+ import type { HostCandidateEndpoint } from "../../types/domain.js";
3
+ import type { RelayTunnelService } from "../relay-tunnel/relay-tunnel-service.js";
2
4
  import type { NpmGlobalPackageService } from "./npm-global-package-service.js";
3
5
  import type { ServiceUpdateTaskService } from "./service-update-task-service.js";
4
6
  import type { ServiceUpdateListDto, ServiceUpdateTaskDto } from "./service-update-types.js";
@@ -8,6 +10,16 @@ export interface ClientRuntimeConfigDto {
8
10
  releaseChannel: "stable" | "beta";
9
11
  autoReconnect: boolean;
10
12
  autoCheckUpdate: boolean;
13
+ relayTunnel: ClientRuntimeRelayTunnelDto | null;
14
+ }
15
+ export interface ClientRuntimeRelayTunnelDto {
16
+ provider: "codingns_relay";
17
+ enabled: boolean;
18
+ controlBaseUrl: string | null;
19
+ tunnelDomain: string | null;
20
+ bindingId: string | null;
21
+ hostFingerprint: string | null;
22
+ candidateEndpoints: HostCandidateEndpoint[];
11
23
  }
12
24
  export interface DesktopReleaseManifestDto {
13
25
  channel: "stable" | "beta";
@@ -36,14 +48,16 @@ export declare class ClientService {
36
48
  private readonly config;
37
49
  private readonly npmGlobalPackageService;
38
50
  private readonly serviceUpdateTaskService;
39
- constructor(config: HostConfig, npmGlobalPackageService: NpmGlobalPackageService, serviceUpdateTaskService: ServiceUpdateTaskService);
51
+ private readonly relayTunnelService;
52
+ constructor(config: HostConfig, npmGlobalPackageService: NpmGlobalPackageService, serviceUpdateTaskService: ServiceUpdateTaskService, relayTunnelService: RelayTunnelService);
40
53
  getRuntimeConfig(platform: "desktop" | "web", requestContext?: {
41
54
  readonly protocol?: string | null;
42
55
  readonly host?: string | null;
43
- }): ClientRuntimeConfigDto;
56
+ }): Promise<ClientRuntimeConfigDto>;
44
57
  getReleaseManifest(channel: "stable" | "beta", platform: string): ReleaseManifestDto;
45
58
  getServiceUpdate(channel: "stable" | "beta"): Promise<ServiceUpdateListDto>;
46
59
  installServiceUpdate(channel: "stable" | "beta", packageName: string): Promise<ServiceUpdateTaskDto>;
47
60
  getServiceUpdateTask(taskId: string): ServiceUpdateTaskDto;
61
+ private getRelayTunnelRuntime;
48
62
  }
49
63
  export declare function readHostPackageVersion(): string;
@@ -6,18 +6,21 @@ export class ClientService {
6
6
  config;
7
7
  npmGlobalPackageService;
8
8
  serviceUpdateTaskService;
9
- constructor(config, npmGlobalPackageService, serviceUpdateTaskService) {
9
+ relayTunnelService;
10
+ constructor(config, npmGlobalPackageService, serviceUpdateTaskService, relayTunnelService) {
10
11
  this.config = config;
11
12
  this.npmGlobalPackageService = npmGlobalPackageService;
12
13
  this.serviceUpdateTaskService = serviceUpdateTaskService;
14
+ this.relayTunnelService = relayTunnelService;
13
15
  }
14
- getRuntimeConfig(platform, requestContext) {
16
+ async getRuntimeConfig(platform, requestContext) {
15
17
  return {
16
18
  platform,
17
19
  hostBaseUrl: resolveClientHostBaseUrl(this.config, platform, requestContext),
18
20
  releaseChannel: this.config.releaseChannel,
19
21
  autoReconnect: true,
20
- autoCheckUpdate: platform === "desktop"
22
+ autoCheckUpdate: platform === "desktop",
23
+ relayTunnel: await this.getRelayTunnelRuntime()
21
24
  };
22
25
  }
23
26
  getReleaseManifest(channel, platform) {
@@ -60,6 +63,21 @@ export class ClientService {
60
63
  getServiceUpdateTask(taskId) {
61
64
  return this.serviceUpdateTaskService.getTask(taskId);
62
65
  }
66
+ async getRelayTunnelRuntime() {
67
+ const status = await this.relayTunnelService.getStatus();
68
+ if (status.provider !== "codingns_relay") {
69
+ return null;
70
+ }
71
+ return {
72
+ provider: status.provider,
73
+ enabled: status.enabled,
74
+ controlBaseUrl: status.controlBaseUrl,
75
+ tunnelDomain: status.tunnelDomain,
76
+ bindingId: status.bindingId,
77
+ hostFingerprint: status.hostFingerprint,
78
+ candidateEndpoints: status.candidateEndpoints
79
+ };
80
+ }
63
81
  }
64
82
  function parseDesktopReleaseManifest(parsed) {
65
83
  if (!isReleaseChannel(parsed.channel) ||
@@ -1 +1 @@
1
- {"version":3,"file":"client-service.js","sourceRoot":"","sources":["../../../../src/modules/client/client-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client-service.js","sourceRoot":"","sources":["../../../../src/modules/client/client-service.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import type { InstanceRelayTunnelIdentityRepository } from "../../storage/reposi
4
4
  import type { InstanceRelayTunnelRepository } from "../../storage/repositories/instance-relay-tunnel-repository.js";
5
5
  import { type TaskManager } from "../tasks/task-manager.js";
6
6
  import { type TaskHandle } from "../tasks/task-types.js";
7
- import type { InstanceRelayTunnelConfig, InstanceRelayTunnelStatus, RelayTunnelPhase, RelayTunnelProvider } from "../../types/domain.js";
7
+ import type { HostCandidateEndpoint, InstanceRelayTunnelConfig, InstanceRelayTunnelStatus, RelayTunnelPhase, RelayTunnelProvider } from "../../types/domain.js";
8
8
  export interface RelayTunnelConfigUpdateInput {
9
9
  activated?: boolean;
10
10
  relayBaseUrl?: string | null;
@@ -34,6 +34,7 @@ export interface InstanceRelayTunnelStatusDto {
34
34
  hostPublicKey: string | null;
35
35
  hostKeyFingerprint: string | null;
36
36
  localTargetBaseUrl: string;
37
+ candidateEndpoints: HostCandidateEndpoint[];
37
38
  phase: RelayTunnelPhase;
38
39
  connected: boolean;
39
40
  hostFingerprint: string | null;
@@ -1,3 +1,4 @@
1
+ import os from "node:os";
1
2
  import { AppError } from "../../shared/errors/app-error.js";
2
3
  import { decryptSecret, encryptSecret } from "../../shared/utils/secret-box.js";
3
4
  import { nowIso } from "../../shared/utils/time.js";
@@ -494,6 +495,7 @@ export class RelayTunnelService {
494
495
  hostPublicKey: effectiveConfig.hostPublicKey,
495
496
  hostKeyFingerprint: effectiveConfig.hostKeyFingerprint,
496
497
  localTargetBaseUrl: effectiveConfig.localTargetBaseUrl,
498
+ candidateEndpoints: buildHostCandidateEndpoints(effectiveConfig),
497
499
  phase: effectiveStatus.phase,
498
500
  connected: effectiveStatus.connected,
499
501
  hostFingerprint: effectiveStatus.hostFingerprint,
@@ -565,13 +567,19 @@ export class RelayTunnelService {
565
567
  }
566
568
  }
567
569
  async requestControlApi(input) {
568
- const response = await this.fetchFn(new URL(input.path, ensureTrailingSlash(input.controlBaseUrl)), {
569
- method: input.method,
570
- headers: input.headers,
571
- body: input.body
572
- });
570
+ let response;
571
+ try {
572
+ response = await this.fetchFn(new URL(input.path, ensureTrailingSlash(input.controlBaseUrl)), {
573
+ method: input.method,
574
+ headers: input.headers,
575
+ body: input.body
576
+ });
577
+ }
578
+ catch (error) {
579
+ throw buildControlFetchError(error, input.controlBaseUrl, input.failurePrefix);
580
+ }
573
581
  if (!response.ok) {
574
- throw await buildControlApiError(response, input.failurePrefix);
582
+ throw await buildControlApiError(response, input.controlBaseUrl, input.failurePrefix);
575
583
  }
576
584
  return await response.json();
577
585
  }
@@ -597,6 +605,133 @@ function buildSkeletonStatus(phase, config, overrides) {
597
605
  observedAt: overrides?.observedAt ?? null
598
606
  };
599
607
  }
608
+ function buildHostCandidateEndpoints(config) {
609
+ const endpoints = new Map();
610
+ const relayEndpoint = buildRelayPublicUrl(config);
611
+ if (relayEndpoint) {
612
+ endpoints.set(relayEndpoint, {
613
+ endpointId: `relay:${relayEndpoint}`,
614
+ kind: "relay",
615
+ url: relayEndpoint,
616
+ priority: 400,
617
+ expiresAt: null,
618
+ source: "host_reported"
619
+ });
620
+ }
621
+ for (const localCandidateUrl of buildLocalCandidateUrls(config.localTargetBaseUrl)) {
622
+ endpoints.set(localCandidateUrl, {
623
+ endpointId: `host_reported:${localCandidateUrl}`,
624
+ kind: classifyCandidateEndpointKind(localCandidateUrl),
625
+ url: localCandidateUrl,
626
+ priority: resolveCandidateEndpointPriority(localCandidateUrl),
627
+ expiresAt: null,
628
+ source: "host_reported"
629
+ });
630
+ }
631
+ return Array.from(endpoints.values()).sort((left, right) => {
632
+ if (left.priority !== right.priority) {
633
+ return left.priority - right.priority;
634
+ }
635
+ return left.url.localeCompare(right.url);
636
+ });
637
+ }
638
+ function buildRelayPublicUrl(config) {
639
+ if (!config.tunnelDomain || !config.controlBaseUrl) {
640
+ return null;
641
+ }
642
+ try {
643
+ const controlUrl = new URL(config.controlBaseUrl);
644
+ controlUrl.hostname = config.tunnelDomain.trim().toLowerCase();
645
+ controlUrl.pathname = "/";
646
+ controlUrl.search = "";
647
+ controlUrl.hash = "";
648
+ return controlUrl.toString().replace(/\/$/, "");
649
+ }
650
+ catch {
651
+ return null;
652
+ }
653
+ }
654
+ function buildLocalCandidateUrls(localTargetBaseUrl) {
655
+ let parsed;
656
+ try {
657
+ parsed = new URL(localTargetBaseUrl);
658
+ }
659
+ catch {
660
+ return [];
661
+ }
662
+ const candidates = new Set();
663
+ const hostname = parsed.hostname.trim().toLowerCase();
664
+ candidates.add(normalizeUrlWithoutTrailingSlash(parsed.toString()));
665
+ if (hostname === "0.0.0.0" || hostname === "::" || hostname === "::0") {
666
+ for (const networkAddress of listPrivateIpv4Addresses()) {
667
+ const candidateUrl = new URL(parsed.toString());
668
+ candidateUrl.hostname = networkAddress;
669
+ candidates.add(normalizeUrlWithoutTrailingSlash(candidateUrl.toString()));
670
+ }
671
+ }
672
+ if (hostname === "127.0.0.1" || hostname === "localhost" || hostname === "::1") {
673
+ for (const networkAddress of listPrivateIpv4Addresses()) {
674
+ const candidateUrl = new URL(parsed.toString());
675
+ candidateUrl.hostname = networkAddress;
676
+ candidates.add(normalizeUrlWithoutTrailingSlash(candidateUrl.toString()));
677
+ }
678
+ }
679
+ return Array.from(candidates);
680
+ }
681
+ function listPrivateIpv4Addresses() {
682
+ const interfaces = os.networkInterfaces();
683
+ const candidates = new Set();
684
+ for (const entries of Object.values(interfaces)) {
685
+ for (const entry of entries ?? []) {
686
+ if (!entry || entry.family !== "IPv4" || entry.internal) {
687
+ continue;
688
+ }
689
+ if (!isPrivateIpv4Address(entry.address)) {
690
+ continue;
691
+ }
692
+ candidates.add(entry.address);
693
+ }
694
+ }
695
+ return Array.from(candidates).sort();
696
+ }
697
+ function isPrivateIpv4Address(address) {
698
+ return (/^10\./.test(address)
699
+ || /^192\.168\./.test(address)
700
+ || /^172\.(1[6-9]|2\d|3[0-1])\./.test(address));
701
+ }
702
+ function classifyCandidateEndpointKind(candidateUrl) {
703
+ try {
704
+ const hostname = new URL(candidateUrl).hostname.toLowerCase();
705
+ if (hostname === "127.0.0.1" || hostname === "localhost" || hostname === "::1") {
706
+ return "loopback";
707
+ }
708
+ if (isPrivateIpv4Address(hostname)) {
709
+ return "lan";
710
+ }
711
+ return "custom";
712
+ }
713
+ catch {
714
+ return "custom";
715
+ }
716
+ }
717
+ function resolveCandidateEndpointPriority(candidateUrl) {
718
+ const kind = classifyCandidateEndpointKind(candidateUrl);
719
+ switch (kind) {
720
+ case "loopback":
721
+ return 100;
722
+ case "lan":
723
+ return 200;
724
+ case "tailscale":
725
+ return 300;
726
+ case "relay":
727
+ return 400;
728
+ default:
729
+ return 500;
730
+ }
731
+ }
732
+ function normalizeUrlWithoutTrailingSlash(value) {
733
+ return value.endsWith("/") ? value.slice(0, -1) : value;
734
+ }
600
735
  function isBound(config) {
601
736
  return Boolean(config.bindingId && config.tunnelDomain);
602
737
  }
@@ -738,12 +873,40 @@ function clearRelayTunnelControlSession(config, options) {
738
873
  updatedAt: options.updatedAt
739
874
  };
740
875
  }
741
- async function buildControlApiError(response, failurePrefix) {
876
+ async function buildControlApiError(response, controlBaseUrl, failurePrefix) {
742
877
  const detail = await readControlApiErrorDetail(response);
878
+ if (response.status === 401 || response.status === 403) {
879
+ return new AppError({
880
+ statusCode: response.status,
881
+ errorCode: "RELAY_TUNNEL_CONTROL_ACCESS_DENIED",
882
+ detail: `${failurePrefix}:控制站 ${controlBaseUrl} 拒绝了这次请求(HTTP ${response.status})。`
883
+ + ` 请确认这是正确的控制站地址,并检查账号、密码或访问权限。`
884
+ + appendControlApiDetail(detail)
885
+ });
886
+ }
887
+ if (response.status === 404) {
888
+ return new AppError({
889
+ statusCode: 404,
890
+ errorCode: "RELAY_TUNNEL_CONTROL_ENDPOINT_NOT_FOUND",
891
+ detail: `${failurePrefix}:控制站 ${controlBaseUrl} 上没有这个接口(HTTP 404)。`
892
+ + " 这通常说明地址写错了,或者目标服务不是 CodingNS 控制站。"
893
+ + appendControlApiDetail(detail)
894
+ });
895
+ }
743
896
  return new AppError({
744
897
  statusCode: response.status,
745
898
  errorCode: "RELAY_TUNNEL_CONTROL_API_ERROR",
746
- detail: `${failurePrefix}:${detail}`
899
+ detail: `${failurePrefix}:控制站 ${controlBaseUrl} 返回了异常响应(HTTP ${response.status})。`
900
+ + appendControlApiDetail(detail)
901
+ });
902
+ }
903
+ function buildControlFetchError(error, controlBaseUrl, failurePrefix) {
904
+ return new AppError({
905
+ statusCode: 502,
906
+ errorCode: "RELAY_TUNNEL_CONTROL_UNREACHABLE",
907
+ detail: `${failurePrefix}:无法连接到控制站 ${controlBaseUrl}。`
908
+ + " 请确认服务地址、端口和网络连接是否正确。"
909
+ + appendControlApiDetail(resolveFetchErrorDetail(error))
747
910
  });
748
911
  }
749
912
  async function readControlApiErrorDetail(response) {
@@ -768,4 +931,36 @@ async function readControlApiErrorDetail(response) {
768
931
  function readJsonErrorText(value) {
769
932
  return typeof value === "string" ? normalizeOptionalText(value) : null;
770
933
  }
934
+ function resolveFetchErrorDetail(error) {
935
+ if (error instanceof Error) {
936
+ const code = readFetchErrorCode(error);
937
+ if (code === "ECONNREFUSED") {
938
+ return "连接被目标服务器拒绝。";
939
+ }
940
+ if (code === "ENOTFOUND" || code === "EAI_AGAIN") {
941
+ return "域名无法解析。";
942
+ }
943
+ if (code === "ETIMEDOUT" || code === "UND_ERR_CONNECT_TIMEOUT") {
944
+ return "连接超时。";
945
+ }
946
+ if (code === "CERT_HAS_EXPIRED" || code === "DEPTH_ZERO_SELF_SIGNED_CERT") {
947
+ return "TLS 证书无效。";
948
+ }
949
+ return normalizeOptionalText(error.message);
950
+ }
951
+ return null;
952
+ }
953
+ function readFetchErrorCode(error) {
954
+ const cause = "cause" in error
955
+ ? error.cause
956
+ : undefined;
957
+ return typeof cause?.code === "string" ? cause.code : null;
958
+ }
959
+ function appendControlApiDetail(detail) {
960
+ const normalized = normalizeOptionalText(detail);
961
+ if (!normalized) {
962
+ return "";
963
+ }
964
+ return ` 详情:${normalized}`;
965
+ }
771
966
  //# sourceMappingURL=relay-tunnel-service.js.map