dsh-deeppilot 0.9.8 → 0.9.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPATIBILITY.md +78 -5
- package/README.md +34 -10
- package/README.zh-CN.md +24 -8
- package/bin/SHA256SUMS +6 -6
- package/bin/darwin-amd64/dsh-deeppilot-tunnel +0 -0
- package/bin/darwin-arm64/dsh-deeppilot-tunnel +0 -0
- package/bin/linux-amd64/dsh-deeppilot-tunnel +0 -0
- package/bin/linux-arm64/dsh-deeppilot-tunnel +0 -0
- package/bin/windows-amd64/dsh-deeppilot-tunnel.exe +0 -0
- package/bin/windows-arm64/dsh-deeppilot-tunnel.exe +0 -0
- package/docs/DSH_RELEASE_MEMORY.md +148 -9
- package/docs/NPM_PUBLISHING.md +30 -0
- package/lib/client.js +152 -4
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +8 -1
- package/lib/index.js +690 -54
- package/lib/index.js.map +1 -1
- package/package.json +13 -12
package/lib/client.js
CHANGED
|
@@ -245,6 +245,40 @@ window.__ModuleLoader__.load({
|
|
|
245
245
|
results
|
|
246
246
|
};
|
|
247
247
|
}
|
|
248
|
+
function parseDiagnosticFailure(value) {
|
|
249
|
+
const s = rec(value, "diagnostics.recentFailures[]");
|
|
250
|
+
const kind = str(s, "kind", "diagnostics.kind");
|
|
251
|
+
if (!/^[a-z][a-z0-9-]{0,47}$/.test(kind)) reject("diagnostics.kind");
|
|
252
|
+
const reason = str(s, "reason", "diagnostics.reason");
|
|
253
|
+
if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(reason)) reject("diagnostics.reason");
|
|
254
|
+
const attemptId = s.attemptId;
|
|
255
|
+
if (attemptId !== void 0 && (typeof attemptId !== "string" || !/^[A-Za-z0-9_-]{1,16}$/.test(attemptId))) reject("diagnostics.attemptId");
|
|
256
|
+
const source = s.source;
|
|
257
|
+
if (source !== void 0 && (typeof source !== "string" || !/^[0-9a-f]{8,64}$/.test(source))) reject("diagnostics.source");
|
|
258
|
+
const closeCode = s.closeCode;
|
|
259
|
+
if (closeCode !== void 0 && (typeof closeCode !== "number" || !Number.isInteger(closeCode))) reject("diagnostics.closeCode");
|
|
260
|
+
const durationMs = s.durationMs;
|
|
261
|
+
if (durationMs !== void 0 && (typeof durationMs !== "number" || !Number.isFinite(durationMs) || durationMs < 0)) reject("diagnostics.durationMs");
|
|
262
|
+
return {
|
|
263
|
+
ts: int(s, "ts", "diagnostics.ts"),
|
|
264
|
+
kind,
|
|
265
|
+
reason,
|
|
266
|
+
...typeof attemptId === "string" ? { attemptId } : {},
|
|
267
|
+
...typeof source === "string" ? { source } : {},
|
|
268
|
+
...typeof closeCode === "number" ? { closeCode } : {},
|
|
269
|
+
...typeof durationMs === "number" ? { durationMs: Math.round(durationMs) } : {}
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function parseDiagnostics(value) {
|
|
273
|
+
const s = rec(value, "diagnostics");
|
|
274
|
+
const failures = s.recentFailures;
|
|
275
|
+
if (!Array.isArray(failures)) reject("diagnostics.recentFailures");
|
|
276
|
+
if (failures.length > 20) reject("diagnostics.recentFailures");
|
|
277
|
+
return {
|
|
278
|
+
startedAt: int(s, "startedAt", "diagnostics.startedAt"),
|
|
279
|
+
recentFailures: failures.map(parseDiagnosticFailure)
|
|
280
|
+
};
|
|
281
|
+
}
|
|
248
282
|
function parseReport(value) {
|
|
249
283
|
const s = rec(value, "report");
|
|
250
284
|
const devices = s.devices;
|
|
@@ -266,7 +300,8 @@ window.__ModuleLoader__.load({
|
|
|
266
300
|
lanAddresses,
|
|
267
301
|
local: parseLocal(s.local),
|
|
268
302
|
remote: parseRemote(s.remote),
|
|
269
|
-
devices: devices.map(parseDevice)
|
|
303
|
+
devices: devices.map(parseDevice),
|
|
304
|
+
...s.diagnostics !== void 0 ? { diagnostics: parseDiagnostics(s.diagnostics) } : {}
|
|
270
305
|
};
|
|
271
306
|
}
|
|
272
307
|
const reportSchema = { parse: parseReport };
|
|
@@ -458,6 +493,31 @@ window.__ModuleLoader__.load({
|
|
|
458
493
|
"troubleshooting.description": "仅在排查连接或推送问题时使用。",
|
|
459
494
|
"troubleshooting.debugTitle": "调试日志",
|
|
460
495
|
"troubleshooting.debugDescription": "打开后在 DSH host 的终端输出里打印握手、推送等诊断信息;不会打印配对令牌、APNs token 或消息内容。改动立即生效,无需重启。",
|
|
496
|
+
"diagnostics.title": "连接诊断",
|
|
497
|
+
"diagnostics.description": "最近的连接失败事件;可一键复制后发给维护者排查。",
|
|
498
|
+
"diagnostics.recent": "最近失败",
|
|
499
|
+
"diagnostics.empty": "最近没有失败记录",
|
|
500
|
+
"diagnostics.staleHost": "宿主插件版本较旧,没有连接诊断数据,请更新 dsh-deeppilot。",
|
|
501
|
+
"diagnostics.copy": "复制诊断信息",
|
|
502
|
+
"diagnostics.copied": "诊断信息已复制",
|
|
503
|
+
"diagnostics.copyFailed": "复制诊断信息失败:",
|
|
504
|
+
"diagnostics.item": "{time} · {kind} · {reason}",
|
|
505
|
+
"diagnostics.attempt": "尝试 {id}",
|
|
506
|
+
"diagnostics.source": "来源 {label}",
|
|
507
|
+
"diagnostics.closeCode": "关闭码 {code}",
|
|
508
|
+
"diagnostics.duration": "耗时 {ms}ms",
|
|
509
|
+
"diagnostics.startedAt": "启动于 {time}",
|
|
510
|
+
"diagnostics.reportTitle": "DeepPilot 诊断信息",
|
|
511
|
+
"diagnostics.reportGeneratedAt": "生成时间",
|
|
512
|
+
"diagnostics.reportVersion": "插件版本",
|
|
513
|
+
"diagnostics.reportEnabled": "总开关",
|
|
514
|
+
"diagnostics.reportLocal": "局域网",
|
|
515
|
+
"diagnostics.reportRemote": "公网",
|
|
516
|
+
"diagnostics.reportConnections": "当前连接",
|
|
517
|
+
"diagnostics.reportFailureHeader": "最近失败",
|
|
518
|
+
"diagnostics.reportNone": "(无)",
|
|
519
|
+
"diagnostics.on": "已启用",
|
|
520
|
+
"diagnostics.off": "已关闭",
|
|
461
521
|
"system.summary": "系统信息",
|
|
462
522
|
"system.title": "运行信息",
|
|
463
523
|
"system.description": "插件、协议与连接端点的技术信息。",
|
|
@@ -676,6 +736,31 @@ window.__ModuleLoader__.load({
|
|
|
676
736
|
"troubleshooting.description": "Use these only when diagnosing connection or push issues.",
|
|
677
737
|
"troubleshooting.debugTitle": "Debug logging",
|
|
678
738
|
"troubleshooting.debugDescription": "When on, prints handshake and push diagnostics to the DSH host’s terminal output; never prints pairing tokens, APNs tokens, or message content. Takes effect immediately, no restart needed.",
|
|
739
|
+
"diagnostics.title": "Connection diagnostics",
|
|
740
|
+
"diagnostics.description": "Recent connection failures; copy them for troubleshooting.",
|
|
741
|
+
"diagnostics.recent": "Recent failures",
|
|
742
|
+
"diagnostics.empty": "No recent failures",
|
|
743
|
+
"diagnostics.staleHost": "This host is too old to report connection diagnostics. Update dsh-deeppilot.",
|
|
744
|
+
"diagnostics.copy": "Copy diagnostics",
|
|
745
|
+
"diagnostics.copied": "Diagnostics copied",
|
|
746
|
+
"diagnostics.copyFailed": "Copying diagnostics failed: ",
|
|
747
|
+
"diagnostics.item": "{time} · {kind} · {reason}",
|
|
748
|
+
"diagnostics.attempt": "attempt {id}",
|
|
749
|
+
"diagnostics.source": "source {label}",
|
|
750
|
+
"diagnostics.closeCode": "close code {code}",
|
|
751
|
+
"diagnostics.duration": "{ms}ms",
|
|
752
|
+
"diagnostics.startedAt": "Started {time}",
|
|
753
|
+
"diagnostics.reportTitle": "DeepPilot diagnostics",
|
|
754
|
+
"diagnostics.reportGeneratedAt": "Generated",
|
|
755
|
+
"diagnostics.reportVersion": "Plugin version",
|
|
756
|
+
"diagnostics.reportEnabled": "Master switch",
|
|
757
|
+
"diagnostics.reportLocal": "LAN",
|
|
758
|
+
"diagnostics.reportRemote": "Funnel",
|
|
759
|
+
"diagnostics.reportConnections": "Active connections",
|
|
760
|
+
"diagnostics.reportFailureHeader": "Recent failures",
|
|
761
|
+
"diagnostics.reportNone": "(none)",
|
|
762
|
+
"diagnostics.on": "enabled",
|
|
763
|
+
"diagnostics.off": "disabled",
|
|
679
764
|
"system.summary": "System information",
|
|
680
765
|
"system.title": "Runtime information",
|
|
681
766
|
"system.description": "Technical details about the plugin, protocol, and endpoints.",
|
|
@@ -3877,9 +3962,11 @@ window.__ModuleLoader__.load({
|
|
|
3877
3962
|
const remote = dotState(input.remoteDot);
|
|
3878
3963
|
const attention = local.attention || remote.attention;
|
|
3879
3964
|
const online = local.online || remote.online;
|
|
3965
|
+
const hasSignal = (dot) => dot !== void 0 && dot !== "";
|
|
3966
|
+
const anySignal = hasSignal(input.localDot) || hasSignal(input.remoteDot);
|
|
3880
3967
|
return {
|
|
3881
|
-
kind: !input.switchReady ? "loading" : !input.enabled ? "off" : attention ? "attention" : online ? "ready" : "loading",
|
|
3882
|
-
dot: !input.enabled ? "" : attention ? " pbb-dotBad" : online ? " pbb-dotOk" : " pbb-dotWarn"
|
|
3968
|
+
kind: !input.switchReady ? "loading" : !input.enabled ? "off" : attention ? "attention" : online ? "ready" : anySignal ? "loading" : "off",
|
|
3969
|
+
dot: !input.enabled || !attention && !online && !anySignal ? "" : attention ? " pbb-dotBad" : online ? " pbb-dotOk" : " pbb-dotWarn"
|
|
3883
3970
|
};
|
|
3884
3971
|
}
|
|
3885
3972
|
const LOCAL_PORT_RANGE = {
|
|
@@ -4072,6 +4159,11 @@ window.__ModuleLoader__.load({
|
|
|
4072
4159
|
const [deviceMessage, setDeviceMessage] = (0, react.useState)("");
|
|
4073
4160
|
const [editingDeviceId, setEditingDeviceId] = (0, react.useState)(null);
|
|
4074
4161
|
const [deviceNameDraft, setDeviceNameDraft] = (0, react.useState)("");
|
|
4162
|
+
/** 复制诊断信息的结果提示;failed 决定是否染红。 */
|
|
4163
|
+
const [diagnosticsCopy, setDiagnosticsCopy] = (0, react.useState)({
|
|
4164
|
+
message: "",
|
|
4165
|
+
failed: false
|
|
4166
|
+
});
|
|
4075
4167
|
(0, react.useEffect)(() => {
|
|
4076
4168
|
if (!can("refresh")) return;
|
|
4077
4169
|
const refresh = props.refresh;
|
|
@@ -4481,6 +4573,62 @@ window.__ModuleLoader__.load({
|
|
|
4481
4573
|
});
|
|
4482
4574
|
const serviceStatusText = translateWith(props.t, SERVICE_STATUS_KEY[service.kind]);
|
|
4483
4575
|
const serviceDot = service.dot;
|
|
4576
|
+
/** 一条失败事件的单行文本:时间 · 类型 · 分因,附带可选排查字段。 */
|
|
4577
|
+
const diagnosticLine = (failure) => {
|
|
4578
|
+
const base = translateWith(props.t, "diagnostics.item", {
|
|
4579
|
+
time: new Date(failure.ts).toLocaleString(),
|
|
4580
|
+
kind: failure.kind,
|
|
4581
|
+
reason: failure.reason
|
|
4582
|
+
});
|
|
4583
|
+
const extras = [];
|
|
4584
|
+
if (failure.attemptId !== void 0) extras.push(translateWith(props.t, "diagnostics.attempt", { id: failure.attemptId }));
|
|
4585
|
+
if (failure.closeCode !== void 0) extras.push(translateWith(props.t, "diagnostics.closeCode", { code: failure.closeCode }));
|
|
4586
|
+
if (failure.durationMs !== void 0) extras.push(translateWith(props.t, "diagnostics.duration", { ms: failure.durationMs }));
|
|
4587
|
+
if (failure.source !== void 0) extras.push(translateWith(props.t, "diagnostics.source", { label: failure.source }));
|
|
4588
|
+
return extras.length === 0 ? base : base + " · " + extras.join(" · ");
|
|
4589
|
+
};
|
|
4590
|
+
/**
|
|
4591
|
+
* 复制诊断信息:报告里的结构化事实(版本 / 相位 / 连接数 / 最近失败)。
|
|
4592
|
+
* 走既有的 report 通道与 i18n;内容不含配对码、公钥、APNs token 与消息正文。
|
|
4593
|
+
*/
|
|
4594
|
+
const copyDiagnostics = () => {
|
|
4595
|
+
if (report === null) return;
|
|
4596
|
+
const enabledText = report.enabled ? translateWith(props.t, "diagnostics.on") : translateWith(props.t, "diagnostics.off");
|
|
4597
|
+
const failures = report.diagnostics?.recentFailures ?? [];
|
|
4598
|
+
const lines = [
|
|
4599
|
+
translateWith(props.t, "diagnostics.reportTitle"),
|
|
4600
|
+
translateWith(props.t, "diagnostics.reportGeneratedAt") + ": " + (/* @__PURE__ */ new Date()).toLocaleString(),
|
|
4601
|
+
translateWith(props.t, "diagnostics.reportVersion") + ": v" + report.pluginVersion + " (" + translateWith(props.t, "advanced.protocolVersion") + " v" + String(report.protocolVersion) + ")",
|
|
4602
|
+
translateWith(props.t, "diagnostics.reportEnabled") + ": " + enabledText,
|
|
4603
|
+
translateWith(props.t, "diagnostics.reportLocal") + ": " + report.local.phase + (report.local.phase === "online" ? " :" + String(report.local.port) : ""),
|
|
4604
|
+
translateWith(props.t, "diagnostics.reportRemote") + ": " + report.remote.phase,
|
|
4605
|
+
translateWith(props.t, "diagnostics.reportConnections") + ": " + String(report.activeConnections)
|
|
4606
|
+
];
|
|
4607
|
+
if (report.diagnostics !== void 0) lines.push(translateWith(props.t, "diagnostics.startedAt", { time: new Date(report.diagnostics.startedAt).toLocaleString() }));
|
|
4608
|
+
lines.push(translateWith(props.t, "diagnostics.reportFailureHeader") + ":");
|
|
4609
|
+
if (failures.length === 0) lines.push("- " + translateWith(props.t, "diagnostics.reportNone"));
|
|
4610
|
+
else for (const failure of failures.slice(-5).reverse()) lines.push("- " + diagnosticLine(failure));
|
|
4611
|
+
writeClipboard(props.t, lines.join("\n")).then(() => {
|
|
4612
|
+
setDiagnosticsCopy({
|
|
4613
|
+
message: translateWith(props.t, "diagnostics.copied"),
|
|
4614
|
+
failed: false
|
|
4615
|
+
});
|
|
4616
|
+
}, (error) => {
|
|
4617
|
+
setDiagnosticsCopy({
|
|
4618
|
+
message: translateWith(props.t, "diagnostics.copyFailed") + (error instanceof Error ? error.message : String(error)),
|
|
4619
|
+
failed: true
|
|
4620
|
+
});
|
|
4621
|
+
});
|
|
4622
|
+
};
|
|
4623
|
+
const diagnosticsSection = report === null ? null : (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("div", { className: "pbb-switchText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "diagnostics.title")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "diagnostics.description"))), (0, react.createElement)("button", {
|
|
4624
|
+
type: "button",
|
|
4625
|
+
className: "pbb-action",
|
|
4626
|
+
onClick: copyDiagnostics,
|
|
4627
|
+
"data-testid": "diagnosticsCopy"
|
|
4628
|
+
}, translateWith(props.t, "diagnostics.copy"))), diagnosticsCopy.message ? (0, react.createElement)("p", { className: "pbb-diag" + (diagnosticsCopy.failed ? " pbb-diagBad" : "") }, diagnosticsCopy.message) : null, report.diagnostics === void 0 ? (0, react.createElement)("p", { className: "pbb-diag" }, translateWith(props.t, "diagnostics.staleHost")) : report.diagnostics.recentFailures.length === 0 ? (0, react.createElement)("p", { className: "pbb-diag" }, translateWith(props.t, "diagnostics.empty")) : (0, react.createElement)("div", null, (0, react.createElement)("span", { className: "pbb-label" }, translateWith(props.t, "diagnostics.recent")), report.diagnostics.recentFailures.slice(-5).reverse().map((failure, index) => (0, react.createElement)("p", {
|
|
4629
|
+
className: "pbb-diag",
|
|
4630
|
+
key: String(index)
|
|
4631
|
+
}, diagnosticLine(failure)))));
|
|
4484
4632
|
return (0, react.createElement)("div", { className: "pbb-section" }, (0, react.createElement)("header", { className: "pbb-pageHeader" }, (0, react.createElement)("div", null, (0, react.createElement)("h2", { className: "pbb-title" }, "DeepPilot"), (0, react.createElement)("p", { className: "pbb-intro" }, translateWith(props.t, "meta.intro"))), (0, react.createElement)("button", {
|
|
4485
4633
|
type: "button",
|
|
4486
4634
|
className: "pbb-refresh",
|
|
@@ -4631,7 +4779,7 @@ window.__ModuleLoader__.load({
|
|
|
4631
4779
|
}, (step.ok ? "✓ " : "✗ ") + (step.id === "health" ? translateWith(props.t, "push.relayStep.health") : translateWith(props.t, "push.relayStep.enroll")) + (step.latencyMs !== void 0 ? ` (${String(step.latencyMs)}ms)` : "") + " — " + step.message))), pushTestError ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, pushTestError) : null, pushTestResult === null ? (0, react.createElement)("p", { className: "pbb-diag" }, translateWith(props.t, "push.pushDefault")) : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("code", { className: "pbb-token " + (pushTestResult.overall === "sent" ? "pbb-ok" : pushTestResult.overall === "failed" ? "pbb-bad" : "") }, pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : pushTestResult.overall === "failed" ? translateWith(props.t, "push.pushFailed") : pushTestResult.overall === "no-targets" ? translateWith(props.t, "push.pushNoTargets") : translateWith(props.t, "push.pushNotEnabled"))), pushTestResult.message ? (0, react.createElement)("p", { className: "pbb-diag" }, pushTestResult.message) : null, pushTestResult.results.map((r, index) => (0, react.createElement)("p", {
|
|
4632
4780
|
className: "pbb-diag",
|
|
4633
4781
|
key: String(index)
|
|
4634
|
-
}, (r.outcome === "sent" ? "✓ " : "✗ ") + r.name + " [" + r.environment + "] — " + r.outcome + (r.reason ? "(" + r.reason + ")" : "") + (r.tokenFingerprint ? " token:" + r.tokenFingerprint + "…" : "")))))), report === null ? null : (0, react.createElement)("details", { className: "pbb-card pbb-disclosure" }, (0, react.createElement)("summary", null, (0, react.createElement)("span", { className: "pbb-disclosureTitle" }, translateWith(props.t, "system.summary")), (0, react.createElement)("span", { className: "pbb-disclosureMeta" }, "v" + report.pluginVersion)), (0, react.createElement)("div", { className: "pbb-disclosureBody" }, (0, react.createElement)("div", { className: "pbb-sectionIntro" }, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "system.title")), (0, react.createElement)("p", { className: "pbb-cardDescription" }, translateWith(props.t, "system.description"))), (0, react.createElement)("div", { className: "pbb-runtimeList" }, (0, react.createElement)("div", { className: "pbb-runtimeRow" }, (0, react.createElement)("span", { className: "pbb-label" }, "DeepPilot"), (0, react.createElement)("span", { className: "pbb-value" }, "v" + report.pluginVersion)), advancedRows, report.updateAvailable === true ? (0, react.createElement)("div", { className: "pbb-updateRow" }, (0, react.createElement)("span", null, translateWith(props.t, "update.badge")), (0, react.createElement)("a", {
|
|
4782
|
+
}, (r.outcome === "sent" ? "✓ " : "✗ ") + r.name + " [" + r.environment + "] — " + r.outcome + (r.reason ? "(" + r.reason + ")" : "") + (r.tokenFingerprint ? " token:" + r.tokenFingerprint + "…" : "")))), diagnosticsSection)), report === null ? null : (0, react.createElement)("details", { className: "pbb-card pbb-disclosure" }, (0, react.createElement)("summary", null, (0, react.createElement)("span", { className: "pbb-disclosureTitle" }, translateWith(props.t, "system.summary")), (0, react.createElement)("span", { className: "pbb-disclosureMeta" }, "v" + report.pluginVersion)), (0, react.createElement)("div", { className: "pbb-disclosureBody" }, (0, react.createElement)("div", { className: "pbb-sectionIntro" }, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "system.title")), (0, react.createElement)("p", { className: "pbb-cardDescription" }, translateWith(props.t, "system.description"))), (0, react.createElement)("div", { className: "pbb-runtimeList" }, (0, react.createElement)("div", { className: "pbb-runtimeRow" }, (0, react.createElement)("span", { className: "pbb-label" }, "DeepPilot"), (0, react.createElement)("span", { className: "pbb-value" }, "v" + report.pluginVersion)), advancedRows, report.updateAvailable === true ? (0, react.createElement)("div", { className: "pbb-updateRow" }, (0, react.createElement)("span", null, translateWith(props.t, "update.badge")), (0, react.createElement)("a", {
|
|
4635
4783
|
className: "pbb-action pbb-buttonPrimary",
|
|
4636
4784
|
href: typeof report.releaseUrl === "string" && /^https:\/\//.test(report.releaseUrl) ? report.releaseUrl : "https://github.com/Mars-Sea/dsh-deeppilot/releases",
|
|
4637
4785
|
target: "_blank",
|