| 2026-06-22 |
Add NAVI_AUTH_ENABLED switch for optional auth
...
- Add navi_auth_enabled setting (default true) to navi/config.py and .env.example
- When disabled, treat every request as anonymous admin user (id='anonymous')
- Create/update fixed anonymous navi_users row on startup
- Bypass OAuth/cookie/API-token resolution in navi/auth/deps.py
- Update /auth/status to return {enabled, configured}
- Log security warning on startup when auth is disabled
- Update webclient: skip fetchMe/login screen, show Local mode footer,
expose /admin link, warn in API keys panel
- Rebuild webclient production bundle
- Add unit and integration tests for no-auth mode
- Update docs: auth.md, config.md, api.md, api_tokens.md, sessions.md,
websocket.md, mechanics.md, index.md
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
2 days ago
|
| 2026-05-25 |

Fix 19 issues found in full codebase review
...
Backend:
- Stop session auth bypass: require auth for owned sessions, reject anonymous with 401
- upload_file: stream chunks directly to disk instead of buffering in RAM
- MCP config: validate name against path traversal regex
- auth deps: cleanup stale refresh locks periodically
- auth routes: expire mobile auth states after 10 min to prevent unbounded growth
- compressor: meta-summarize existing summaries before compression; preserve assistant content when tool_calls present; rewrite hard_truncate to keep whole turns
- orchestrator: configurable WS replay buffer size; async cleanup/remove_websocket/clear_busy; fix run_recall ContextVar order to avoid deadlock on _build_agent failure; await cleanup in finally
- agent: persist image_msg in session.messages; remove archived messages from session after archive; remove duplicate StreamStopped yield on tool stop
- websocket: try/except around create_task with cleanup on failure; await remove_websocket
Frontend:
- App.vue: hashchange listener lifecycle in onMounted/onUnmounted
- MessageList.vue: passive scroll, flash timeout cleanup, archive scroll snapshot
- InputBar.vue: 300 ms debounce on draft save to localStorage
- SessionList.vue: remove :key from DynamicScroller to avoid remount jitter
Tests: 422 passed, 1 skipped
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 25 May
|
| 2026-05-24 |
Fix settings route switching and document API token system
...
- App.vue: make route reactive via ref + getRouteFromHash() so
#settings toggles work without page reload
- docs/api_tokens.md: new comprehensive API token auth doc
- docs/api.md: add /api-tokens REST endpoints
- docs/auth.md: add token flow architecture diagram and resolution order
- docs/websocket.md: add auth section with cookie vs query-param token
- docs/architecture.md: update to AgentSessionOrchestrator + ToolContext
- docs/tools.md: add gnexus-creds MCP tools
- docs/index.md: link to api_tokens.md
- Rebuild webclient dist
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 24 May
|

Add API token auth system for headless/micro clients
...
Backend:
- navi/auth/_ddl.py: add api_tokens table with boot-time migration
- navi/auth/deps.py: _resolve_user now falls back to X-Api-Token header
and ?api_token query param for WebSocket auth
- navi/auth/__init__.py: add ApiToken pydantic model
- navi/api/routes/api_tokens.py: CRUD endpoints (POST/GET/DELETE)
- navi/main.py: wire api_tokens router
Frontend:
- webclient/src/App.vue: add #settings hash routing
- webclient/src/components/settings/: SettingsView, ApiKeysPanel,
CreateKeyModal with copy-to-clipboard flow
- webclient/src/api/index.js: token CRUD API functions
- webclient/src/stores/apiTokens.js: Pinia store
- webclient/src/components/sidebar/AppSidebar.vue: settings link
- webclient/src/composables/useWebSocket.js: append ?api_token= when
localStorage token is present
Tests:
- tests/unit/auth/test_api_tokens.py: 10 unit tests covering token
resolution (header + query param), revoke, missing/revoked tokens,
orphan users, and CRUD endpoints
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 24 May
|
| 2026-05-13 |
Set browser tab title to active session name or id
...
In App.vue: added computed `documentTitle` and a `watch` that updates
`document.title` whenever the active session changes or its name is
updated. Falls back to session id prefix (8 chars) when unnamed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 13 May
|
| 2026-05-12 |
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
|
| 2026-05-10 |
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-08 |
Add pagination, search, and sorting to admin sessions
...
Backend:
- Add count_all and search_list abstract methods to SessionStore
- Implement count_all and search_list in PgSessionStore (SQL with ILIKE)
- Implement count_all and search_list in InMemorySessionStore
- Update /admin/sessions to accept limit, offset, search, sort_by, sort_order
- Return {total, limit, offset, items} from /admin/sessions
Frontend:
- Add search input for sessions in admin panel
- Add clickable sortable column headers with asc/desc toggle
- Add pagination controls (prev/next, page size selector, item count)
- Debounce search input (300ms)
Tests:
- Add integration tests for pagination, offset, search, and sorting
- All 217 tests pass
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 8 May
|
| 2026-05-04 |
Dark login screen: #111 overlay, transparent card
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 4 May
|
Add full-screen login overlay for unauthenticated users
...
- Backend: new endpoint GET /auth/status returns {configured: bool}
- Webclient auth store: add authConfigured ref + fetchStatus()
- LoginScreen.vue: centered card with logo, title, and login button
- App.vue: show LoginScreen overlay when auth is configured but
user is not authenticated (z-index 9999, blocks all UI)
- App.vue onMounted: fetch auth status before trying to resolve user
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 4 May
|
| 2026-05-03 |
Multi-user auth via gnexus-auth OAuth + hybrid role/permission model
...
- Integrate gnexus-auth-client-py (GAuthClient) for OAuth flow, token refresh,
and webhook parsing
- Add navi/auth/ package: User model, Fernet encryptor, client singleton,
deps (get_current_user, require_admin, require_permission)
- New tables: navi_users, user_auth_sessions (auto-created on startup)
- Session/memory isolation by user_id with legacy NULL support
- Cookie-based auth proxy: /auth/login, /callback, /logout, /me
- Webhook receiver /webhooks/gnexus-auth handling user events, global logout,
session revocation, role/permission changes
- Admin endpoints (/admin/*) gated by role + permissions
- Webclient auth store with isAdmin/hasPermission guards
- Admin-only profile filtering in /agents/profiles
- 200/200 tests passing
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 3 May
|
| 2026-05-02 |
Paginate session list loading
Eugene Sukhodolskiy
committed
on 2 May
|
| 2026-04-30 |
Improve artifacts workspace controls
Eugene Sukhodolskiy
committed
on 30 Apr
|
Improve content publishing UX
Eugene Sukhodolskiy
committed
on 30 Apr
|
| 2026-04-24 |
WelcomeScreen polish, root-path fix, docs update
...
- Move mobile sidebar button to top-left corner (no header bar backdrop)
- Show WelcomeScreen on / with no hash instead of auto-loading first session
- Docs: document Ollama multi-server fallback, model priority lists, OLLAMA_BACKENDS_FILE
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 24 Apr
|
Fix WelcomeScreen: add with-icon, mobile sidebar toggle
...
- Add with-icon class to Start button
- Add mobile-only header with sidebar toggle (reuses chat-header +
btn-sidebar-toggle styles, hidden on desktop via existing CSS)
- Wire toggle-sidebar event through App.vue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 24 Apr
|
Go to WelcomeScreen when active session is deleted
...
Previously deleting the active session would load the first session from
the list. Now it calls clearSession() which resets currentId to null,
and showWelcome now triggers on currentId === null (not just empty list).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 24 Apr
|
| 2026-04-17 |
Webclient UI improvements + backend fixes
...
Webclient:
- Draft persistence across page refreshes (localStorage, reactive watch)
- Image lightbox modal using UI kit classes on thumbnail click
- Copy button on user and assistant messages
- Selection reply toolbar: select assistant text → quote inserted into input
- User message rendering: proper HTML escaping, styled blockquote for > replies
- Markdown table fix: preprocessor to inject missing separator rows
- Planning status labels (rebuild dist)
Backend:
- Developer profile: enable subagent delegation, increase max_iterations to 35
- share_file: updated description + manual with absolute path requirement and URL sharing
- persona.txt: instructions for quote replies and GFM table format
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 17 Apr
|
| 2026-04-16 |
webclient: message timestamps, confirm dialog, layout and UX fixes
...
- Add useTime.js: relative time labels ("just now", "5m ago", HH:MM) with auto-refresh every 30s
- Show message timestamps below user bubbles and assistant replies
- Show session last_active time in sidebar below preview
- Add ConfirmDialog.vue + useConfirm.js: kit-styled modal confirm, wired to delete in SessionItem
- SessionList: switch RecycleScroller → DynamicScroller to support variable item heights
- SessionItem: remove fixed 74px height; show action buttons always on touch devices (hover: none)
- MessageList: constrain content to max-width 920px centered (message-list-inner, input-row)
- MessageList: replace TransitionGroup with plain v-for; animate only new messages via .msg-enter CSS class, history loads silently without scroll animation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 16 Apr
|
Migrate to Vue webclient; rename old client to old_webclient
...
- client/ → old_webclient/ (vanilla JS client preserved as reference)
- webclient/ — new Vue 3 + Pinia webclient (source + dist build)
- vite.config.js: outDir changed to webclient/dist/
- main.py: serve /assets and /images from webclient/dist/,
index.html from webclient/dist/index.html
- .gitignore: exclude webclient/node_modules/, include webclient/dist/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 16 Apr
|