diff --git a/znai-docs/znai/release-notes/1.91/add-2026-06-01-preview-atomic-write-linux.md b/znai-docs/znai/release-notes/1.91/add-2026-06-01-preview-atomic-write-linux.md new file mode 100644 index 000000000..ee40de06a --- /dev/null +++ b/znai-docs/znai/release-notes/1.91/add-2026-06-01-preview-atomic-write-linux.md @@ -0,0 +1 @@ +* Add: Live preview on Linux now detects files saved via atomic write (write-to-temp then rename), so changes from AI agents are picked up reliably \ No newline at end of file diff --git a/znai-server/src/main/java/org/testingisdocumenting/znai/server/preview/FileWatcher.java b/znai-server/src/main/java/org/testingisdocumenting/znai/server/preview/FileWatcher.java index 799978625..aa8d9fe7d 100644 --- a/znai-server/src/main/java/org/testingisdocumenting/znai/server/preview/FileWatcher.java +++ b/znai-server/src/main/java/org/testingisdocumenting/znai/server/preview/FileWatcher.java @@ -179,7 +179,9 @@ private void register(Path path) { return; } - final WatchKey key = path.register(watchService, new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY}, + // ENTRY_CREATE is required to handle swap in atomic writes + final WatchKey key = path.register(watchService, + new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY}, SensitivityWatchEventModifier.HIGH); pathByKey.put(key, path); diff --git a/znai-server/src/main/java/org/testingisdocumenting/znai/server/preview/PreviewPushFileChangeHandler.java b/znai-server/src/main/java/org/testingisdocumenting/znai/server/preview/PreviewPushFileChangeHandler.java index 704eda7ee..a5620b5a9 100644 --- a/znai-server/src/main/java/org/testingisdocumenting/znai/server/preview/PreviewPushFileChangeHandler.java +++ b/znai-server/src/main/java/org/testingisdocumenting/znai/server/preview/PreviewPushFileChangeHandler.java @@ -137,6 +137,11 @@ private void onMarkupChange(Path path) { private void onDependentChange(Path path) { execute(() -> { + String pathAsString = path.toString(); + if (pathAsString.contains(".md.tmp.") || pathAsString.endsWith(".md.tmp")) { + return; + } + Collection dependentTocItems = previewWebSite.dependentTocItems(path); if (dependentTocItems.isEmpty()) { ConsoleOutputs.out("no markup files depends on ", BLUE, path);