Commit Graph

104 Commits

Author SHA1 Message Date
ekko b4f809d8b5 fix: improve chat scroll behavior and dark mode readability
- Smart auto-scroll: only follow SSE stream when user is near bottom (200px threshold), scroll once on send/switch session
- Brighten dark mode text colors (primary #e0→#f0, secondary #a0→#c0, muted #66→#88)
- Fix tool-call panel height to match thinking video (120px→213px)
- Fix tool-call item background invisible in dark mode
- Fix gateway start button using hardcoded dark color

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 10:46:33 +08:00
ekko 4f923da490 feat: replace ModelSelector dropdown with modal picker
NSelect dropdown is unusable with providers that have hundreds of models.
Replaced with a modal dialog featuring search filter, collapsible provider
groups, and click-to-select.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 22:08:34 +08:00
ekko aa34b02b09 chore: bump version to 0.3.5
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 14:34:50 +08:00
ekko 07d36297d6 Merge remote-tracking branch 'origin/main' into feat/multi-gateway 2026-04-18 14:33:04 +08:00
ekko 27051dcb32 feat: profile-aware cache isolation and UX improvements
- Fix chat store cache keys to include profile name, prevent data leaking between profiles
- Defer cache hydration to after profile load to avoid race condition
- Remove collapsible sidebar feature (not needed)
- Remove confirmation dialog on profile switch (direct reload)
- Auto-start gateway when creating new profile
- Clear profile-specific localStorage cache on profile delete (safe prefix matching)
- Clean up unused imports in SettingsView

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 14:32:54 +08:00
ekko da7910f934 Merge pull request #44 from 0xnuu/pr/chat-resilience-sidebar
feat(chat): improve resilience and collapsible sidebar
2026-04-18 14:32:36 +08:00
Shentar 0df3303f8f feat: add terminal theme selector with 15 presets
Add NSelect dropdown in terminal toolbar to switch themes dynamically.
Includes 9 dark themes (Default, Solarized Dark, Monokai, Dracula, Nord,
One Dark, GitHub Dark, Tokyo Night) and 6 light themes (Solarized Light,
GitHub Light, Catppuccin Latte, Alabaster, XTerm Light, One Light,
Gruvbox Light). Theme choice persists via localStorage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 13:14:20 +08:00
ekko 17f0cdc1de Merge branch 'pr-44' into feat/multi-gateway
# Conflicts:
#	packages/client/src/components/layout/AppSidebar.vue
2026-04-18 13:12:42 +08:00
ekko b9e0aefec3 Merge branch 'pr-43' into feat/multi-gateway 2026-04-18 13:09:21 +08:00
ekko 4b6de351bd feat: add multi-gateway management with auto port detection
- Add GatewayManager for multi-profile gateway lifecycle management
- Auto-detect running gateways on startup via PID + health check
- Port conflict detection: check managed gateways, allocated ports, and
  system-level port availability (TCP bind test)
- Two-phase startup: sequential port resolution, parallel process launch
- Use `gateway start/restart` on normal systems, `gateway run --replace`
  on WSL/Docker
- Wait for health check before returning start/stop responses
- Add Gateways page with card-based layout showing profile status
- Reorganize sidebar navigation into collapsible groups
- Hide API server settings (now auto-managed by GatewayManager)
- Profile switch reloads page; Ctrl+C no longer stops gateways
- Remove redundant ensureApiServerConfig from index.ts and profiles.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 13:07:12 +08:00
Shentar 40d4b9ac4b feat: add terminal theme selector with 15 presets
Add NSelect dropdown in terminal toolbar to switch themes dynamically.
Includes 9 dark themes (Default, Solarized Dark, Monokai, Dracula, Nord,
One Dark, GitHub Dark, Tokyo Night) and 6 light themes (Solarized Light,
GitHub Light, Catppuccin Latte, Alabaster, XTerm Light, One Light,
Gruvbox Light). Theme choice persists via localStorage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 11:26:09 +08:00
ekko 7264eabfe2 Merge dev into main
- fix: avoid full session export in session list (#38)
- fix: fallback title from preview when session has no explicit title
- fix: use dynamic import for node:sqlite with Node version guard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 09:35:03 +08:00
ekko 35481e452d fix: use dynamic import for node:sqlite with Node version guard
Replace static top-level import with runtime version check and dynamic
import() so Node < 22.5 gracefully falls back to CLI path instead of
crashing at module load time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 09:34:59 +08:00
ekko fd7071b75d fix: fallback title from preview when session has no explicit title
SQLite path was returning null title for sessions without an explicit
title, while the CLI path derives it from the first user message.
Now uses the preview (first user message content) as title fallback,
matching the original CLI behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 08:53:45 +08:00
ekko 7e84c56c20 fix: avoid full session export in session list (#38)
Read lightweight session summaries directly from state.db via node:sqlite
instead of exporting full transcripts through hermes CLI. Falls back to
CLI path if sqlite query fails. Includes title fallback from preview when
no explicit title is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 08:53:38 +08:00
ekko d6661c0325 Merge branch 'dev' 2026-04-18 08:29:51 +08:00
ekko 4dc3b3cd56 chore: add MIT LICENSE file
Closes #39

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 08:27:40 +08:00
Burak bcfbaa6a24 fix: avoid full session export in session list 2026-04-17 12:56:41 -04:00
zksnet 7e777fd661 feat(chat): improve resilience and collapsible sidebar
问题描述:\n- 刷新页面、切后台或手机锁屏后,进行中的对话容易丢失,SSE 断开时前端还会插入假的错误气泡\n- 移动端首屏会话列表会短暂遮住聊天区\n- 桌面端侧栏无法折叠,在窄窗口和缩放场景占用过多横向空间\n\n复现路径:\n- 发起一轮对话,在模型仍在输出时刷新页面或锁屏后再回到页面\n- 在窄屏设备首次打开聊天页,观察会话列表首帧覆盖聊天内容\n- 在桌面端缩窄浏览器窗口,观察侧栏始终保持完整宽度\n\n修复思路:\n- 为 chat store 增加本地缓存、水合、in-flight 标记和轮询恢复,SSE 断开后静默从服务端回补真实结果\n- 将运行中指示统一到 isRunActive,让实时流式与恢复轮询共享同一状态\n- 在 ChatPanel 首帧同步读取媒体查询,避免移动端会话列表闪烁覆盖\n- 为侧栏增加可持久化的桌面折叠状态,并补充对应文案与回归测试
2026-04-18 00:00:24 +08:00
ekko d40c224196 feat: add GitHub link to sidebar footer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 23:29:24 +08:00
ekko bf726a9ec0 Merge branch 'dev' 2026-04-17 23:14:28 +08:00
ekko 9979871550 feat: add Codex OAuth login and fix channel config display
- Add OpenAI Codex Device Code Flow login (backend polling + frontend modal)
- Codex provider integrated into preset dropdown (hides URL/API key fields)
- Sync provider model catalogs with Hermes system
- Fix channel config not displaying on first visit (wait for data load)
- Fix sidebar model list not refreshing after adding provider
- Add autocomplete="off" to API key input to prevent browser autofill

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 23:11:57 +08:00
ekko 26bb821e29 feat: support manual model input and sync provider catalogs
- Allow manual model name input when adding custom providers (NSelect tag mode)
- Sync provider model catalogs with Hermes _PROVIDER_MODELS
- Add new providers: kimi-coding-cn, moonshot, arcee
- Fix provider key naming to match Hermes (kilo→kilocode, vercel→ai-gateway, etc.)
- Ensure custom_providers from config.yaml always appear in available-models
- Append configured default model to model list if not in catalog
- Fix provider deletion with case-insensitive key matching
- Add selectOrInput i18n key to all 8 locales

Closes #24

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 22:05:06 +08:00
ekko 4d98209d13 Merge branch 'dev' into main — v0.3.2
- fix: use deep merge for config updates to prevent nested field loss
- fix: save config inputs on blur instead of every keystroke
- fix: job edit schedule format error (#25)
- chore: add engines requirement (node >= 20)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 17:50:47 +08:00
ekko ca3fea4d0e chore: add engines requirement (node >= 20) and bump version to 0.3.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 17:50:28 +08:00
ekko b290b755c9 fix: use deep merge for config updates and save inputs on blur
- Backend: replace shallow merge with recursive deepMerge in PUT /api/hermes/config
  to prevent nested config fields from being lost when updating partial values
- Frontend: switch all NInput fields to default-value + @change (save on blur)
  instead of :value + @update:value (save on every keystroke) in both
  PlatformSettings.vue and SettingsView.vue api_server tab
- Remove unused debounce logic and dead changeKey function

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 17:43:54 +08:00
ekko 3d2b1c5e47 fix: job edit schedule format error and refactor services directory
- Fix #25: job update sends schedule as plain string but upstream expects
  { kind, expr, display } object, causing "'str' object has no attribute 'get'"
- Move hermes-cli.ts, hermes.ts, hermes-profile.ts into services/hermes/
  for multi-agent namespacing consistency
- Fix ts-node Set spread compatibility in filesystem.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 16:48:24 +08:00
ekko 9a0b50f370 fix: add MiniMax highspeed variants and deduplicate model list
- Add MiniMax-M2.7/M2.5/M2.1/M2 -highspeed variants for both
  international and China providers (#17)
- Deduplicate models in /available-models response to fix
  repeated entries when using Copilot or other providers (#18)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 12:04:20 +08:00
ekko dcb477594b feat: add 6 new locales (ja, ko, fr, es, de, pt) and UI polish
- Add Japanese, Korean, French, Spanish, German, Portuguese translations
- Improve session active state visibility in both themes
- Static language labels in LanguageSwitch component
- Dark theme: lighten chat input background for better contrast
- Fix system theme listener not toggling back to light

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:09:50 +08:00
ekko 16e07bcc9b feat: dark theme polish — fix sidebar layout, update button, chat input & theme switching
- Fix sidebar footer layout: separate update button from version row
- Replace custom update-hint with NButton for proper dark mode support
- Darken chat input background in dark theme for better contrast
- Fix system theme listener always applying dark mode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:37:57 +08:00
ekko 6df7cada04 Merge branch 'feat/dark-theme' into dev 2026-04-17 08:13:30 +08:00
ekko a036569041 Merge pull request #16 from P2K0/feat/docker-compose-gateway-stability
feat: add docker-compose deployment and harden gateway startup
2026-04-17 08:11:04 +08:00
ekko d7d62e5f6c Merge pull request #15 from later0day/later0day/fix-node-pty-helper-perms
Prevent macOS terminal sessions from failing after node-pty installs
2026-04-17 08:10:58 +08:00
P2K0 f0d1d2e16c feat: add docker-compose deployment and harden gateway startup
- add docker-compose setup with hermes-agent + hermes-webui

- make runtime config env-driven (compose vars + HERMES_BIN)

- improve gateway startup/restart resilience in docker

- make base image configurable via BASE_IMAGE/HERMES_AGENT_IMAGE

Closes https://github.com/EKKOLearnAI/hermes-web-ui/issues/14
2026-04-17 06:43:42 +08:00
later0day 7eab694fe9 Prevent macOS terminal sessions from failing after node-pty installs
Node-pty's darwin helper can lose its execute bit in local installs, which leaves the module loadable but causes terminal session creation to fail with posix_spawnp errors. Normalize helper permissions before loading node-pty and remove the rebuild-only hint so startup repairs the real failure mode automatically.

Constraint: Must preserve Node 24 and the existing node-pty integration path
Rejected: Pipe fallback transport | loses true PTY behavior such as proper terminal semantics
Rejected: Tell users to run npm rebuild node-pty | rebuild alone did not restore the helper execute bit here
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If a future node-pty release changes helper locations, update the helperCandidates list before touching terminal startup again
Tested: npm run build
Tested: WebSocket terminal session create + echo command on localhost:8648 under Node 24/macOS
Not-tested: Non-macOS helper layouts
2026-04-16 23:44:43 +08:00
ekko a54a89d521 fix: update video assets and sidebar dark background color
Replace video assets with processed versions, update sidebar logo
dark background to #393939, restore streaming indicator with
theme-aware video switching.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 23:43:54 +08:00
ekko b5aeb876b8 feat: add dark theme support with CSS custom properties and Naive UI integration
Implement runtime theme switching using CSS custom properties delegated through SCSS variables, with light/dark/system modes, FOUC prevention, sidebar toggle, and settings selector. Add theme-aware video assets for sidebar and chat thinking indicator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 23:13:04 +08:00
ekko 076a7c2a38 feat: add Vitest testing framework, fix proxy auth stripping and 401 handling
- Set up Vitest with jsdom for client tests, node for server tests
- Add tests for auth service, proxy handler, API client, and profiles store
- Strip Authorization header in proxy to prevent web-ui token leaking to gateway
- Distinguish local BFF vs proxied gateway 401s to avoid false logouts
- Remove unused hero.png asset

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 20:24:09 +08:00
ekko b8d121ed79 Merge branch 'dev'
# Conflicts:
#	package.json
2026-04-16 15:21:24 +08:00
ekko 26423984d1 fix: profile import file upload, startup health check, sidebar scroll, node-pty fallback
- Change profile import from server path input to browser file upload (multipart)
- Fix startup script to wait for health check before opening browser
- Add overflow scroll with hidden scrollbar to sidebar nav
- Graceful degradation when node-pty fails to load (WSL compatibility)
- Remove rename button from profile cards
- Restrict profile name input to English letters, numbers, hyphens
- Use raw.githubusercontent.com URLs in README setup script

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 15:19:05 +08:00
ekko 99a47cf1ad feat: profile-aware routes, provider sync, channel settings improvements
- Add hermes-profile.ts for dynamic profile path resolution (all backend
  routes now read from active profile directory instead of hardcoded ~/.hermes/)
- Add profile switcher dropdown in sidebar, reload page on switch
- Sync PROVIDER_PRESETS with Hermes CLI (fix keys: kimi-coding→kimi-for-coding,
  kilocode→kilo, ai-gateway→vercel, opencode-zen→opencode; remove moonshot)
- Sync PROVIDER_ENV_MAP with Hermes models.dev + overlays (correct env var names)
- Add gateway restart after adding model provider
- Don't write GLM_BASE_URL/KIMI_BASE_URL for zai/kimi (let Hermes auto-detect)
- Write API keys to .env and credential_pool for all providers
- Built-in providers skip custom_providers in config.yaml
- Add debounce + per-field loading state for channel settings inputs
- Run hermes setup --reset for profiles without config.yaml
- Create empty .env for new profiles (not copied from default)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 13:51:42 +08:00
ekko 014168864f fix: always overwrite api_server config on startup
Simplify ensureApiServerConfig to unconditionally write default
platforms.api_server values, preventing missing config issues.

Bump version to 0.2.7.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:59:18 +08:00
ekko 293f36ecac fix: always overwrite api_server config on startup
Simplify ensureApiServerConfig to unconditionally write default
platforms.api_server values, preventing missing config issues.

Bump version to 0.2.7.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:54:58 +08:00
ekko 04b80a616e feat: add profile management page with full CRUD UI
- Add frontend API layer, Pinia store, and 5 components (ProfileCard, ProfilesPanel, ProfileCreateModal, ProfileRenameModal, ProfileImportModal)
- Add ProfilesView page with card grid layout and expandable details
- Modify export endpoint to stream file as browser download instead of returning server path
- Add sidebar nav entry, router route, and i18n translations (en/zh)
- Support create, rename, delete, switch (with gateway restart), export, and import profiles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:40:25 +08:00
ekko 57ef171dda docs: add openapi.json specification
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 08:39:53 +08:00
ekko 351c861777 refactor: restructure project for multi-agent extensibility
- Migrate source to packages/client and packages/server directories
- Namespace all Hermes-specific code under hermes/ subdirectories
  (api/hermes/, components/hermes/, views/hermes/, stores/hermes/)
- Add hermes.* route names and /hermes/* path prefixes
- Upgrade @koa/router to v15, adapt path-to-regexp v8 syntax
- Fix proxy path rewriting: /api/hermes/v1/* → /v1/*, /api/hermes/* → /api/*
- Fix frontend API paths to match backend /api/hermes/* routes
- Fix WebSocket terminal path to /api/hermes/terminal
- Add proxyMiddleware for reliable unmatched route proxying
- Add profiles route module and hermes-cli profile commands
- Update CLAUDE.md development guide with new architecture
- Add Chinese README (README_zh.md)
- Add Web Terminal feature to README

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 08:38:18 +08:00
ekko 4917242dca fix: add auth to /upload endpoint to resolve 401 on file attachment
Fixes #10

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:29:44 +08:00
ekko 71c7f25f4b feat: add web terminal, improve README, fix node-pty and i18n issues
- Add web terminal view with xterm.js and node-pty WebSocket backend
- Rewrite README with badges, feature table, mobile demo video
- Add package keywords and improved description for npm/GitHub SEO
- Fix node-pty spawn-helper missing execute permission after npm install -g
- Auto-fix node-pty permissions on CLI startup
- Fix duplicate 'error' key in en.ts and zh.ts i18n files
- Remove nested NSpin in PlatformSettings (causes invisible loading spinner)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 16:36:04 +08:00
ekko d258875cef feat: support concurrent session streaming, persist active session, and improve 401 handling
- Refactor streaming to use Map<string, AbortController> for multi-session concurrency
- SSE callbacks capture session ID in closure, no cross-session interference
- messages is now computed from activeSession, no manual sync needed
- Persist active session ID to localStorage, restore on reload
- Auto-expand session group when restoring saved session
- Clear auth key and redirect to login on 401 (skip if already on login page)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 11:00:47 +08:00
ekko 2faa6fb95c chore: bump version to 0.2.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 10:29:36 +08:00