dsh-zen-remote 2.3.6 → 2.3.7

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 (66) hide show
  1. package/AGENTS.md +15 -5
  2. package/CHANGELOG.md +71 -0
  3. package/README.md +2 -2
  4. package/README.zh-CN.md +2 -2
  5. package/docs/interface.md +10 -4
  6. package/docs/remote-access.en.md +6 -0
  7. package/docs/remote-access.md +6 -0
  8. package/lan-gate.mjs +7 -0
  9. package/lib/client-pairing.js +10 -0
  10. package/lib/client-pairing.js.map +1 -1
  11. package/lib/client-routes.js +183 -94
  12. package/lib/client-routes.js.map +1 -1
  13. package/lib/client.js +505 -78
  14. package/lib/debug-redact.js +253 -0
  15. package/lib/debug-redact.js.map +1 -0
  16. package/lib/debug-report.js +60 -0
  17. package/lib/debug-report.js.map +1 -0
  18. package/lib/fetch-route-intercept.js +23 -0
  19. package/lib/fetch-route-intercept.js.map +1 -1
  20. package/lib/index.js +293 -45
  21. package/lib/index.js.map +1 -1
  22. package/lib/log-ring.js +76 -0
  23. package/lib/log-ring.js.map +1 -0
  24. package/lib/types/client/effects/remote-drop.d.ts +20 -8
  25. package/lib/types/client/effects/remote-drop.d.ts.map +1 -1
  26. package/lib/types/client/locales.d.ts +8 -1
  27. package/lib/types/client/locales.d.ts.map +1 -1
  28. package/lib/types/client/settings/SettingsSection.d.ts.map +1 -1
  29. package/lib/types/client/styles/misc.css.d.ts +1 -1
  30. package/lib/types/client/styles/misc.css.d.ts.map +1 -1
  31. package/lib/types/client-data/remote-drop.d.ts +64 -0
  32. package/lib/types/client-data/remote-drop.d.ts.map +1 -1
  33. package/lib/types/client-data/settings-form.d.ts +3 -0
  34. package/lib/types/client-data/settings-form.d.ts.map +1 -1
  35. package/lib/types/client-pairing.d.ts +8 -0
  36. package/lib/types/client-pairing.d.ts.map +1 -1
  37. package/lib/types/client-routes.d.ts +23 -0
  38. package/lib/types/client-routes.d.ts.map +1 -1
  39. package/lib/types/debug-redact.d.ts +68 -0
  40. package/lib/types/debug-redact.d.ts.map +1 -0
  41. package/lib/types/debug-report.d.ts +58 -0
  42. package/lib/types/debug-report.d.ts.map +1 -0
  43. package/lib/types/fetch-route-intercept.d.ts +26 -0
  44. package/lib/types/fetch-route-intercept.d.ts.map +1 -1
  45. package/lib/types/index.d.ts +7 -1
  46. package/lib/types/index.d.ts.map +1 -1
  47. package/lib/types/log-ring.d.ts +57 -0
  48. package/lib/types/log-ring.d.ts.map +1 -0
  49. package/package.json +3 -2
  50. package/pwa/app.css +13 -2
  51. package/scripts/check-debug-report.mjs +277 -0
  52. package/scripts/check-remote-drop.mjs +130 -0
  53. package/scripts/check-tablet-safe-area.mjs +49 -0
  54. package/src/client/effects/remote-drop.ts +271 -24
  55. package/src/client/locales.ts +20 -4
  56. package/src/client/settings/SettingsSection.tsx +120 -3
  57. package/src/client/styles/misc.css.ts +38 -0
  58. package/src/client-data/remote-drop.ts +103 -0
  59. package/src/client-data/settings-form.ts +3 -0
  60. package/src/client-pairing.ts +11 -0
  61. package/src/client-routes.ts +196 -90
  62. package/src/debug-redact.ts +290 -0
  63. package/src/debug-report.ts +93 -0
  64. package/src/fetch-route-intercept.ts +29 -0
  65. package/src/index.ts +282 -43
  66. package/src/log-ring.ts +101 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * CU-1: the plugin's in-process diagnostic log ring (SPEC §方案 C). A bounded
3
+ * FIFO of the plugin row's own log lines, kept in memory only — the desktop
4
+ * app writes no log file, so this is the one artifact the debug report (CU-2)
5
+ * can read on either role. Deliberately NOT a file, and deliberately only
6
+ * this plugin's lines: DSH's own log stream stays untouched.
7
+ *
8
+ * Pure module: no DSH imports, no I/O, no clocks beyond the timestamp it
9
+ * stamps entries with. The wiring lives in src/index.ts, which funnels its
10
+ * `logWarn` / `logInfo` through {@link createPluginLog} so existing call
11
+ * sites enter the ring unchanged (double write: logger first, ring second),
12
+ * and pushes the handful of lifecycle events (row apply/reload, gateway
13
+ * spawn/exit, relay link flips, fetch-route installs) by hand.
14
+ *
15
+ * One discipline the debug report leans on: ring lines carry event codes,
16
+ * id shapes and counters — never payloads. The redactor (debug-redact.ts)
17
+ * is the second layer, not the license to log secrets here.
18
+ */
19
+
20
+ import { format } from 'node:util'
21
+
22
+ /** Severity of one ring entry. The ring only distinguishes what the report
23
+ * renders: info lines and warnings. */
24
+ export type LogLevel = 'info' | 'warn'
25
+
26
+ /** One ring entry: ISO timestamp, level, fully interpolated message. */
27
+ export interface LogRingEntry {
28
+ t: string
29
+ level: LogLevel
30
+ msg: string
31
+ }
32
+
33
+ /** Longest message kept, in characters (UTF-16 code units). Debug lines are
34
+ * codes and shapes, not dumps — anything longer was the wrong thing to log. */
35
+ const MAX_MSG_CHARS = 512
36
+
37
+ /** The ring's face. `push` never throws and never returns anything; callers
38
+ * log through it exactly like they would through the context logger. */
39
+ export interface LogRing {
40
+ push(level: LogLevel, formatText: string, ...args: unknown[]): void
41
+ /** Oldest-last copy of the ring. Mutating the returned array or its
42
+ * entries never reaches the ring's own state. */
43
+ snapshot(): LogRingEntry[]
44
+ }
45
+
46
+ /**
47
+ * Create one bounded log ring. `cap` defaults to 300 entries — a full debug
48
+ * session of lifecycle lines plus a healthy share of warnings, while keeping
49
+ * the report a fixed small size. A cap below 1 is clamped to 1.
50
+ */
51
+ export function createLogRing(cap = 300): LogRing {
52
+ const capacity = Number.isFinite(cap) && cap >= 1 ? Math.floor(cap) : 1
53
+ const entries: LogRingEntry[] = []
54
+ return {
55
+ push(level, formatText, ...args) {
56
+ let msg: string
57
+ try {
58
+ msg = args.length === 0 ? String(formatText) : format(formatText, ...args)
59
+ } catch {
60
+ // A malformed format string must never break the caller's flow —
61
+ // keep the raw template as the message.
62
+ msg = String(formatText)
63
+ }
64
+ if (msg.length > MAX_MSG_CHARS) msg = msg.slice(0, MAX_MSG_CHARS)
65
+ entries.push({ t: new Date().toISOString(), level, msg })
66
+ if (entries.length > capacity) entries.splice(0, entries.length - capacity)
67
+ },
68
+ snapshot() {
69
+ return entries.map((entry) => ({ ...entry }))
70
+ },
71
+ }
72
+ }
73
+
74
+ /** The logger face this module needs: the cordis context logger's two
75
+ * methods, each optional (test fakes carry none). */
76
+ export interface PluginLogLike {
77
+ info?(format: string, ...args: unknown[]): void
78
+ warn?(format: string, ...args: unknown[]): void
79
+ }
80
+
81
+ /** The double-writer the apply() wiring funnels its logging through: every
82
+ * line reaches the context logger (unchanged behavior, unchanged call
83
+ * sites) AND the ring (the debug report's source). A ring failure is
84
+ * swallowed; a logger failure propagates exactly as it did before this
85
+ * module existed. */
86
+ export function createPluginLog(ring: LogRing, logger: PluginLogLike | undefined): { info(format: string, ...args: unknown[]): void, warn(format: string, ...args: unknown[]): void } {
87
+ return {
88
+ info(formatText, ...args) {
89
+ logger?.info?.(formatText, ...args)
90
+ try {
91
+ ring.push('info', formatText, ...args)
92
+ } catch { /* the ring must never break logging */ }
93
+ },
94
+ warn(formatText, ...args) {
95
+ logger?.warn?.(formatText, ...args)
96
+ try {
97
+ ring.push('warn', formatText, ...args)
98
+ } catch { /* the ring must never break logging */ }
99
+ },
100
+ }
101
+ }