| 2026-05-12 |
Rename login button text from gnexus-auth to GNEXUS.
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 12 May
|
Fix Phosphor icon class on GnButton/GnIconButton usages.
...
gnexus-ui-kit's iconNode() does not prepend the base `ph` class
when the icon string starts with `ph-`; it only keeps the string
as-is. All icon props must include the base class explicitly:
`icon="ph ph-sidebar"` instead of `icon="ph-sidebar"`.
Updated 15 icon bindings across 9 components.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 12 May
|
Wire gnexus-ui-kit v0.2.0 Vue 3 adapter and migrate Wave 1 components.
...
- Update vendor/gnexus-ui-kit to v0.2.0 (Vue components + composables)
- Add Vite aliases for gnexus-ui-kit/vue and gnexus-ui-kit/css
- Install GnexusUiVue plugin in main.js + GnToastProvider in App.vue
- Migrate ProfileBadge → GnBadge
- Migrate ErrorMessage → GnAlert
- Migrate ConfirmDialog → GnConfirmDialog
- Migrate raw <button> elements → GnButton / GnIconButton in:
WelcomeScreen, LoginScreen, ChatArea, ChatHeader, AppSidebar,
ArtifactsPanel, UserMessage, AssistantMessage, SelectionToolbar
Build and tests pass (51/51).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 12 May
|
Auto-inject relevant memory facts into LLM context on every user turn.
...
Semantic search against the vector memory store runs in parallel with
context provider collection. Number of injected facts scales with
message length (1–3) to reduce noise on short queries. Guardrails:
min length gate, per-turn deduplication, and structured logging at
info level for observability.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 12 May
|

Audit and fix docs/ for accuracy against current codebase
...
Package A (API + WebSocket + Sessions):
- api.md: add missing endpoints (health/embed, auth/status, agents/prompts,
agents/mcp_servers, sessions/content, 7 admin endpoints). Fix response
schemas, auth requirements, query params. Update path formats.
- websocket.md: fix planning_status.phase type (int 1|2|3), add metadata
to tool_call, message_index to stream_end, context_tokens/max_context_tokens
to context_compressed.
- sessions.md: fix context_compression_threshold default (0.80→0.70),
add list_page method, add metadata to Message flags.
Package B (Config + Profiles + Tools + Agent + Memory):
- config.md: remove stale ANTHROPIC_API_KEY description, add 12 missing
env vars (embedding, web search, terminal_user_allowed_commands,
context_providers_dir, gnauth fields, output_reserve_tokens).
Fix OPENAI_BASE_URL type.
- profiles.md: fix max_iterations default (20→10), add top_k/top_p/num_thread,
is_admin_only, context_providers, mcp_servers, subagent_think_enabled.
Clarify subagent_tools fallback and step_validation_enabled.
- tools.md: replace 3 separate memory tools with unified `memory`, add
`mcp_status`.
- agent.md: fix run_ephemeral return type (str→tuple), clarify DB reads.
- memory.md: fix search_facts/get_all_facts param order, fix MemoryStore
init description.
236 tests passing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 12 May
|
Remove dead LLMBackend.stream() method
...
The method was defined on all backends (Ollama, FallbackOllama, OpenAI)
and in the base LLMBackend interface, but was never called by agent.py
or messages.py. stream_complete() covers all streaming use cases.
- navi/llm/base.py: remove abstract stream() method
- navi/llm/ollama.py: remove OllamaBackend.stream()
- navi/llm/fallback.py: remove FallbackOllamaBackend.stream()
- navi/llm/openai_backend.py: remove OpenAIBackend.stream()
- docs/tech_debt_review: mark item 54 as fixed
236 tests passing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 12 May
|
| 2026-05-11 |
Fix ollama_backends / FallbackOllamaBackend issues
...
- registry.py: always use FallbackOllamaBackend (unified backend).
Enables model priority lists in all deployments, not just multi-server.
- agent.py: add missing think=profile.think_enabled to run() (REST endpoint).
- compressor.py: fix model param type (str → list[str] | str | None).
- fallback.py: harden load_servers_from_file against missing/bad JSON files
and entries without host. Add clear_blacklists() for manual reset.
- admin.py: add POST /admin/ollama/clear-blacklists endpoint.
- tech_debt_review: document dead stream() methods.
- tests: add tests for single-server fallback, bad file handling,
missing host skipping, and blacklist clearing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 11 May
|
Add deterministic line-based file editing (edit_lines), rating UI fix, and session refresh
...
- filesystem.py: add edit_lines action (deterministic line ops via operations array)
+ numbered param for read (1-based line numbers in output)
+ clarify four editing modes in tool description
- chat.js: fix rating IDs for streaming messages (assign h_ ID on stream_end)
- SessionList.vue: mobile pull-to-refresh with PTR_THRESHOLD=80
- AppSidebar.vue: desktop refresh button next to Conversations header
- planning.py: knowledge source assessment in Phase 1
- debug panel: MCP servers tab + resolved tools per profile
- NAVI.md: reposition as neutral quick-reference
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 11 May
|
Fix graceful MCP disconnect during server shutdown
...
- McpClient.disconnect(): catch CancelledError / RuntimeError from
anyio SSE transport teardown
- McpManager.disconnect_all(): shield gather from CancelledError
- main.py _on_shutdown(): catch CancelledError and RuntimeError
explicitly (BaseException, not Exception)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 11 May
|
Inject MCP server instructions into system prompt
...
- McpClient: collect instructions from MCP initialize handshake
- McpServerConfig: add 'instructions' field for Navi-side overlay
- McpManager.get_instructions(): merge server + config instructions
- ContextBuilder: new _mcp_context_msg() injects MCP server
descriptions into every LLM context as a system message
- Agent passes mcp_manager to ContextBuilder
- mcp_servers.json: add overlay instructions for gnexus-book
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 11 May
|
Fix MCP tool lookup in websocket handler and tests
...
- websocket.py: pass mcp_manager to Agent(), with graceful fallback
if MCP connection fails
- conftest.py: mock get_mcp_manager() in tests to prevent SSE
connection attempts against real servers
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 11 May
|
Refactor MCP integration: server groups in profiles
...
- mcp_servers.json: add 'groups' (read/write/admin) for gnexus-book
- AgentProfile: new 'mcp_servers' field (server_name -> group list)
- Profile loader: parse and persist 'mcp_servers' in config.json
- Agent._tool_list(): expands mcp_servers into concrete tool names
via McpManager.resolve_group(), wildcard '*' supported
- /agents/profiles API: includes 'mcp_servers' in response
- Profiles no longer list individual mcp_ tools in 'enabled_tools'
- discuss: gnexus-book read group
- server_admin: gnexus-book read+write+admin groups
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 11 May
|
Connect gnexus-book MCP server and enable in profiles
...
- mcp_servers.json: SSE transport to 192.168.1.170:8001
- server_admin profile: all 16 gnexus-book tools
- discuss profile: read-only gnexus-book tools (docs + inventory)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 11 May
|
| 2026-05-10 |
Add MCP server support and fix memory tools user isolation
...
MCP integration:
- New navi/mcp/ package: client, manager, config, tools
- ToolRegistry learns register_external() for MCP tools
- reload_tools reconnects MCP servers on hot reload
- New built-in mcp_status tool
- Startup/shutdown wiring for MCP connections
- 12 new tests (unit + integration with real stdio server)
Memory tools fix:
- memory, memory_save, memory_search, memory_forget now read
current_user_id from tool context and pass it to MemoryStore
- Fixes invisible facts for authenticated users
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 10 May
|
Rebuild webclient and fix showWelcome condition
...
- Rebuild dist/ after removing erroneous vue-router
- Fix App.vue showWelcome to use chatStore.loading (prevents flicker
to WelcomeScreen during session load)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 10 May
|
Remove erroneous vue-router from webclient
...
vue-router was accidentally left over from an earlier attempt to embed
admin features in the main client. It broke hash-based session routing
and rendered app-main empty. Revert to direct component rendering in
App.vue with native hashchange handling.
- Remove vue-router dependency and src/router/index.js
- Revert main.js to createApp without router
- App.vue: render WelcomeScreen/ChatArea directly, restore hashchange handler
- chat.js: revert hash format to raw session id
- api/index.js: keep 401 → authStore.user = null (login overlay fix)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 10 May
|
Fix blank session rendering and 401 auth handling
...
- Install missing vue-router dependency (was imported but not in node_modules,
causing app init failure and empty app-main)
- Add :sessionId? route param and HomeView watcher for hash-based session routing
- Update hash format to '#/' for Vue Router compatibility
- Add 401 handling in api/index.js to invalidate auth and show login overlay
- Add error handling in loadSession and WelcomeScreen start to prevent stuck UI
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 10 May
|
| 2026-05-09 |
Replace profile edit drawer with centered modal
...
The drawer was awkward on wide screens. Modal is centered, capped at
900px, with proper header/body/footer layout and scrollable content.
Model & Generation fields now render in a responsive row of 5 columns.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
Add profile editing to admin panel
...
Backend:
- navi/profiles/loader.py: add save_profile_to_dir() to write config.json
and system_prompt.txt back to disk
- navi/core/registry.py: add ProfileRegistry.update() for in-memory updates
- navi/api/routes/admin.py: new endpoints GET /admin/profiles/{id} and
PUT /admin/profiles/{id} for reading and saving full profile config
Admin panel:
- Profiles table: add Edit button per row
- Drawer form with sections: Basic, Model & Generation, Thinking,
Planning, Sub-agent, Tools, System Prompt
- All fields editable inline (text inputs, checkboxes, textareas for lists)
- Save via PUT request, updates both disk and in-memory registry without
server restart
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
Open admin panel in new browser tab from Android and webclient
...
Android:
- Add /admin path to shouldOpenExternally so admin links open in
the system browser instead of the WebView.
Webclient:
- Add target="_blank" and rel="noopener noreferrer" to the admin
link in AppSidebar.vue so it opens in a new tab.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
Fix admin panel review findings
...
- Remove dead admin API functions from webclient/src/api/index.js
(admin is standalone now, no longer part of webclient)
- Harden esc() in admin/index.html to escape quotes (" / ')
- Add 401 redirect to '/' in admin API requests
- Add TypeError catch for offline/network errors with human message
- Remove redundant Yes/No text in profiles table (toggle switch is enough)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
Document Android OAuth bridge page flow
...
- docs/auth.md: describe browser vs Android WebView flows, bridge page
mechanism, state metadata detection via NaviAndroid UA
- docs/api.md: add /auth/mobile-done endpoint reference
- docs/android-client.md: add OAuth/login section covering intent filter,
CookieManager injection, deep-link handling in onCreate/onNewIntent
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
Style OAuth bridge page with gnexus UI kit design system
...
Redesigned /auth/mobile-done to match the Navi webclient visual
language (Tokyo Night cyberpunk palette):
- Dark background (#16161E), muted panel with green success accent
- Squared corners, uppercase headings, wide letter-spacing
- Spinner during auto-redirect, fallback button with left accent border
- Full hover states matching .btn-success from the kit
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
Detect Android OAuth client via User-Agent header
...
WebView always sends NaviAndroid/1.0 in the HTTP User-Agent, while
navigator.userAgent in JS is unreliable. Backend now detects the
Android platform from the UA header when the ?platform query param is
absent, ensuring the bridge-page flow works regardless of webclient
version.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
Improve OAuth bridge page with Chrome Intent URL + fallback button
...
/auth/mobile-done now tries Chrome Intent URL for automatic app
opening, and falls back to a styled button if the browser blocks
automatic navigation to custom schemes.
- Auto-redirect: intent://...#Intent;scheme=navi;package=com.navi.client;end
- Fallback UI: card with \"Open Navi App\" button after 1.5s timeout
- Works in both Chrome (auto) and DuckDuckGo (manual tap)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
Add Android deep-link OAuth bridge for WebView auth
...
Problem: Android WebView opens OAuth in external browser (Chrome).
After successful login, cookie stays in Chrome and WebView remains
unauthenticated because cookies are not shared between apps.
Solution: bridge page flow that avoids cookies entirely for mobile.
Backend:
- /auth/login accepts ?platform=android and ?return_to params
- /auth/callback detects android via state metadata, skips cookie,
redirects to /auth/mobile-done?sid=<session_id>
- /auth/mobile-done renders HTML that deep-links to navi://auth/callback
Webclient:
- login() detects NaviAndroid UA and adds ?platform=android
Android:
- MainActivity: handle incoming navi:// intent in onCreate and onNewIntent,
set cookie via CookieManager, reload WebView
- AndroidManifest: add intent-filter for navi://auth/callback and
singleTask launchMode
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 9 May
|
| 2026-05-08 |
Compact admin/logout buttons in sidebar footer
...
In sidebar-footer-actions, replace text+icon Admin and Logout buttons
with icon-only btn-icon buttons (shield-check and sign-out icons).
Add without-hover class to suppress the default icon rotation hover
animation. Keep the Login button unchanged (text + icon as before).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 8 May
|
Add per-user sessions and memory filters in admin panel
...
Backend:
- GET /admin/memory now accepts user_id query param to filter facts
for a specific user instead of returning the global view.
Frontend:
- Users table now has "Sessions" and "Memory" buttons per row.
- Clicking "Sessions" switches to Sessions tab and pre-fills search
with the user id.
- Clicking "Memory" switches to Memory tab and passes user_id to the
API, showing only that user's facts.
- Manual tab clicks reset filters (search / userId) so the view
returns to unfiltered state.
Docs:
- docs/api.md updated with user_id param for GET /admin/memory.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 8 May
|
Update docs for admin pagination, search, sorting and memory all_users
...
- docs/api.md:
- GET /admin/sessions: document pagination (limit/offset), search,
sort_by and sort_order query params; switch response to {total,
limit, offset, items} envelope.
- GET /admin/memory: same pagination/sort docs, {total, limit,
offset, items} envelope.
- docs/memory.md:
- get_all_facts signature now includes offset, search, sort_by,
sort_order and all_users parameters.
- docs/sessions.md:
- Document count_all and search_list store methods.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 8 May
|

Fix admin memory showing 0 facts; add pagination/search/sort
...
Bug fix:
- get_all_facts(user_id=None) was filtering for user_id IS NULL only,
so admin panel showed 0 facts when facts had user_ids set.
- Added all_users parameter to get_all_facts and fact_count.
- Admin endpoint now passes all_users=True to return all facts.
Memory pagination:
- Extended get_all_facts with offset, search, sort_by, sort_order params.
- Extended fact_count with search and all_users params.
- /admin/memory endpoint now accepts limit, offset, search, sort_by,
sort_order and returns {total, limit, offset, items}.
Admin panel frontend:
- Added server-side search with debounce for memory facts.
- Added sortable column headers (category, key, source, confidence, updated).
- Added pagination controls (prev/next, page size selector).
- Switched memory display from grouped tables to flat sortable table.
Tests:
- Added unit tests for get_all_facts(all_users=True) and
fact_count(all_users=True).
- All 219 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 8 May
|