conductor-remote 1.46.1 → 1.46.2

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-CUK1vepc.js"></script>
16
+ <script type="module" crossorigin src="/assets/index-Cox9xTfw.js"></script>
17
17
  <link rel="stylesheet" crossorigin href="/assets/index-DGZkOBT-.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,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let l={};const c=e=>i(e,o),t={module:{uri:o},exports:l,require:c};s[o]=Promise.all(n.map(e=>t[e]||c(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";importScripts("/push-sw.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"push-sw.js",revision:"e1e682e2e5e88fa03b7808ae9db8e098"},{url:"index.html",revision:"e1e0a60e3dfd111be45acc4472064f5c"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-DGZkOBT-.css",revision:null},{url:"assets/index-CUK1vepc.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,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let l={};const c=e=>i(e,o),t={module:{uri:o},exports:l,require:c};s[o]=Promise.all(n.map(e=>t[e]||c(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";importScripts("/push-sw.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"push-sw.js",revision:"e1e682e2e5e88fa03b7808ae9db8e098"},{url:"index.html",revision:"039e5ab1adab0c250569cb906306c5a8"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-DGZkOBT-.css",revision:null},{url:"assets/index-Cox9xTfw.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\//]}))});
@@ -908,6 +908,20 @@ on firstLine(s)
908
908
  return item 1 of parts
909
909
  end firstLine
910
910
 
911
+ on pickerShowsModel(popup, wanted)
912
+ set pickerLabel to my tabLabel(popup)
913
+ if pickerLabel contains ("(" & wanted & ")") then return true
914
+ -- The menu can label a newly released model "Opus 5 NEW", while the
915
+ -- composer deliberately drops that temporary badge and says "Opus 5".
916
+ -- Treat that exact display form as the same choice; the surrounding
917
+ -- parentheses keep "Opus 5" distinct from a longer model name.
918
+ if wanted ends with " NEW" then
919
+ set baseName to text 1 thru -5 of wanted
920
+ if pickerLabel contains ("(" & baseName & ")") then return true
921
+ end if
922
+ return false
923
+ end pickerShowsModel
924
+
911
925
  on setModel(wanted)
912
926
  set popup to missing value
913
927
  repeat with entry in my composerControls()
@@ -915,13 +929,14 @@ on setModel(wanted)
915
929
  if my tabLabel(c) contains "Change agent" then set popup to c
916
930
  end repeat
917
931
  if popup is missing value then error "couldn't find the model picker"
918
- if (my tabLabel(popup)) contains ("(" & wanted & ")") then return
932
+ if my pickerShowsModel(popup, wanted) then return
919
933
  tell application "System Events" to tell process "Conductor"
920
934
  perform action "AXPress" of popup
921
935
  end tell
922
936
  delay 1.0
923
- -- Menu labels carry badges ("Opus 5 NEW"), so an exact match is preferred but a
924
- -- prefix match is accepted except when it is ambiguous ("Sonnet 4.6" would
937
+ -- The relay removes a temporary `NEW` badge before it sends this label back,
938
+ -- so a prefix match resolves that menu item. It is accepted only when unique:
939
+ -- "Sonnet 4.6" would
925
940
  -- otherwise also match "Sonnet 4.6 1M"), which must fail rather than guess.
926
941
  set chosen to missing value
927
942
  set loose to {}
@@ -954,7 +969,7 @@ on setModel(wanted)
954
969
  if my tabLabel(c) contains "Change agent" then set popup to c
955
970
  end repeat
956
971
  if popup is missing value then error "the model picker vanished"
957
- if (my tabLabel(popup)) does not contain ("(" & wanted & ")") then error "the model didn't switch to " & wanted
972
+ if not my pickerShowsModel(popup, wanted) then error "the model didn't switch to " & wanted
958
973
  end setModel
959
974
 
960
975
  on listModels()
@@ -50,6 +50,14 @@ export function workspaceTitle(w) {
50
50
  export function queryTokens(raw) {
51
51
  return raw.toLowerCase().match(/[\p{L}\p{N}_]+/gu) ?? [];
52
52
  }
53
+ /**
54
+ * A temporary `NEW` marker in Conductor's picker is a badge, not part of the
55
+ * model name. The relay and phone use this value for the visible label and for
56
+ * a later selection, so both sides must remove it in the same way.
57
+ */
58
+ export function modelPickerLabel(label) {
59
+ return label.endsWith(' NEW') ? label.slice(0, -4) : label;
60
+ }
53
61
  /**
54
62
  * Markers the relay wraps search hits in (src/search.ts, via FTS5 `snippet()`). They
55
63
  * are control characters, so they must never reach the DOM: an unsplit snippet renders
@@ -3,6 +3,7 @@ import { execFile } from 'node:child_process';
3
3
  import { readFileSync } from 'node:fs';
4
4
  import path from 'node:path';
5
5
  import { promisify } from 'node:util';
6
+ import { modelPickerLabel } from "./shared.js";
6
7
  import { sidecarAvailable, sidecarSendUserMessage } from "./sidecar.js";
7
8
  const exec = promisify(execFile);
8
9
  /** Waiting runs past this are refused rather than queued. */
@@ -584,8 +585,9 @@ return my listModels()`.trim();
584
585
  const models = stdout
585
586
  .split('\n')
586
587
  .map(s => s.trim())
588
+ .map(modelPickerLabel)
587
589
  .filter(Boolean);
588
- return { ok: true, models };
590
+ return { ok: true, models: [...new Set(models)] };
589
591
  }
590
592
  catch (err) {
591
593
  return { ok: false, error: osaError(err) };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conductor-remote",
3
- "version": "1.46.1",
3
+ "version": "1.46.2",
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.",
@@ -50,13 +50,14 @@
50
50
  "typecheck": "tsc -p tsconfig.json",
51
51
  "lint": "biome check .",
52
52
  "fix": "biome check . --fix",
53
- "verify": "yarn typecheck && yarn lint && yarn check:imports && yarn check:routes && yarn check:attachments && yarn check:applescript && yarn check:nosleep && yarn check:uilock && yarn check:firstprompt && yarn check:sendonce && yarn check:notify",
53
+ "verify": "yarn typecheck && yarn lint && yarn check:imports && yarn check:routes && yarn check:attachments && yarn check:applescript && yarn check:model-labels && yarn check:nosleep && yarn check:uilock && yarn check:firstprompt && yarn check:sendonce && yarn check:notify",
54
54
  "release": "semantic-release",
55
55
  "prepack": "yarn build && yarn build:node",
56
56
  "postinstall": "husky || true",
57
57
  "check:attachments": "node scripts/check-attachments.ts",
58
58
  "check:applescript": "node scripts/check-applescript.ts",
59
59
  "check:firstprompt": "node scripts/check-firstprompt.ts",
60
+ "check:model-labels": "node scripts/check-model-labels.ts",
60
61
  "check:sendonce": "node scripts/check-sendonce.ts",
61
62
  "check:notify": "node scripts/check-notify.ts",
62
63
  "check:imports": "node scripts/check-imports.ts",