Merge pull request #727: fix: don't point the image watcher at a remote session's directory

This commit is contained in:
Codeman maintainer committed 2026-10-28 09:10:06 +01:00
commit 9fec26009f
6 files changed
+217 -8

No files matched your search

+14 -3
View File
@@ -2709,7 +2709,10 @@ Object.assign(CodemanApp.prototype, {
// Git: the session's own choice if it has one, otherwise the app setting. updateGitFetchStatus is also
// what SSE calls when a scheduled run lands, so the rows stay current while the modal is open.
this.updateGitFetchStatus(sessionId);
document.getElementById('modalImageWatcherEnabled').checked = session.imageWatcherEnabled ?? true;
const imageWatcherToggle = document.getElementById('modalImageWatcherEnabled');
imageWatcherToggle.checked = session.imageWatcherEnabled ?? true;
// The server never watches a remote session's directory (it is on another host), so the row is hidden.
imageWatcherToggle.closest('.set-row').style.display = session.remote ? 'none' : '';
document.getElementById('modalFlickerFilterEnabled').checked = session.flickerFilterEnabled ?? false;
// Populate session name input with prefix/suffix split
@@ -3149,9 +3152,17 @@ Object.assign(CodemanApp.prototype, {
async toggleSessionImageWatcher() {
if (!this.editingSessionId) return;
const enabled = document.getElementById('modalImageWatcherEnabled').checked;
const toggle = document.getElementById('modalImageWatcherEnabled');
const enabled = toggle.checked;
try {
await this._apiPost(`/api/sessions/${this.editingSessionId}/image-watcher`, { enabled });
const res = await this._apiPost(`/api/sessions/${this.editingSessionId}/image-watcher`, { enabled });
// `_apiPost` hands back the Response without checking it, so a refused request (a 400) must not
// read as a save: put the switch back and say so.
if (!res?.ok) {
toggle.checked = !enabled;
this.showToast('Failed to toggle image watcher', 'error');
return;
}
// Update local session state
const session = this.sessions.get(this.editingSessionId);
if (session) {
+5
View File
@@ -3780,6 +3780,11 @@ export function registerSessionRoutes(
const { id } = req.params as { id: string };
const body = parseBody(ImageWatcherSchema, req.body, 'Invalid request body');
const session = findSessionOrFail(ctx, id, req);
// A remote session's workingDir is a path on the remote host; the watcher would watch it on the
// LOCAL disk (a missing folder, or a same-named local one whose images are not the session's).
if (body.enabled && session.remote) {
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Image watching does not run for remote sessions');
}
if (body.enabled) {
imageWatcher.watchSession(session.id, session.workingDir);
+3 -2
View File
@@ -1183,9 +1183,10 @@ export function registerSystemRoutes(
// Handle image watcher toggle dynamically
toggleService((merged.imageWatcherEnabled as boolean) ?? false, imageWatcher, 'Image watcher', () => {
// Re-watch all active sessions that have image watcher enabled
// Re-watch all active sessions that have image watcher enabled (never a remote session: its
// workingDir is a path on the remote host, not on this disk)
for (const session of ctx.sessions.values()) {
if (session.imageWatcherEnabled) {
if (session.imageWatcherEnabled && !session.remote) {
imageWatcher.watchSession(session.id, session.workingDir);
}
}
+4 -2
View File
@@ -2069,8 +2069,10 @@ export class WebServer extends EventEmitter {
session.ralphTracker.setWorkingDir(session.workingDir);
}
// Start watching for new images in this session's working directory (if enabled globally and per-session)
if ((await this.isImageWatcherEnabled()) && session.imageWatcherEnabled) {
// Start watching for new images in this session's working directory (if enabled globally and per-session).
// A remote session's workingDir is a path on the remote host, and the watcher watches it on the LOCAL
// disk, so it is skipped there (the per-session and app-wide toggles skip it too).
if ((await this.isImageWatcherEnabled()) && session.imageWatcherEnabled && !session.remote) {
imageWatcher.watchSession(session.id, session.workingDir);
}