conductor-remote 1.27.1 → 1.27.3
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-
|
|
16
|
+
<script type="module" crossorigin src="/assets/index-DodAVrF-.js"></script>
|
|
17
17
|
<link rel="stylesheet" crossorigin href="/assets/index-DnE5ulTu.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
|
|
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 c={};const l=e=>n(e,o),t={module:{uri:o},exports:c,require:l};i[o]=Promise.all(s.map(e=>t[e]||l(e))).then(e=>(r(...e),c))}}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:"0d9b7c2e83c2d2ac18a82c2accca260a"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-DodAVrF-.js",revision:null},{url:"assets/index-DnE5ulTu.css",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\//]}))});
|
package/dist-node/src/writes.js
CHANGED
|
@@ -67,11 +67,112 @@ on splitLines(s)
|
|
|
67
67
|
return parts
|
|
68
68
|
end splitLines
|
|
69
69
|
|
|
70
|
+
on hasWindow()
|
|
71
|
+
-- Also false when the process itself is gone: "tell process" errors there.
|
|
72
|
+
try
|
|
73
|
+
tell application "System Events" to tell process "Conductor"
|
|
74
|
+
return (count of windows) > 0
|
|
75
|
+
end tell
|
|
76
|
+
on error
|
|
77
|
+
return false
|
|
78
|
+
end try
|
|
79
|
+
end hasWindow
|
|
80
|
+
|
|
81
|
+
on scriptingBlocked()
|
|
82
|
+
-- hasWindow() cannot tell "no window" from "macOS refused us" — it swallows
|
|
83
|
+
-- every error — so without this a missing permission reads as "no open
|
|
84
|
+
-- window" and sends the user off to open a window that is already open.
|
|
85
|
+
-- These are the two separate grants the write path needs: Automation (may we
|
|
86
|
+
-- talk to System Events at all) and Accessibility (may we read the UI tree).
|
|
87
|
+
-- Returns "" when both are in place.
|
|
88
|
+
try
|
|
89
|
+
tell application "System Events" to set axTrusted to (UI elements enabled)
|
|
90
|
+
on error errText number errNum
|
|
91
|
+
return "macOS blocked the relay from controlling the UI (" & errNum & ") - grant Automation permission to the node binary running the relay in System Settings > Privacy & Security > Automation. " & errText
|
|
92
|
+
end try
|
|
93
|
+
if not axTrusted then return "the relay is not trusted for Accessibility - grant it to the node binary running the relay in System Settings > Privacy & Security > Accessibility, then restart the relay (upgrading node silently revokes it)"
|
|
94
|
+
return ""
|
|
95
|
+
end scriptingBlocked
|
|
96
|
+
|
|
97
|
+
on conductorRunning()
|
|
98
|
+
try
|
|
99
|
+
tell application "System Events" to return (exists process "Conductor")
|
|
100
|
+
on error
|
|
101
|
+
return false
|
|
102
|
+
end try
|
|
103
|
+
end conductorRunning
|
|
104
|
+
|
|
105
|
+
on requireWindow()
|
|
106
|
+
-- ASCII on purpose: these reach the phone, and osascript decodes -e by the
|
|
107
|
+
-- caller's locale, which a LaunchAgent doesn't set.
|
|
108
|
+
if my hasWindow() then return
|
|
109
|
+
set blocked to my scriptingBlocked()
|
|
110
|
+
if blocked is not "" then error blocked
|
|
111
|
+
if not (my conductorRunning()) then error "Conductor is not running - the relay started it, but it did not come up in time. Try again in a few seconds."
|
|
112
|
+
error "Conductor has no open window - open it on your Mac and try again"
|
|
113
|
+
end requireWindow
|
|
114
|
+
|
|
115
|
+
on waitForWindow(attempts)
|
|
116
|
+
-- "reopen" is the dock-click event — that is what recreates a closed window;
|
|
117
|
+
-- "activate" on its own does not. Nudge a few times across the wait: a cold
|
|
118
|
+
-- launch can reach "process exists" long before it draws anything.
|
|
119
|
+
repeat with attempt from 1 to attempts
|
|
120
|
+
if my hasWindow() then return true
|
|
121
|
+
if attempt is 2 or attempt is 8 or attempt is 20 then
|
|
122
|
+
try
|
|
123
|
+
tell application "Conductor" to reopen
|
|
124
|
+
tell application "Conductor" to activate
|
|
125
|
+
end try
|
|
126
|
+
end if
|
|
127
|
+
delay 0.25
|
|
128
|
+
end repeat
|
|
129
|
+
return false
|
|
130
|
+
end waitForWindow
|
|
131
|
+
|
|
132
|
+
on activateConductor()
|
|
133
|
+
-- Conductor keeps running with every window closed (standard macOS: the red
|
|
134
|
+
-- button doesn't quit), and it may not be running at all. Both used to surface
|
|
135
|
+
-- as "Can't get window 1 of process Conductor. Invalid index." from whichever
|
|
136
|
+
-- handler happened to run first. So: launch-or-front it ("activate" starts it
|
|
137
|
+
-- when it isn't running), wait for a real window, then say what actually went
|
|
138
|
+
-- wrong in words the phone can act on.
|
|
139
|
+
-- Permissions first: a blocked relay reads as "no process, no window" from
|
|
140
|
+
-- every probe below, and waiting 9s to say the wrong thing helps nobody.
|
|
141
|
+
set blocked to my scriptingBlocked()
|
|
142
|
+
if blocked is not "" then error blocked
|
|
143
|
+
set wasRunning to my conductorRunning()
|
|
144
|
+
try
|
|
145
|
+
tell application "Conductor" to activate
|
|
146
|
+
on error errText
|
|
147
|
+
error "couldn't bring Conductor to the front: " & errText
|
|
148
|
+
end try
|
|
149
|
+
delay 0.4
|
|
150
|
+
-- Patience sized to what we're waiting for. A running app only has to redraw a
|
|
151
|
+
-- window (~4s is plenty, and the caller's osascript timeout still needs room
|
|
152
|
+
-- for the send itself). A cold launch is a whole app start, so it gets ~9s —
|
|
153
|
+
-- still inside the 20s script budget once the send's own delays are counted.
|
|
154
|
+
-- Anything slower fails with the message above and finds a warm app on retry.
|
|
155
|
+
set patience to 16
|
|
156
|
+
if not wasRunning then set patience to 36
|
|
157
|
+
if my waitForWindow(patience) then return
|
|
158
|
+
my requireWindow()
|
|
159
|
+
end activateConductor
|
|
160
|
+
|
|
161
|
+
on webArea()
|
|
162
|
+
-- The webview root: the window, then four nested containers. Guarded, or a
|
|
163
|
+
-- window that closed mid-run reappears as an "Invalid index" from a caller
|
|
164
|
+
-- that has nothing to do with windows.
|
|
165
|
+
my requireWindow()
|
|
166
|
+
tell application "System Events" to tell process "Conductor"
|
|
167
|
+
return UI element 1 of UI element 1 of UI element 1 of UI element 1 of window 1
|
|
168
|
+
end tell
|
|
169
|
+
end webArea
|
|
170
|
+
|
|
70
171
|
on sidebarLinks()
|
|
71
172
|
-- The sidebar rows are AXLinks named "<repo> <title> +adds -dels". They live
|
|
72
173
|
-- two levels under the web area; collect them wherever they are at that depth.
|
|
174
|
+
set wa to my webArea()
|
|
73
175
|
tell application "System Events" to tell process "Conductor"
|
|
74
|
-
set wa to UI element 1 of UI element 1 of UI element 1 of UI element 1 of window 1
|
|
75
176
|
set out to {}
|
|
76
177
|
repeat with a in (UI elements of wa)
|
|
77
178
|
try
|
|
@@ -156,6 +257,7 @@ on tabGroups()
|
|
|
156
257
|
-- Level-order search, returning every tab group at the shallowest depth that
|
|
157
258
|
-- has one (the chat strip and the terminal strip are siblings). Bounded: the
|
|
158
259
|
-- pane sits ~5 levels down, and we must never descend into the transcript.
|
|
260
|
+
my requireWindow()
|
|
159
261
|
tell application "System Events" to tell process "Conductor"
|
|
160
262
|
set level to {window 1}
|
|
161
263
|
set depth to 0
|
|
@@ -483,8 +585,8 @@ on setModel(wanted)
|
|
|
483
585
|
-- otherwise also match "Sonnet 4.6 1M"), which must fail rather than guess.
|
|
484
586
|
set chosen to missing value
|
|
485
587
|
set loose to {}
|
|
588
|
+
set wa to my webArea()
|
|
486
589
|
tell application "System Events" to tell process "Conductor"
|
|
487
|
-
set wa to UI element 1 of UI element 1 of UI element 1 of UI element 1 of window 1
|
|
488
590
|
repeat with m in (UI elements of wa whose role is "AXMenu")
|
|
489
591
|
repeat with mi in (UI elements of m whose role is "AXMenuItem")
|
|
490
592
|
set label to my firstLine(my tabLabel(mi))
|
|
@@ -529,8 +631,8 @@ on listModels()
|
|
|
529
631
|
end tell
|
|
530
632
|
delay 1.0
|
|
531
633
|
set labels to {}
|
|
634
|
+
set wa to my webArea()
|
|
532
635
|
tell application "System Events" to tell process "Conductor"
|
|
533
|
-
set wa to UI element 1 of UI element 1 of UI element 1 of UI element 1 of window 1
|
|
534
636
|
repeat with m in (UI elements of wa whose role is "AXMenu")
|
|
535
637
|
repeat with mi in (UI elements of m whose role is "AXMenuItem")
|
|
536
638
|
set end of labels to my firstLine(my tabLabel(mi))
|
|
@@ -592,6 +694,11 @@ function targetEnv(target) {
|
|
|
592
694
|
/** osascript echoes the whole failing script back; keep just the reason for the phone. */
|
|
593
695
|
function osaError(err) {
|
|
594
696
|
const raw = err instanceof Error ? err.message : String(err);
|
|
697
|
+
// A timeout kill carries no execution error at all — its first line is
|
|
698
|
+
// "Command failed: osascript -e" plus the whole script, which is useless here.
|
|
699
|
+
if (err && typeof err === 'object' && 'killed' in err && err.killed) {
|
|
700
|
+
return 'Conductor took too long to respond';
|
|
701
|
+
}
|
|
595
702
|
return raw.match(/execution error: (.+?) \(-?\d+\)/)?.[1] ?? raw.split('\n')[0];
|
|
596
703
|
}
|
|
597
704
|
/**
|
|
@@ -617,8 +724,7 @@ export class AppleScriptActuator {
|
|
|
617
724
|
const script = `
|
|
618
725
|
${SELECT_CHAT_TAB_HANDLERS}
|
|
619
726
|
|
|
620
|
-
|
|
621
|
-
delay 0.4
|
|
727
|
+
my activateConductor()
|
|
622
728
|
my focusWorkspace()
|
|
623
729
|
my selectChatTab()
|
|
624
730
|
set promptText to my normalizeNewlines(do shell script "cat" & " " & quoted form of (system attribute "RELAY_PROMPT_FILE"))
|
|
@@ -680,8 +786,7 @@ export async function setAgentOptions(target, opts) {
|
|
|
680
786
|
const script = `
|
|
681
787
|
${SELECT_CHAT_TAB_HANDLERS}
|
|
682
788
|
|
|
683
|
-
|
|
684
|
-
delay 0.4
|
|
789
|
+
my activateConductor()
|
|
685
790
|
my focusWorkspace()
|
|
686
791
|
my selectChatTab()
|
|
687
792
|
my applyAgentOptions()
|
|
@@ -709,8 +814,7 @@ export async function listAgentModels(target) {
|
|
|
709
814
|
const script = `
|
|
710
815
|
${SELECT_CHAT_TAB_HANDLERS}
|
|
711
816
|
|
|
712
|
-
|
|
713
|
-
delay 0.4
|
|
817
|
+
my activateConductor()
|
|
714
818
|
my focusWorkspace()
|
|
715
819
|
my selectChatTab()
|
|
716
820
|
return my listModels()`.trim();
|
|
@@ -781,8 +885,7 @@ export async function newChat(workspace) {
|
|
|
781
885
|
const script = `
|
|
782
886
|
${SELECT_CHAT_TAB_HANDLERS}
|
|
783
887
|
|
|
784
|
-
|
|
785
|
-
delay 0.4
|
|
888
|
+
my activateConductor()
|
|
786
889
|
my focusWorkspace()
|
|
787
890
|
tell application "System Events"
|
|
788
891
|
keystroke "t" using {command down}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conductor-remote",
|
|
3
|
-
"version": "1.27.
|
|
3
|
+
"version": "1.27.3",
|
|
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.",
|