From 7297f7c339186f8af50f4f0ed3734e4ad4b47aed Mon Sep 17 00:00:00 2001 From: haoyuren <13851610112@163.com> Date: Thu, 30 Jul 2026 09:00:55 +0800 Subject: Cross-platform support: Windows build target and CI release workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Normalize watcher paths to forward slashes (Windows events use backslashes; all sync maps are '/'-keyed), path.delimiter for PATH/TEXINPUTS, dirname() instead of '/'-substring splits, bridge log in os.tmpdir() - Platform-aware TeX search paths (TeX Live / MiKTeX on Windows), terminal shell default (COMSPEC/powershell), native window frame off macOS - electron-builder: NSIS target + win icon + GitHub publish provider - GitHub Actions workflow builds the Windows installer on tag push (node-pty needs MSVC — cannot cross-compile from macOS) and attaches it to the release Co-Authored-By: Claude Fable 5 --- src/main/fileSyncBridge.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/main/fileSyncBridge.ts') diff --git a/src/main/fileSyncBridge.ts b/src/main/fileSyncBridge.ts index 3072ae6..ae22eb8 100644 --- a/src/main/fileSyncBridge.ts +++ b/src/main/fileSyncBridge.ts @@ -2,7 +2,8 @@ // Licensed under AGPL-3.0 - see LICENSE file // Bidirectional file sync bridge: temp dir ↔ Overleaf via OT (text) + REST (binary) -import { join, dirname } from 'path' +import { join, dirname, relative, sep } from 'path' +import { tmpdir } from 'os' import { existsSync } from 'fs' import { readFile, writeFile, mkdir, unlink, rename as fsRename, appendFile, readdir, rm } from 'fs/promises' import { createHash } from 'crypto' @@ -16,7 +17,7 @@ import type { OtOp } from './otTypes' import { isInsert, isDelete } from './otTypes' const dmp = new diff_match_patch() -const LOG_FILE = '/tmp/lattex-bridge.log' +const LOG_FILE = join(tmpdir(), 'lattex-bridge.log') function bridgeLog(msg: string, ...rest: unknown[]) { const line = `[${new Date().toISOString()}] ${msg}${rest.length ? ' ' + rest.map(String).join(' ') : ''}` console.log(line) @@ -225,7 +226,7 @@ export class FileSyncBridge { }, 60_000) this.watcher.on('change', (absPath: string) => { - const relPath = absPath.replace(this.tmpDir + '/', '') + const relPath = this.relFromAbs(absPath) bridgeLog(`[FileSyncBridge] chokidar change: ${relPath}`) // A real fs event means new content — give parked failures a fresh chance this.permanentFailures.delete(relPath) @@ -237,7 +238,7 @@ export class FileSyncBridge { }) this.watcher.on('add', (absPath: string) => { - const relPath = absPath.replace(this.tmpDir + '/', '') + const relPath = this.relFromAbs(absPath) bridgeLog(`[FileSyncBridge] chokidar add: ${relPath}`) this.permanentFailures.delete(relPath) if (this.pathDocMap[relPath] || this.pathFileRefMap[relPath]) { @@ -250,7 +251,7 @@ export class FileSyncBridge { }) this.watcher.on('unlink', (absPath: string) => { - const relPath = absPath.replace(this.tmpDir + '/', '') + const relPath = this.relFromAbs(absPath) bridgeLog(`[FileSyncBridge] chokidar unlink: ${relPath}`) }) @@ -1478,6 +1479,12 @@ export class FileSyncBridge { } } + /** Absolute watcher path → project-relative path with forward slashes + (Windows watcher events use backslashes; all maps are '/'-keyed) */ + private relFromAbs(absPath: string): string { + return relative(this.tmpDir, absPath).split(sep).join('/') + } + // ── Compile-artifact detection ─────────────────────────────── /** Register a file our own local compile will write (e.g. root main.pdf) */ -- cgit v1.2.3