pi-lean-search 0.7.0 → 0.7.1
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/index.ts +10 -53
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
* Registers the `web-search` tool and a `/searxng-status` diagnostic command.
|
|
5
5
|
* Manages the `search` status bar slot with health-colored glyphs.
|
|
6
6
|
*
|
|
7
|
-
* Owns the `pi-lean-dimension.search` toolset
|
|
7
|
+
* Owns the `pi-lean-dimension.search` toolset:
|
|
8
8
|
* ● searxng (accent/blue) — healthy and reachable
|
|
9
9
|
* ● searxng (warning/yellow) — server up but pipeline degraded
|
|
10
10
|
* ● searxng (error/red) — unreachable
|
|
11
11
|
* ○ searxng — search tools off
|
|
12
|
+
*
|
|
13
|
+
* Co-activation with the web workflow is portal-owned: `/web on|off|learn`
|
|
14
|
+
* batches the search toolset id directly. Search is independently togglable
|
|
15
|
+
* via /tbox and focus.
|
|
12
16
|
*/
|
|
13
17
|
|
|
14
18
|
import type {
|
|
@@ -23,7 +27,6 @@ import {
|
|
|
23
27
|
import type {
|
|
24
28
|
ToolsetSpec,
|
|
25
29
|
ToolsetChangedEvent,
|
|
26
|
-
BranchReader,
|
|
27
30
|
} from "pi-tool-masking";
|
|
28
31
|
import { readSearxngUrl } from "./search-config.js";
|
|
29
32
|
import { webSearchTool, normalizeBaseUrl } from "./web-search-tool.js";
|
|
@@ -54,18 +57,9 @@ let _lastDegraded = false;
|
|
|
54
57
|
/** Cached ExtensionContext for event-driven glyph rendering. */
|
|
55
58
|
let _lastCtx: ExtensionContext | null = null;
|
|
56
59
|
|
|
57
|
-
/** Live sessionManager reference for the co-activation mirror — stored at
|
|
58
|
-
* session_start; the library invokes getBranch() fresh per apply, so the
|
|
59
|
-
* stored reference stays correct across cascades and external writes. */
|
|
60
|
-
let _sessionManager: BranchReader | null = null;
|
|
61
|
-
|
|
62
|
-
/** Unsubscribe for the co-activation mirror (registered inside session_start,
|
|
63
|
-
* torn down in session_shutdown so re-fires don't stack listeners). */
|
|
64
|
-
let _offMirror: (() => void) | null = null;
|
|
65
|
-
|
|
66
60
|
/** Unsubscribers for the factory-time glyph-sync listeners — pi re-invokes
|
|
67
61
|
* the cached extension factory per load pass, so these are re-registered
|
|
68
|
-
* each time and torn down in the
|
|
62
|
+
* each time and torn down in the factory prologue / session_shutdown to avoid
|
|
69
63
|
* stacking duplicate listeners on the shared event bus. */
|
|
70
64
|
let _offSync: (() => void)[] = [];
|
|
71
65
|
|
|
@@ -188,8 +182,6 @@ function _resetStateForTest(): void {
|
|
|
188
182
|
_lastHealth = null;
|
|
189
183
|
_lastDegraded = false;
|
|
190
184
|
_lastCtx = null;
|
|
191
|
-
_sessionManager = null;
|
|
192
|
-
_offMirror = null;
|
|
193
185
|
}
|
|
194
186
|
|
|
195
187
|
export { _resetStateForTest };
|
|
@@ -200,11 +192,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
200
192
|
// --- Ensure idempotent re-invocation ----------------------------
|
|
201
193
|
// pi reuses the cached extension factory on /resume (same cwd),
|
|
202
194
|
// which re-invokes this function with the same module-level
|
|
203
|
-
// singletons.
|
|
204
|
-
// skip re-registration behind a stale _offMirror.
|
|
205
|
-
_offMirror?.();
|
|
206
|
-
_offMirror = null;
|
|
207
|
-
_sessionManager = null;
|
|
195
|
+
// singletons.
|
|
208
196
|
for (const off of _offSync) off();
|
|
209
197
|
_offSync = [];
|
|
210
198
|
|
|
@@ -213,32 +201,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
213
201
|
|
|
214
202
|
// ── Define the pi-lean-dimension.search toolset ───────────
|
|
215
203
|
// Registers restore handler on session_start / session_tree.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// ── Co-activation: mirror pi-lean-dimension.web changed events ─
|
|
219
|
-
// Listen on changed ONLY, not restored. Registered inside session_start
|
|
220
|
-
// (after _sessionManager is stored) so the reader always exists when the
|
|
221
|
-
// mirror runs — there is no reader-less window.
|
|
222
|
-
const mirrorWebChanged = (data: unknown) => {
|
|
223
|
-
const event = data as ToolsetChangedEvent;
|
|
224
|
-
if (event.id !== "pi-lean-dimension.web") return;
|
|
225
|
-
// Catch AllowlistModeError by name, never `instanceof` — the handle
|
|
226
|
-
// may come from a different library copy via the shared registry;
|
|
227
|
-
// refusal means "nothing changed" — skip co-activation.
|
|
228
|
-
try {
|
|
229
|
-
if (event.enabled) {
|
|
230
|
-
searchToolset.enable(pi, _sessionManager!);
|
|
231
|
-
} else {
|
|
232
|
-
searchToolset.disable(pi, _sessionManager!);
|
|
233
|
-
}
|
|
234
|
-
} catch (err) {
|
|
235
|
-
if ((err as { name?: string } | undefined)?.name !== "AllowlistModeError") {
|
|
236
|
-
throw err;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
};
|
|
204
|
+
defineToolset(pi, SEARCH_WEB_SPEC);
|
|
240
205
|
|
|
241
206
|
// ── Keep cached state in sync with library events ────────
|
|
207
|
+
// Glyph cache only — display re-render, not actuation. Co-activation
|
|
208
|
+
// lives in portal's /web command (it batches this toolset id directly).
|
|
242
209
|
const syncSearchState = (data: unknown) => {
|
|
243
210
|
const event = data as ToolsetChangedEvent;
|
|
244
211
|
if (event.id === "pi-lean-dimension.search") {
|
|
@@ -253,15 +220,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
253
220
|
|
|
254
221
|
// ── Session start: health probe + glyph ──────────────────
|
|
255
222
|
pi.on("session_start", async (event, ctx) => {
|
|
256
|
-
_sessionManager = ctx.sessionManager;
|
|
257
223
|
_lastCtx = ctx;
|
|
258
224
|
|
|
259
|
-
// Register the co-activation mirror once, after the reader is stored
|
|
260
|
-
// (dedup across re-fires of session_start for the same instance).
|
|
261
|
-
if (!_offMirror) {
|
|
262
|
-
_offMirror = pi.events.on(TOOLSET_EVENTS.changed, mirrorWebChanged);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
225
|
// Re-read config in case it changed between sessions
|
|
266
226
|
_searxngUrl = readSearxngUrl();
|
|
267
227
|
|
|
@@ -315,12 +275,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
315
275
|
|
|
316
276
|
// ── Session shutdown: clean up ───────────────────────────
|
|
317
277
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
318
|
-
_offMirror?.();
|
|
319
|
-
_offMirror = null;
|
|
320
278
|
for (const off of _offSync) off();
|
|
321
279
|
_offSync = [];
|
|
322
280
|
_lastCtx = null;
|
|
323
|
-
_sessionManager = null;
|
|
324
281
|
try {
|
|
325
282
|
ctx?.ui?.setStatus?.("search", "");
|
|
326
283
|
} catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-lean-search",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "SearXNG web search for Pi. Self-hosted or public instance, no API keys or quotas; returns a setup message instead of erroring when unreachable. Pairs with pi-lean-portal's /web toggle or works standalone.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|