Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ai-memory/feature-server-only-file-watching-55c4316/init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Feature: Server-Only File Watching Setting

## User Request
Add a new user setting `serverOnlyFileWatching` (boolean, default: false) that controls whether nodemon watches only server files, so client-only changes via git pull don't restart the server.

## Requirements
1. New user setting in `user-settings.json` and defaults
2. Launcher script `scripts/dev-server.js` that reads the setting and spawns nodemon accordingly
3. Settings UI toggle in the client settings panel
4. Follows existing patterns for server-persisted settings
17 changes: 17 additions & 0 deletions ai-memory/feature-server-only-file-watching-55c4316/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Implementation Plan

## Files to modify
1. `server/userSettingsService.js` - Add `serverOnlyFileWatching` to `getDefaultSettings()` under `global`
2. `user-settings.default.json` - Add the default setting
3. `scripts/dev-server.js` - New launcher script (reads setting, spawns nodemon)
4. `package.json` - Point `dev:server` at the launcher
5. `client/index.html` - Add toggle to settings panel
6. `client/app.js` - Add event listener + sync for the toggle

## Implementation order
1. Add setting to defaults (server + default JSON)
2. Create launcher script
3. Update package.json
4. Add UI toggle
5. Syntax check + test
6. Commit, push, PR
10 changes: 10 additions & 0 deletions ai-memory/feature-server-only-file-watching-55c4316/progress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Progress

- [x] Add setting to server defaults
- [x] Add setting to user-settings.default.json
- [x] Create scripts/dev-server.js launcher
- [x] Update package.json dev:server script
- [x] Add UI toggle in settings panel
- [x] Add event listener + sync in app.js
- [x] Syntax check
- [ ] Commit, push, PR
13 changes: 13 additions & 0 deletions client/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2444,6 +2444,14 @@ class ClaudeOrchestrator {
});
}

// Server-only file watching (server-persisted, requires dev:server restart)
const serverOnlyFileWatching = document.getElementById('server-only-file-watching');
if (serverOnlyFileWatching) {
serverOnlyFileWatching.addEventListener('change', async (e) => {
await this.updateGlobalUserSetting('serverOnlyFileWatching', !!e.target.checked);
});
}

// Discord services auto-start (server-persisted)
const discordAutoEnsure = document.getElementById('discord-auto-ensure-services');
if (discordAutoEnsure) {
Expand Down Expand Up @@ -14995,6 +15003,11 @@ class ClaudeOrchestrator {
}
this.applySimpleModeConfig();

const serverOnlyFileWatching = document.getElementById('server-only-file-watching');
if (serverOnlyFileWatching) {
serverOnlyFileWatching.checked = this.userSettings.global?.serverOnlyFileWatching === true;
}

const discordAutoEnsure = document.getElementById('discord-auto-ensure-services');
if (discordAutoEnsure) {
const cfg = this.userSettings.global?.ui?.discord || {};
Expand Down
11 changes: 11 additions & 0 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,17 @@ <h4>Projects + Chats</h4>
</div>
</div>

<div class="setting-section">
<h4>Developer</h4>
<div class="setting-group">
<label>
<input type="checkbox" id="server-only-file-watching" />
Server-only file watching
</label>
<p class="setting-description">Only restart server when server files change. Client changes take effect on browser refresh.</p>
</div>
</div>

<div class="setting-section settings-glossary">
<h4>Glossary</h4>
<p class="setting-description">A quick mental model for how the Orchestrator is structured.</p>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "server/index.js",
"scripts": {
"start": "npm run dev",
"dev:server": "node scripts/ensure-pty.js && nodemon server/index.js",
"dev:server": "node scripts/ensure-pty.js && node scripts/dev-server.js",
"dev:client": "node client/dev-server.js",
"dev:diff": "cd diff-viewer && npm run dev",
"tauri": "tauri",
Expand Down
48 changes: 48 additions & 0 deletions scripts/dev-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env node

const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');

const projectRoot = path.resolve(__dirname, '..');

function loadServerOnlyFileWatching() {
const settingsPath = process.env.ORCHESTRATOR_USER_SETTINGS_PATH
|| path.join(projectRoot, 'user-settings.json');

try {
if (fs.existsSync(settingsPath)) {
const data = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
return data?.global?.serverOnlyFileWatching === true;
}
} catch {
// Fall through to default
}
return false;
}

const serverOnly = loadServerOnlyFileWatching();

const nodemonBin = path.join(projectRoot, 'node_modules', '.bin', 'nodemon');
const args = [];

if (serverOnly) {
// Explicit watch list overrides nodemon.json watch config
args.push('--watch', 'server/', '--watch', '.env');
}

args.push('server/index.js');

if (process.argv.includes('--dry-run')) {
console.log('serverOnlyFileWatching:', serverOnly);
console.log('command:', nodemonBin, args.join(' '));
process.exit(0);
}

const child = spawn(nodemonBin, args, {
cwd: projectRoot,
stdio: 'inherit',
env: process.env
});

child.on('exit', (code) => process.exit(code ?? 1));
4 changes: 4 additions & 0 deletions server/userSettingsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class UserSettingsService {
terminal: {
// Add other global terminal settings here in the future
},
serverOnlyFileWatching: false,
process: {
status: {
lookbackHours: 24,
Expand Down Expand Up @@ -595,6 +596,9 @@ class UserSettingsService {
if (userSettings.global.terminal) {
Object.assign(merged.global.terminal, userSettings.global.terminal);
}
if (typeof userSettings.global.serverOnlyFileWatching === 'boolean') {
merged.global.serverOnlyFileWatching = userSettings.global.serverOnlyFileWatching;
}
if (userSettings.global.process) {
const procDefaults = (merged.global.process || {});
const proc = userSettings.global.process || {};
Expand Down
1 change: 1 addition & 0 deletions user-settings.default.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"delay": 500
},
"terminal": {},
"serverOnlyFileWatching": false,
"scheduler": {
"enabled": false,
"tickSeconds": 30,
Expand Down
Loading