conductor-remote 1.23.1 → 1.24.0

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/dist/index.html CHANGED
@@ -13,7 +13,7 @@
13
13
  <title>Conductor Remote</title>
14
14
  <!-- Runs before the module bundle so it can catch a stale shell that fails to boot. -->
15
15
  <script src="/self-heal.js"></script>
16
- <script type="module" crossorigin src="/assets/index-CX1BZrqn.js"></script>
16
+ <script type="module" crossorigin src="/assets/index-CKMPOrHs.js"></script>
17
17
  <link rel="stylesheet" crossorigin href="/assets/index-D6B0k-tm.css">
18
18
  <link rel="manifest" href="/manifest.webmanifest"></head>
19
19
  <body>
package/dist/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let e,i={};const n=(n,s)=>(n=new URL(n+".js",s).href,i[n]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=i,document.head.appendChild(e)}else e=n,importScripts(n),i()}).then(()=>{let e=i[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(s,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(i[o])return;let l={};const t=e=>n(e,o),c={module:{uri:o},exports:l,require:t};i[o]=Promise.all(s.map(e=>c[e]||t(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"index.html",revision:"a35984f0f5f739ab71b95687496126d1"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-D6B0k-tm.css",revision:null},{url:"assets/index-CX1BZrqn.js",revision:null},{url:"apple-touch-icon.png",revision:"2b9301416b880d45d4bb655f2600d1f2"},{url:"icon-192.png",revision:"c5e01ac58768627e18ee7b8b6a9239ef"},{url:"icon-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon-maskable-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon.svg",revision:"c1aee186821798733dd477e69a0ef243"},{url:"manifest.webmanifest",revision:"cf88fbc5755108a7fe0616fa160a8a15"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"),{denylist:[/^\/api\//]}))});
1
+ if(!self.define){let e,i={};const s=(s,n)=>(s=new URL(s+".js",n).href,i[s]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=i,document.head.appendChild(e)}else e=s,importScripts(s),i()}).then(()=>{let e=i[s];if(!e)throw new Error(`Module ${s} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(i[o])return;let l={};const t=e=>s(e,o),c={module:{uri:o},exports:l,require:t};i[o]=Promise.all(n.map(e=>c[e]||t(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"index.html",revision:"73af7d827d5e4e46f01875f350c4cd1d"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-D6B0k-tm.css",revision:null},{url:"assets/index-CKMPOrHs.js",revision:null},{url:"apple-touch-icon.png",revision:"2b9301416b880d45d4bb655f2600d1f2"},{url:"icon-192.png",revision:"c5e01ac58768627e18ee7b8b6a9239ef"},{url:"icon-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon-maskable-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon.svg",revision:"c1aee186821798733dd477e69a0ef243"},{url:"manifest.webmanifest",revision:"cf88fbc5755108a7fe0616fa160a8a15"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"),{denylist:[/^\/api\//]}))});
@@ -0,0 +1,69 @@
1
+ // `conductor-remote nosleep [duration]` — keep this Mac fully awake, including with
2
+ // the lid closed, so the relay stays reachable and AppleScript sends can reach
3
+ // Conductor while you're away from the desk.
4
+ //
5
+ // The lever is `pmset -a disablesleep 1` (root): unlike a `caffeinate` idle
6
+ // assertion — which does NOT prevent lid-close/clamshell sleep on battery — this
7
+ // keeps the system genuinely awake with the lid shut. It needs sudo, so this is a
8
+ // FOREGROUND command (sudo prompts for your password on this terminal); the
9
+ // background LaunchAgent has no TTY and can't do it. The whole awake window runs
10
+ // inside one root shell whose EXIT/INT/TERM trap restores `disablesleep 0`, so
11
+ // Ctrl-C, a timeout, or a crash can't leave the Mac unable to sleep.
12
+ //
13
+ // Caveat: keeping the system awake lid-closed is necessary but may not be
14
+ // sufficient for AppleScript *delivery* — a closed lid with no display can leave
15
+ // the window server non-drivable (fix: a virtual/dummy display), and a locked
16
+ // screen blocks `activate`. If a send still doesn't land with nosleep on, that's
17
+ // the graphics surface, not power. Strip-clean (plain-node type-stripping),
18
+ // stdlib-only — see CLAUDE.md.
19
+ import { spawn } from 'node:child_process';
20
+ /** Parse `90m` / `2h` / `30s` / bare seconds into seconds; null = run until Ctrl-C. */
21
+ function parseDuration(raw) {
22
+ if (!raw)
23
+ return null;
24
+ const m = raw.match(/^(\d+)(s|m|h)?$/);
25
+ if (!m) {
26
+ console.error(`nosleep: bad duration "${raw}" — use e.g. 90m, 2h, 30s, or a number of seconds`);
27
+ process.exit(1);
28
+ }
29
+ const n = Number(m[1]);
30
+ const unit = m[2] ?? 's';
31
+ return unit === 'h' ? n * 3600 : unit === 'm' ? n * 60 : n;
32
+ }
33
+ function main() {
34
+ if (process.platform !== 'darwin') {
35
+ console.error('nosleep: macOS only (uses pmset).');
36
+ process.exit(1);
37
+ }
38
+ const arg = process.argv[2];
39
+ const seconds = parseDuration(arg);
40
+ // Do everything as a single root shell: set the keep-awake, then either sleep for
41
+ // the duration or idle forever, and ALWAYS restore on exit via the trap. One sudo
42
+ // prompt covers set + restore, and the trap fires even on Ctrl-C / kill. Mirror the
43
+ // proven battery setup — disablesleep + standby + Power Nap off — so the system
44
+ // stays genuinely awake (not just idle-awake) with the lid shut.
45
+ const sleepStep = seconds !== null ? `sleep ${seconds}` : 'while :; do sleep 86400; done';
46
+ const set = 'pmset -a disablesleep 1 standby 0 powernap 0';
47
+ const restore = 'pmset -a disablesleep 0 standby 1 powernap 1';
48
+ const script = `${set} && trap '${restore}' EXIT INT TERM && ${sleepStep}`;
49
+ console.info('conductor-remote nosleep — keeping this Mac awake (incl. lid-closed system sleep).');
50
+ console.info(seconds !== null ? `Duration: ${arg} — Ctrl-C to stop early.` : 'Runs until you press Ctrl-C.');
51
+ // Be honest: this handles sleep only. It does NOT enable sending with the lid shut
52
+ // on its own — that also needs the screen lock off (System Settings ▸ Lock Screen;
53
+ // yours is set to lock immediately) and possibly a virtual display.
54
+ console.info('Note: sleep only — lid-closed *sending* also needs the screen lock off.');
55
+ console.info('sudo will ask for your password…\n');
56
+ const child = spawn('sudo', ['sh', '-c', script], { stdio: 'inherit' });
57
+ // Forward Ctrl-C / termination so the root shell's trap restores sleep before we go.
58
+ const forward = (sig) => () => child.kill(sig);
59
+ process.on('SIGINT', forward('SIGINT'));
60
+ process.on('SIGTERM', forward('SIGTERM'));
61
+ child.on('exit', (code, signal) => {
62
+ if (code === 0 || signal)
63
+ console.info('\nSleep restored — the Mac can sleep normally again.');
64
+ else
65
+ console.error(`\nnosleep exited with code ${code}. If sleep is still disabled, run: sudo pmset -a disablesleep 0`);
66
+ process.exit(code ?? 0);
67
+ });
68
+ }
69
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conductor-remote",
3
- "version": "1.23.1",
3
+ "version": "1.24.0",
4
4
  "type": "module",
5
5
  "packageManager": "yarn@4.15.0",
6
6
  "description": "Phone control panel for local Conductor agents. Reads ride SQLite + git; prompts ride Conductor's own dispatch path.",