sotashimozono_obsidian-remo.../plugin/src/util
Souta 45c26c1a6c fix(shadow): address Phase B adversarial review — version-ordered binaries + unhandled rejection
Two real defects an independent review found in Phase B:

BLOCKER — plugin-binary clobber/oscillation. The push diff-gate was
string-equality and the pull was "local authoritative", so a machine on
an OLDER plugin version would overwrite the remote's newer copy (and the
two sides ping-ponged forever). Now VERSION-ORDERED by manifest
`version`: pull only when the remote is strictly newer (or absent
locally), push only when local is strictly newer (or remote lacks it).
Converges, never downgrades. + parseManifestVersion/versionGt helpers.

MAJOR — pre-spawn pull unhandled rejection. When the budget fired first,
`finally` disconnected the client and the in-flight read then threw
"not connected", settling the pull promise a second time after the race
had lost → unhandledrejection in the renderer. The pull now runs as a
standalone promise with a mop-up `.catch` (real-error diagnostics still
flow through the withTimeout race into the existing catch).

Also: withTimeout typed its timer id as `number` (Obsidian renderer DOM)
— `window.setTimeout`'s @types/node overload was leaking `Timeout` and
failing `tsc`. And a clear warning that the round-trip is a UTF-8 TEXT
channel (no binary assets).

Tests rewritten to the version-ordered contract: upgrade, anti-downgrade
(both directions), no-manifest skips, convergence-no-ping-pong, per-plugin
error isolation. Integration test 3 → real-SSH downgrade guard.
tsc + eslint clean; unit suite 1166 pass.

Clean per review: B3 standalone SftpClient does not patch the source
vault, no double-connect leak, B1/B2 ordering correct, backward compat OK.

Refs #429 #342

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 21:38:04 +09:00
..
errorHook.ts chore(plugin): satisfy eslint-plugin-obsidianmd recommended preset (0.4.74) 2026-04-29 16:53:22 +09:00
errorMessage.ts refactor: extract shared errorMessage() and asError() helpers (#195) 2026-05-01 13:34:56 +09:00
fingerprint.ts feat: add named error classes, HostKeyConfirmModal, and shared fingerprint util 2026-05-02 10:33:55 +09:00
logger.ts fix(types): eliminate validator unsafe-* / CSS-portability warnings (#394) 2026-06-09 15:04:58 +09:00
ObservabilityInstaller.ts refactor: extract shared errorMessage() and asError() helpers (#195) 2026-05-01 13:34:56 +09:00
pathUtils.ts fix(rpc): address PR #355 v2 review — pin startRpcSession + honest type 2026-05-18 00:28:26 +09:00
PerfTracer.ts refactor: extract withPerfTrace helper for RpcRemoteFsClient (#196) 2026-05-01 13:37:51 +09:00
redact.ts chore(plugin): satisfy eslint-plugin-obsidianmd recommended preset (0.4.74) 2026-04-29 16:53:22 +09:00
retry.ts chore(deps-dev): integrate dev-deps group + prefer-window-timers fix (1.1.1-beta.1) (#371) 2026-06-08 13:18:07 +09:00
Telemetry.ts chore(deps-dev): integrate dev-deps group + prefer-window-timers fix (1.1.1-beta.1) (#371) 2026-06-08 13:18:07 +09:00
TransferTracker.ts feat: status-bar indicator for large file transfers (#127) 2026-05-03 15:40:00 +09:00
withTimeout.ts fix(shadow): address Phase B adversarial review — version-ordered binaries + unhandled rejection 2026-06-30 21:38:04 +09:00