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.
Files changed (2) hide show
  1. package/index.ts +10 -53
  2. 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 (co-activated off `pi-lean-dimension.web`):
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 reset block / session_shutdown to avoid
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. Reset the mirror state so the second load doesn't
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
- const searchToolset = defineToolset(pi, SEARCH_WEB_SPEC);
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.0",
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",