nightytidy 0.2.6 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/agent/index.js +7 -1
- package/src/agent/keep-awake.js +60 -0
package/package.json
CHANGED
package/src/agent/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import { WebhookDispatcher } from './webhook-dispatcher.js';
|
|
|
12
12
|
import { CliBridge } from './cli-bridge.js';
|
|
13
13
|
import { AgentGit } from './git-integration.js';
|
|
14
14
|
import { FirebaseAuth } from './firebase-auth.js';
|
|
15
|
+
import { acquireKeepAwake, releaseKeepAwake } from './keep-awake.js';
|
|
15
16
|
|
|
16
17
|
const FIREBASE_WEBHOOK_URL = 'https://webhookingest-24h6taciuq-uc.a.run.app';
|
|
17
18
|
|
|
@@ -479,7 +480,10 @@ export async function startAgent() {
|
|
|
479
480
|
|
|
480
481
|
async function processQueue() {
|
|
481
482
|
const run = runQueue.dequeue();
|
|
482
|
-
if (!run)
|
|
483
|
+
if (!run) {
|
|
484
|
+
releaseKeepAwake();
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
483
487
|
|
|
484
488
|
const project = projectManager.getProject(run.projectId);
|
|
485
489
|
if (!project) {
|
|
@@ -497,6 +501,7 @@ export async function startAgent() {
|
|
|
497
501
|
runOutputBuffer = '';
|
|
498
502
|
runProgress = { stepList: [], completedCount: 0, failedCount: 0, totalCost: 0, currentStepNum: null };
|
|
499
503
|
|
|
504
|
+
acquireKeepAwake();
|
|
500
505
|
info(`\n━━━ Run started: ${project.name} ━━━`);
|
|
501
506
|
info(` Steps: [${run.steps.join(', ')}] (${run.steps.length} total)`);
|
|
502
507
|
info(` Project: ${project.path}`);
|
|
@@ -1036,6 +1041,7 @@ export async function startAgent() {
|
|
|
1036
1041
|
// Graceful shutdown
|
|
1037
1042
|
const shutdown = async () => {
|
|
1038
1043
|
info('Agent shutting down...');
|
|
1044
|
+
releaseKeepAwake();
|
|
1039
1045
|
saveInterruptedState();
|
|
1040
1046
|
scheduler.stopAll();
|
|
1041
1047
|
await wsServer.stop();
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prevents the OS from sleeping while NightyTidy runs are active.
|
|
3
|
+
*
|
|
4
|
+
* Windows: Uses PowerShell to call SetThreadExecutionState with
|
|
5
|
+
* ES_CONTINUOUS | ES_SYSTEM_REQUIRED (0x80000001). This tells Windows
|
|
6
|
+
* "don't sleep, this process needs the system." The flag is automatically
|
|
7
|
+
* cleared when the process exits or when releaseKeepAwake() is called.
|
|
8
|
+
*
|
|
9
|
+
* macOS/Linux: Uses caffeinate / systemd-inhibit respectively.
|
|
10
|
+
*
|
|
11
|
+
* No admin privileges required on any platform.
|
|
12
|
+
*/
|
|
13
|
+
import { execSync, spawn } from 'node:child_process';
|
|
14
|
+
import { debug, warn } from '../logger.js';
|
|
15
|
+
|
|
16
|
+
let keepAwakeProcess = null;
|
|
17
|
+
|
|
18
|
+
export function acquireKeepAwake() {
|
|
19
|
+
if (keepAwakeProcess) return; // already held
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
if (process.platform === 'win32') {
|
|
23
|
+
// PowerShell script that sets ES_CONTINUOUS | ES_SYSTEM_REQUIRED
|
|
24
|
+
// and then sleeps forever. When we kill this process, the flag clears.
|
|
25
|
+
keepAwakeProcess = spawn('powershell', [
|
|
26
|
+
'-NoProfile', '-WindowStyle', 'Hidden', '-Command',
|
|
27
|
+
`Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class SleepPreventer { [DllImport("kernel32.dll")] public static extern uint SetThreadExecutionState(uint esFlags); }'; [SleepPreventer]::SetThreadExecutionState(0x80000001); while($true) { Start-Sleep -Seconds 3600 }`,
|
|
28
|
+
], { stdio: 'ignore', detached: false });
|
|
29
|
+
keepAwakeProcess.unref();
|
|
30
|
+
keepAwakeProcess.on('error', () => { keepAwakeProcess = null; });
|
|
31
|
+
debug('Sleep prevention acquired (Windows SetThreadExecutionState)');
|
|
32
|
+
} else if (process.platform === 'darwin') {
|
|
33
|
+
// macOS: caffeinate prevents sleep, -i = idle sleep, -s = system sleep
|
|
34
|
+
keepAwakeProcess = spawn('caffeinate', ['-is'], { stdio: 'ignore' });
|
|
35
|
+
keepAwakeProcess.unref();
|
|
36
|
+
keepAwakeProcess.on('error', () => { keepAwakeProcess = null; });
|
|
37
|
+
debug('Sleep prevention acquired (macOS caffeinate)');
|
|
38
|
+
} else {
|
|
39
|
+
// Linux: systemd-inhibit (may not exist on all distros)
|
|
40
|
+
keepAwakeProcess = spawn('systemd-inhibit', [
|
|
41
|
+
'--what=idle:sleep', '--who=NightyTidy', '--why=Running codebase improvement',
|
|
42
|
+
'sleep', 'infinity',
|
|
43
|
+
], { stdio: 'ignore' });
|
|
44
|
+
keepAwakeProcess.unref();
|
|
45
|
+
keepAwakeProcess.on('error', () => { keepAwakeProcess = null; });
|
|
46
|
+
debug('Sleep prevention acquired (Linux systemd-inhibit)');
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
warn('Could not acquire sleep prevention — system may sleep during runs');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function releaseKeepAwake() {
|
|
54
|
+
if (!keepAwakeProcess) return;
|
|
55
|
+
try {
|
|
56
|
+
keepAwakeProcess.kill();
|
|
57
|
+
} catch { /* already dead */ }
|
|
58
|
+
keepAwakeProcess = null;
|
|
59
|
+
debug('Sleep prevention released');
|
|
60
|
+
}
|