You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Workflow-based curator hard cutover (workflow). Replaced curate with workflow: "none" | "summary-review", added summary-review approval flow with POST /summarize, made summary text the primary returned output while retaining raw curated evidence in details, and switched timeout handling to submit-first with deterministic summary fallback when no approved draft exists.
Auto-open curator for all web_search runs (single + multi query). Searches now open the curator window immediately and stream results live for review workflows; the old countdown/auto-condense fallback path was removed.
Exa.ai search provider. Neural/semantic search available alongside Perplexity and Gemini. 1,000 free requests/month. Set EXA_API_KEY env var or exaApiKey in ~/.pi/web-search.json, or select explicitly with provider: "exa". Includes built-in content extraction — when includeContent is true, full page text comes back with search results instead of requiring a separate background fetch. Monthly usage tracked in ~/.pi/exa-usage.json with a warning at 80%.
Exa MCP fallback. When no Exa API key is configured, search routes through mcp.exa.ai with zero setup. Supports basic search and includeContent but not domain/recency filtering (falls through to Gemini for those).
code_search tool. Code/documentation search via Exa MCP (get_code_context_exa). No API key required. Returns code examples, docs, and API references from GitHub, Stack Overflow, and official documentation.
Glimpse native curator window. On macOS with Glimpse installed, the search curator opens in a native WKWebView window instead of a browser tab. Faster launch, closer integration. Falls back to browser automatically when Glimpse is unavailable.
Curator provider UX rewrite. Replaced the provider dropdown with provider buttons (hidden when unavailable), made provider re-search additive, added provider badges on all cards (including errors), and switched button states to coverage-based logic keyed by logical query slots so duplicate query text is handled correctly.
Per-card provider re-search. Completed result cards now show "Also try" chips for other available providers. Clicking one searches the same query with that provider and adds a new card below, keeping both results for comparison.
Query rewrite with magic wand. The "Add a search" input now has a ✨ button that rewrites the entered query using a fast LLM (haiku/flash) to make it more specific and effective. The improved query replaces the input text for review before searching.
Summary model chooser redesign. Summary review now follows a provider-first flow: provider dropdown first, then provider-scoped model dropdown.
Active summary-generation loading state. Summary review now shows a dedicated animated in-progress panel while /summarize is running (panel sweep, pulse + shimmer placeholders, staged copy updates, and active model label) instead of only a static disabled textarea.
Model/provider guard retry for summary generation. If a selected summary model fails with model/provider configuration errors, curator now retries once with Auto model selection before surfacing a terminal error.
Feedback input for summary regeneration. Optional text field in the summary review panel for providing instructions when regenerating a summary. Only the Regenerate button passes feedback to the prompt; auto-generation and the initial Generate button do not. Feedback is cleared on success and persisted on error for retry.
/curator command. Toggle or configure the curator workflow at runtime: /curator on, /curator off, /curator summary-review, or /curator to toggle. Persists to ~/.pi/web-search.json and takes effect on the next web_search call.
Config-based workflow default. Added workflow field to ~/.pi/web-search.json for persistent curator preference. Per-call workflow parameter on web_search takes priority, then config, then the built-in default (summary-review with UI, none without).
"Send selected results without summary" button. New secondary button in the curator that submits curated results directly without generating or approving a summary. Works from any stage when results are selected. Output uses the raw curated results format with per-query detail.
Summary preview modal. Preview button in the summary actions opens a full-page modal with the summary rendered as formatted markdown. Includes Approve and Regenerate actions with an inline model selector for switching models without leaving the preview.
"Also try" provider chips on searching cards. Provider re-search chips now appear on cards still in-flight, not just completed ones, so alternative-provider searches can be kicked off in parallel without waiting.
Live search progress in heading. Hero heading shows "2 of 4 Searches Complete" while searches are running, with status line showing "2 completed, 2 searching". Reverts to "N Searches Complete" when all finish.
Summary subtitle with selection count. Subtitle now shows "Summary of N selected results" and reacts to selection changes ("Selection changed — regenerating summary…").
Summary model selector relocated. Moved the provider/model dropdowns from the hero area into the summary panel header, next to the title, so the model choice is adjacent to the summary it controls.
Improved collapsed TUI preview. Collapsed search result cards now show adaptive content: summary text when available, curated query titles with source counts when results were sent without summary, or a fallback text line otherwise. Line count hint matching pi's built-in pattern: ... (X more lines, Y total, ctrl+o to expand).
Inline annotation feedback in preview modal. Select any text in the rendered summary preview to get a popover with a quoted excerpt and a feedback textarea. Regenerate from the popover to send targeted feedback like Regarding: "<selected text>" — <your note>. Supports Cmd/Ctrl+Enter to submit and Escape to dismiss.
Concurrent add-search and alt-chip searches. The "Add a search" input and "Also try" provider chips are no longer locked while other searches are in-flight. Multiple searches can run in parallel.
Batch provider search shows searching cards immediately. Clicking a provider button now creates placeholder cards with loading animations upfront instead of waiting for results to arrive.
Changed
Exa search now always requests text content from both direct API and MCP paths (3000 chars default, 50000 with includeContent) instead of requesting highlights only. Ensures consistent answer quality regardless of whether Exa returns highlight snippets.
Adapted model registry calls to pi SDK changes: getApiKey() → getApiKeyAndHeaders() in index.ts and summary-review.ts, and getAvailable() from async to sync.
Hoisted dynamic await import() calls to static top-level imports in gemini-web.ts, video-extract.ts, and youtube-extract.ts.
Removed
result-review workflow. Hard cutover — only "none" and "summary-review" remain. Removed from WebSearchWorkflow type, resolveWorkflow(), tool schema, /websearch command, and /curator command.
Fixed
Summary generation no longer hard-fails on empty model payloads (content parts: none): empty-response failures now fall back to deterministic summary output with explicit fallback metadata (fallbackReason: "summary-model-empty-response") instead of surfacing a terminal UI error.
Deterministic fallback summaries now strip trailing Source:/Sources: boilerplate from provider answer text before building query previews, preventing noisy source-list dumps from replacing actual summary prose. Fixed regex matching so Source: tokens at the start of provider answers are correctly detected and removed.
Curator now allows provider switching and add-search actions while summary generation is running. User-initiated search mutations supersede the in-flight summary request client-side and return the UI to results mode so searching can continue without waiting for draft completion.
Curator client now handles non-2xx server responses consistently across /provider, /search, /submit, /cancel, and heartbeat requests, and no longer leaves timeout/heartbeat POST promises unhandled.
Prevented duplicate completion counting when the same result card is updated more than once.
Fixed background fetch abort detection to avoid crashing on non-Error rejection values.
Fixed YouTube detection for protocol-less links (youtu.be/...) by allowing regex fallback after URL-parse failures.
Fixed README probing in GitHub clone mode to continue scanning alternate README filenames when one candidate is unreadable.
Removed dead search-filter.ts code path and its stale README file-table entry.
Gemini provider routing now preserves provider failure context in explicit/final Gemini paths instead of silently collapsing errors to null.
Hardened auto-provider fallback diagnostics: when Exa/Perplexity/Gemini are available but fail at runtime, the thrown error now includes all provider-specific failure reasons instead of dropping context.
Prevented queued SSE event loss in curator reconnect flows by preserving unsent buffered messages when an SSE flush write fails.
Hardened curator server provider validation (/provider, /search) so invalid/unavailable provider names are rejected explicitly instead of mutating session state.
Fixed file:// local-video path handling to decode URL-escaped paths and treat malformed file URLs as invalid inputs instead of throwing.
Prevented path-escape reads in GitHub clone rendering by constraining blob/tree paths to remain within the cloned repository root.
Prevented symlink-escape traversal in clone tree/list rendering (buildTree / buildDirListing) by skipping entries that resolve outside the repository root.
Config parse errors from YouTube/video/Gemini fallback paths are now surfaced explicitly to users instead of silently collapsing to generic fallback messages.
Fixed provider switching during streaming curator searches (web_search + /websearch) so remaining queued searches use the latest selected provider instead of the initial one.
Fixed fetch_content timestamp behavior to fail explicitly on invalid timestamp formats and non-video/non-YouTube targets instead of silently ignoring timestamp and falling through to generic extraction.
Removed Promise.withResolvers from web_search curation flow for broader Node compatibility (no ES2024 runtime requirement).
Hardened PDF metadata handling (pdf-extract.ts) with typed metadata guards and safe maxPages clamping.
Normalized configured/default provider values in index.ts and gemini-search.ts (including case-insensitive values) so invalid provider strings no longer leak into curator state and now safely fall back to auto resolution.
Hardened config string/number normalization (index.ts, gemini-search.ts, gemini-web.ts, youtube-extract.ts, video-extract.ts): whitespace-only model/profile/provider values now safely fall back to defaults, and invalid/non-positive video maxSizeMB no longer disables local video detection accidentally.
Hardened API key/config handling (gemini-api.ts, perplexity.ts, exa.ts, github-extract.ts): whitespace/invalid key values are no longer treated as configured credentials, and invalid GitHub clone config booleans/numbers/paths now safely fall back to defaults instead of causing silent misconfiguration.
Fixed mid-flight abort behavior in extraction fallbacks (extract.ts, github-extract.ts): aborted YouTube/local-video/GitHub extraction no longer degrades into misleading fallback guidance and now returns explicit Aborted results instead of continuing with fallback network work.
Fixed abort lifecycle consistency in GitHub clone extraction (github-extract.ts): aborted clone attempts now correctly close activity entries as aborted and avoid persisting failed-abort clone cache entries that could force stale API-only fallback on later requests.
Fixed activity-monitor lifecycle for shared-clone races (github-extract.ts): callers that race onto an already-started clone now properly close their own activity entry (success/error/aborted) instead of leaving stale pending entries.
Fixed oversized-repo activity status accuracy (github-extract.ts): API fallback paths now mark activity success only when API fetch succeeds and correctly log an error when API fallback is unavailable instead of reporting false-positive success.
Fixed clone-failure fallback telemetry (github-extract.ts): when clone fails but API fallback succeeds, activity now reports success instead of remaining an error, and aborted clone-failure paths now short-circuit without extra fallback fetches.
Fixed GitHub URL host matching (github-extract.ts) so https://www.github.com/... URLs are recognized as clone/API candidates instead of silently falling through to generic HTTP extraction.
Hardened curator markdown rendering (curator-page.ts) against HTML/script injection by escaping provider answer text before markdown rendering, preserving markdown formatting while blocking raw HTML execution in the UI.
Closed additional curator link-safety gaps (curator-page.ts): sanitized markdown-rendered href/src protocols and source-link URLs to block javascript:/non-http schemes, enforced safe link attrs (noopener noreferrer), and stripped inline event-handler attributes from rendered markdown DOM.
Hardened inline script data serialization in curator page generation (curator-page.ts) by escaping Unicode line/paragraph separators (U+2028, U+2029) in safeInlineJSON, preventing malformed script blocks or injection edge cases from unescaped JSON payloads.
Fixed abort telemetry misclassification in media extractors (youtube-extract.ts, video-extract.ts): canceled extractions now log activity as aborted (status: 0) instead of incorrectly reporting all ... paths failed errors after abort races.
Fixed GitHub URL path decoding in clone/API extraction (github-extract.ts): percent-encoded path segments (for example %20) are now decoded before blob/tree resolution, so URLs that point to files/directories with encoded characters no longer fall through to incorrect "path not found" output.
Fixed error-signal downgrade in local-video API fallback (video-extract.ts): tryVideoGeminiApi now rethrows config parse failures (Failed to parse ~/.pi/web-search.json) instead of swallowing them as null, preserving actionable root-cause errors.
Fixed provider config type hardening in search routing (index.ts): normalizeProviderInput now guards non-string config values before trimming so malformed provider entries in ~/.pi/web-search.json no longer crash runtime provider resolution with value.trim is not a function.
Simplified provider typing flow in curator/search orchestration (index.ts): narrowed resolveProvider and PendingCurate.defaultProvider to resolved provider types, normalized incoming provider strings at callback boundaries, and removed redundant as SearchProvider | undefined casts while preserving search behavior.
Improved curator loading experience in curator-page.ts: added animated skeleton loading panel in the content area while searches are in-flight, upgraded searching card visuals with shimmer/active-state styling, and wired loading visibility to real search state transitions (including add-search, done, submit/cancel, and timeout paths).
Updated curator session timeout defaults in index.ts: curator now starts at 20 seconds by default (down from 60) and can be configured via curatorTimeoutSeconds in ~/.pi/web-search.json (capped at 600 seconds).
Hardened /websearch startup error handling in index.ts: config/provider bootstrap now runs behind explicit error handling so malformed ~/.pi/web-search.json no longer throws uncaught command errors before the existing server-start try/catch; users now receive a direct UI error with parse context.
Hardened extension bootstrap config handling in index.ts: shortcut initialization now uses guarded config loading, logging parse errors and falling back to default shortcuts instead of crashing extension registration on malformed ~/.pi/web-search.json.
Simplified curator-timeout config plumbing in index.ts by removing an unused getCuratorTimeoutSeconds(config) parameter path and keeping a single config-read code path.
Simplified curator bootstrap wiring in index.ts by extracting shared provider/timeout setup (ProviderAvailability, CuratorBootstrap, getProviderAvailability, loadCuratorBootstrap) and removing duplicated availability assembly across web_search and /websearch flows.
Hardened SSE event parsing in curator client (curator-page.ts): malformed JSON payloads from SSE data: lines now surface as user-visible errors instead of crashing the page via uncaught JSON.parse exceptions.
Fixed "Send results" producing a deterministic summary instead of raw curated results. The submit payload now uses a rawResults flag to distinguish explicit "Send results" clicks from timeout-via-submit, which correctly falls back to a deterministic summary.
Exa search results with no highlight snippets now fall back to item.text (truncated to 1000 chars) instead of producing empty answers. Empty snippets are also skipped during MCP answer assembly.
Exa MCP result parsing now handles Highlights: response blocks in addition to Text: blocks, and strips trailing --- separators from parsed content.
Fixed stale heading count after a user-added search fails and its card is removed. updateSummaryText() is now called in all card-removal error paths.
Fixed heading not reflecting new in-progress searches immediately. Adding a search via "Also try" or "Add a search" now updates the heading to show the new total (e.g., "4 of 5 Searches Complete") right away instead of waiting for completion.