conductor-remote 1.34.3 → 1.35.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.
@@ -80,6 +80,44 @@ const TERMINAL_ERRORS = [
80
80
  export function retryWontHelp(error) {
81
81
  return error !== undefined && TERMINAL_ERRORS.some(phrase => error.includes(phrase));
82
82
  }
83
+ /**
84
+ * A send that failed because the Mac's screen is locked. Deliberately *not* in
85
+ * `TERMINAL_ERRORS`: it isn't terminal (an unlock fixes it) but it also isn't a
86
+ * warm-up cost a retry loop should burn budget on — the caller parks the prompt
87
+ * instead (src/parked.ts) and the queue delivers it when the lock lifts. Matched
88
+ * on the phrase every lock refusal in conductor.applescript starts with; the
89
+ * words are ours, so they can't drift under us the way macOS's can.
90
+ */
91
+ export function lockBlocked(error) {
92
+ return (error ?? '').includes('The Mac is locked');
93
+ }
94
+ /**
95
+ * Node's own read of the lock screen — the same CGSessionCopyCurrentDictionary
96
+ * probe `screenLocked()` in conductor.applescript makes, minus the AppleScript
97
+ * wrapper, so the parked-prompt queue can poll it without spinning up a whole
98
+ * UI script (and without needing Accessibility at all). `null` means the probe
99
+ * itself failed — callers should treat that as "try the send and let it tell
100
+ * you", not as either lock state.
101
+ */
102
+ export async function screenLocked() {
103
+ // Keep in lockstep with `screenLocked()` in conductor.applescript, traps and
104
+ // all: $.CFBridgingRelease segfaults under JXA, and without the bindFunction
105
+ // rebind deepUnwrap reads the CF dictionary as undefined — a silent "unlocked"
106
+ // on a locked Mac.
107
+ const jxa = "ObjC.import('CoreGraphics'); ObjC.bindFunction('CGSessionCopyCurrentDictionary', ['id', []]); const d = ObjC.deepUnwrap($.CGSessionCopyCurrentDictionary()) || {}; d.CGSSessionScreenIsLocked ? 'locked' : 'unlocked'";
108
+ try {
109
+ const { stdout } = await exec('osascript', ['-l', 'JavaScript', '-e', jxa], { timeout: 5_000 });
110
+ const out = stdout.trim();
111
+ if (out === 'locked')
112
+ return true;
113
+ if (out === 'unlocked')
114
+ return false;
115
+ return null;
116
+ }
117
+ catch {
118
+ return null;
119
+ }
120
+ }
83
121
  /**
84
122
  * The sidecar IPC path — the precise, per-session write. Delivers straight to
85
123
  * `sessionId` over Conductor's own dispatch socket (see sidecar.ts), so it needs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conductor-remote",
3
- "version": "1.34.3",
3
+ "version": "1.35.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.",