| 2026-10-06 |
webclient: tool-count badge, kit-styled content card, thinking corner gap, chat top gap, drop duplicate reconnect notice
Eugene Sukhodolskiy
committed
1 day ago
|
| 2026-10-05 |

webclient: retokenize styles onto gn-ui-kit v1.0 CSS variables
...
All ~165 legacy var() usages (--color-*, --surface*, --accent*, --border,
--text*) with hex fallbacks and ~150 raw hex literals across app.scss and
24 scoped style blocks are swapped to the kit's --gn-* tokens per the
intent of the old fallback values:
- accent/primary/teal (#7aa2f7/#4ec9b0) -> --gn-color-secondary
- amber/orange highlights -> --gn-color-accent
- text greys -> --gn-color-text-{light,medium,dark}
- panels -> --gn-surface-panel; elevated tints -> color-mix over panel
- translucent overlays -> color-mix(in srgb, ..., transparent)
Deliberately literal: terminal deep bg #0f0f14 (darker than any token)
and the content-card image badge teal #89dceb (kit has no teal). File
type badges keep a categorical palette via nearest kit tokens.
Dead "UI kit overrides" block halved: kit 1.0 dropped hover icon
rotation, so only the app-owned chevron open-state flip remains.
Verified: vitest 111 passed, build OK, dev render matches W1 baseline
Eugene Sukhodolskiy
committed
2 days ago
|
webclient: loading indicators where the UI looked frozen
...
- session open: centered spinner in MessageList while chat.loading
- image paste/drop: imagesProcessing counter (chat store, shared);
FilePreviewStrip shows spinner placeholder tiles where the resized
previews will land
- file upload: indeterminate sliding bar instead of the fake static 60%
- send → run start gap: "Sending…" hint with spinner, cleared on
stream_start / message_queued / stream end / error / session switch
- content-card images: skeleton with spinner until @load (reset on src
change); wrapper keeps min-height while the img is empty
vitest 96 passed.
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-04-29 |

Stability fixes batch — tech debt review 2026-04-29
...
Critical:
- Concurrent WS run race guard (#1)
- Tool task cancellation on generator teardown (#2)
- StopAsyncIteration kills fallback chain (#3)
- Session loading race with _lastLoadId guard (#4)
- ContentCard .match() crash on non-string result (#5)
- Image data type guard in buildMessageList (#6)
High:
- Cap WS replay buffer at 500 events (#7)
- Deduplicate memory extraction task with asyncio.Lock (#9)
- TTL-based fallback blacklisting (5 min) (#10)
- Subagent tool exception isolation (#11)
- Inline image size/count validation on WS (#12)
- Clean up orphaned file on DB insert failure (#13)
- Deep watch streamingMsg for auto-scroll (#14)
- WS_SCHEME wss:// support for HTTPS (#15)
- Sending guard against duplicate message sends (#16)
- Global unhandledrejection listener in API layer (#17)
Medium:
- Cap planning_logs at 20 entries (#22)
- Store cleanup_loop task reference (#23)
- BaseException → Exception in _run_with_sentinel (#24)
- Propagate SystemExit in agent loop (#25)
- Configurable output_reserve_tokens (#26)
- Always reloadSession on session_sync (#30)
- FIFO queue for confirm dialogs (#31)
- Reset body.overflow on ImageLightbox unmount (#32)
- try/finally in fallback copy (#33)
- _isConnecting guard in WS send() (#34)
Low:
- Lazy-init deps.py singletons (#36)
- Replace __import__ with direct imports (#38)
- Preserve token count 0 in ollama.py (#39)
- Clear orphaned streamingMsg on reconnect reload (#43)
- Escape single quote in UserMessage (#44)
- Polyfill-free findLast replacement (#48)
- Match <table> tags with attributes in markdown (#49)
- Attach copy buttons only when msg.done (#50)
- Fix hasMeta falsy-0 bug (#53)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 29 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 |
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
|