conductor-remote 1.63.0 → 1.64.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-
|
|
16
|
+
<script type="module" crossorigin src="/assets/index-C8s68scA.js"></script>
|
|
17
17
|
<link rel="stylesheet" crossorigin href="/assets/index-BhxPTIyU.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
|
|
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:"0cc53b4390ac109ed647b9f747869331"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-C8s68scA.js",revision:null},{url:"assets/index-BhxPTIyU.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\//]}))});
|
|
@@ -116,7 +116,10 @@ export function createTools(call) {
|
|
|
116
116
|
inputSchema: {
|
|
117
117
|
type: 'object',
|
|
118
118
|
properties: {
|
|
119
|
-
query: {
|
|
119
|
+
query: {
|
|
120
|
+
type: 'string',
|
|
121
|
+
description: 'Plain words, ranked by relevance; wrap a "phrase in quotes" to require it word for word. Other punctuation and operators are ignored, not parsed.'
|
|
122
|
+
},
|
|
120
123
|
limit: { type: 'number', description: 'Max workspaces to return (default 12, max 50).' }
|
|
121
124
|
},
|
|
122
125
|
required: ['query']
|
package/dist-node/src/search.js
CHANGED
|
@@ -80,19 +80,58 @@ const INDEXED_ROLES = new Set(['user', 'assistant', 'thinking']);
|
|
|
80
80
|
* the one matching one, and requiring all four would return nothing whenever a
|
|
81
81
|
* single word is misremembered.
|
|
82
82
|
*
|
|
83
|
+
* OR alone loses the query made of common words, and nothing about sentence
|
|
84
|
+
* boundaries is why — a chunk is a whole prose block. Measured 2026-09-01 against
|
|
85
|
+
* this Mac's 225k-chunk index: "may i run the", a sentence one chat verifiably
|
|
86
|
+
* contains, ranked nowhere in the top 300 chunks, because OR rewards density
|
|
87
|
+
* ("Running the headless artifact render… first run may…") and nothing rewards
|
|
88
|
+
* adjacency. So each run of unquoted words also enters as one FTS5 phrase term
|
|
89
|
+
* OR'd beside its tokens: the phrase is rare where the words are common, its BM25
|
|
90
|
+
* weight is correspondingly large, and the same query then puts the exact sentence
|
|
91
|
+
* first (95ms against 206ms for bare OR, both inside the 250ms debounce). A phrase
|
|
92
|
+
* the index doesn't contain matches nothing and costs nothing.
|
|
93
|
+
*
|
|
94
|
+
* Quotes filter. `"exactly this"` becomes a *required* phrase (AND), because a
|
|
95
|
+
* typed quote is the one signal that the user is filtering rather than recalling;
|
|
96
|
+
* words outside the quotes stay OR'd. Curly `“”` count as quotes — iOS smart
|
|
97
|
+
* punctuation substitutes them for the straight one the user pressed, so the phone
|
|
98
|
+
* mostly never sends `"`. Stemming still applies inside quotes (`"running"` finds
|
|
99
|
+
* "runs"): quoting changes which chunks qualify, not how they were tokenized.
|
|
100
|
+
*
|
|
83
101
|
* The last token gets a prefix `*` so search-as-you-type matches mid-word, but only
|
|
84
102
|
* from three characters: `"a"*` matches a large fraction of the index and would
|
|
85
|
-
* spend the whole query budget on a keystroke that means nothing yet.
|
|
103
|
+
* spend the whole query budget on a keystroke that means nothing yet. Inside an
|
|
104
|
+
* unclosed quote the star rides on the phrase itself (`"may i ru"*` — valid FTS5,
|
|
105
|
+
* the last token matches as a prefix), so a phrase still being typed already
|
|
106
|
+
* matches what it is about to say.
|
|
86
107
|
*/
|
|
87
108
|
export function matchQuery(raw) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
109
|
+
// Split on quote characters: segments alternate unquoted/quoted, and a trailing
|
|
110
|
+
// unclosed quote leaves the last segment quoted — the phrase still being typed.
|
|
111
|
+
const segments = raw.toLowerCase().split(/["“”]/);
|
|
112
|
+
const typing = !/[\s"“”]$/.test(raw);
|
|
113
|
+
const required = [];
|
|
114
|
+
const loose = [];
|
|
115
|
+
for (let i = 0; i < segments.length; i++) {
|
|
116
|
+
const tokens = segments[i].match(/[\p{L}\p{N}_]+/gu);
|
|
117
|
+
if (!tokens?.length)
|
|
118
|
+
continue;
|
|
119
|
+
const star = i === segments.length - 1 && typing && tokens[tokens.length - 1].length >= 3 ? '*' : '';
|
|
120
|
+
const phrase = `"${tokens.join(' ')}"${star}`;
|
|
121
|
+
if (i % 2) {
|
|
122
|
+
required.push(phrase);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
if (tokens.length > 1)
|
|
126
|
+
loose.push(phrase);
|
|
127
|
+
loose.push(...tokens.slice(0, -1).map(t => `"${t}"`), `"${tokens[tokens.length - 1]}"${star}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!loose.length)
|
|
131
|
+
return required.length ? required.join(' AND ') : null;
|
|
132
|
+
// The OR group is parenthesised because FTS5 binds AND tighter than OR.
|
|
133
|
+
const looseExpr = loose.length > 1 ? `(${loose.join(' OR ')})` : loose[0];
|
|
134
|
+
return required.length ? `${required.join(' AND ')} AND ${looseExpr}` : looseExpr;
|
|
96
135
|
}
|
|
97
136
|
/** The tokens `matchQuery` will search for — what a caller matches names against. */
|
|
98
137
|
export { queryTokens } from "./shared.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conductor-remote",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.64.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.",
|