feat: redesign Ask as global pill with agent-driven UI actions#304
Merged
SimplicityGuy merged 33 commits intomainfrom Apr 15, 2026
Merged
feat: redesign Ask as global pill with agent-driven UI actions#304SimplicityGuy merged 33 commits intomainfrom
SimplicityGuy merged 33 commits intomainfrom
Conversation
Designs the Explore Ask feature redesign as a global floating pill with agent-driven UI actions, dynamic suggestions, and a shared common/agent_tools registry for the NLQ engine and MCP server. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
31 TDD tasks across 10 phases implementing the approved spec: shared agent_tools registry, NLQ engine action contract, suggestions endpoint, MCP server refactor, floating pill component with suggestions and action applier, DOMPurify markdown renderer, summary strip, and E2E coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the inline name-resolution + find_shortest_path logic in NLQToolRunner._handle_find_path with a call to the shared common.agent_tools.find_path, injecting a resolve_name closure that wraps EXPLORE_DISPATCH (handles numeric pass-through, missing type pass-through, and named lookups). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nt_tools Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Defines 10 Pydantic action types with a `type` literal discriminator for strict JSON parsing. parse_action_list drops malformed entries with a warning log. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add actions: list[Action] field to NLQResult, an _extract_actions() helper that strips the <!--actions:[...]--> marker from agent text, and extend the system prompt so Claude knows to emit the marker. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add an `actions` SSE event between status events and the final `result` event in `_stream_response`, and include `actions` in the non-SSE JSON response branch for consistency. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Delegates mcp_server.find_path to common.agent_tools.find_path via API-backed resolver closures (_api_get for name resolution, /api/path for path traversal), so future shared tool additions automatically benefit MCP clients without changes to server.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add click-to-expand, ⌘K/Ctrl+K, ? (when no input focused), Esc-to-collapse, and expanded-state render with focused input to NlqPill. Install @testing-library/dom for fireEvent in tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ection Adds nlq-markdown.js — a security-hardened markdown renderer that uses DOMPurify RETURN_DOM_FRAGMENT (never innerHTML) and injects entity anchor elements via createElement/textContent. Anchor tags from markdown source are stripped by the ALLOWED_TAGS allowlist. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add fetchNlqSuggestions to ApiClient and replace the monolithic NLQPanel class with a thin initNlq coordinator that delegates to NlqPill, NlqSuggestions, NlqActionApplier, NlqSummaryStrip, and nlq-handlers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the searchAskToggle/nlqPanel/nlqExamples navbar markup, the initNlqPanel IIFE from app.js, and all test code that depended on the old NLQPanel class. Add a guardrail test to prevent reintroduction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds nlqStripMount div to index.html, calls window.NlqInit from app.js DOMContentLoaded handler after exploreApp is set, and adds a static assertion guardrail test. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Add targeted tests covering initNlq orchestration, action applier sanitizers, handler delegates, pill Enter-key submit, suggestions non-array history reset, and graph addEntity app-delegate branch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ions Add targeted tests for previously uncovered branches: _extract_actions invalid-JSON warning path, whitespace-only suggestion focus fallback, explore-entity unknown-type guards, resolve_name None-return path, suggestions cache hit/read-failure/write-failure, and jwt_secret=None early-return. Add pragma: no cover to TYPE_CHECKING block and unreachable non-list guard in _extract_actions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
Contributor
Contributor
Contributor
Contributor
This was referenced Apr 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RETURN_DOM_FRAGMENT— never touchesinnerHTML) and re-injects entity links safelycommon/agent_tools/as a framework-free shared tool registry consumed by both the NLQ engine (api/nlq/tools.py) and the MCP server (mcp-server/mcp_server/server.py) to prevent tool drift/api/nlq/suggestionsendpoint with Redis caching, rate limiting, and fallback-safe error pathsArchitecture highlights
Backend (Phases 1-5):
common/agent_tools/{graph,entities,discovery,stats}.py— dependency-injected async toolsapi/nlq/actions.py— Pydantic discriminated-union for 10 action types with server-side validation<!--actions:[...]-->marker the engine strips from the user-visible summaryactionsevent betweenstatusandresultFrontend (Phases 6-10):
nlq-pill.js— state machine (collapsed → expanded → loading → summary) with ⌘K / ? / Esc keyboard shortcutsnlq-suggestions.js— context-aware dynamic chip rows + localStorage history (capped at 5, auto-recovers from corruption)nlq-action-applier.js— sanitizes, orders, dispatches, snapshots for single-action undonlq-handlers.js— thin bridge between the applier and the existing graph/insights/trends subsystemsnlq-markdown.js— DOMPurify-backed renderer with safe entity span injectionnlq-summary-strip.js— dismissable action log with undo buttonnlq.js— thin coordinator (78 lines, down from 256)GraphVisualizationgainssnapshot(),restore(),clearAll(),addEntity()for action-driven graph mutationCleanup:
Test plan
Known minor observations (follow-ups, not blocking)
Spec and plan
🤖 Generated with Claude Code