Replace hardcoded 'claude' string with getDefaultClaudeCodePath() to
ensure the correct Claude Code executable path is resolved, consistent
with claudeLocal.ts. This respects HAPI_CLAUDE_PATH env var and finds
the global claude installation path properly.
On iPadOS with a hardware keyboard, `isTouch` is true (via pointer:coarse)
so submitOnEnter is disabled and there's no keyboard-based way to send.
Add Shift+Enter as a send shortcut that works on all platforms without
changing existing behavior — desktop Enter-to-send is preserved.
Closes#175
via [HAPI](https://hapi.run)
Co-authored-by: HAPI <noreply@hapi.run>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(cli): support slash commands from installed plugins
Allows HAPI to automatically scan and load slash commands from installed Claude plugins (e.g. superpowers). Commands are indexed with their plugin namespace prefix.
* fix(web): add 'plugin' to SlashCommand source type
This fixes the typecheck error identified by the PR review bot.
* fix(web): update Suggestion type to include 'plugin' source
* fix(slashCommands): 修复 scoped 插件名称解析及多版本安装选择逻辑
- 使用 lastIndexOf('@') 替代 split('@')[0] 以正确解析带 scope 的插件名
- 按 lastUpdated 降序排序选择最新的安装实例
- 增加 installations 空数组边界检查
- Remove Quick Tunnel (TryCloudflare) documentation as it doesn't support SSE which HAPI uses for real-time updates
- Add warning note explaining the limitation with link to Cloudflare docs
- Keep only Named Tunnel as the recommended approach
- Add tip about HAPI_RELAY_FORCE_TCP environment variable for users experiencing connectivity issues
Add comprehensive contributor guidelines including code of conduct,
AI-generated code policy (GPT-5.2-codex only), PR best practices
(no mega PRs), bug report/feature request procedures, and getting
started instructions.
On Windows, spawning Claude with shell: true causes the process to
exit immediately with code 1. This happens because shell: true invokes
cmd.exe /c claude <args>, and cmd.exe's PATH resolution differs from
direct process creation, leading to environment inconsistencies.
This fix:
- Adds findWindowsClaudePath() to locate claude.exe absolute path
- Changes spawn to use absolute path with shell: false on Windows
- Maintains Unix behavior (command name works fine with shell: false)
- Adds HAPI_CLAUDE_PATH env var for user override
Tested on Windows 11 with Claude Code v2.1.29 and hapi v0.15.0.
via [HAPI](https://hapi.run)
Co-authored-by: HAPI <noreply@hapi.run>
* feat(web): add built-in Nerd Font for terminal icon support
Add MesloLGLDZ Nerd Font as a built-in web font to ensure Powerlevel10k
and other Nerd Font-dependent prompts render correctly in the web terminal,
even on devices without local Nerd Fonts installed (e.g., mobile phones).
Changes:
- Add MesloLGLDZNerdFontMono-Regular.woff2 to web/public/fonts/
- Load font via FontFace API with BASE_URL support for subpath deployments
- Merge font loading and terminal creation in same useEffect to ensure
font is ready before terminal renders
Fixes#121
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: use CDN for Nerd Font instead of bundled file
Load MesloLGLDZ Nerd Font from jsDelivr CDN instead of bundling the 1.2MB
font file. This reduces the bundle size significantly while still ensuring
Nerd Font icons display correctly on all devices.
CDN URL: https://cdn.jsdelivr.net/gh/mshaugh/nerdfont-webfonts@v3.3.0/build/fonts/MesloLGLDZNerdFontMono-Regular.woff2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(web): prevent message ordering issues when switching sessions
When switching between sessions or loading paginated messages, old tool
blocks from agentState.requests were being mixed with current messages,
causing display order issues.
Root cause: reduceChatBlocks creates tool blocks for all permissions in
agentState, including those older than the current message page. These
old blocks (with earlier createdAt) would appear mixed with newer messages.
Fix:
1. In reducer.ts: Skip creating permission-only tool blocks if their
createdAt is older than the oldest message in the current view
2. In SessionChat.tsx: Clear caches synchronously in useMemo when session
changes, since useEffect runs after render
Closes#148
via [HAPI](https://hapi.run)
Co-Authored-By: HAPI <noreply@hapi.run>
---------
Co-authored-by: tfq <tfq@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: HAPI <noreply@hapi.run>
- Add ReconnectingBanner component to show "Reconnecting..." status
- Track SSE connection state in App.tsx with onDisconnect handler
- Add onBlocked callback to useSendMessage for handling blocked send attempts
- Provide haptic feedback when send is blocked due to no API or session
- Show toast notification when message cannot be sent due to server disconnection
- Add translation keys for reconnecting message and send blocked feedback in en/zh-CN
close#125
- Add settings.json column to environment variables table with key name mappings
- Document missing ENV variables: TELEGRAM_BOT_TOKEN, TELEGRAM_NOTIFICATION,
HAPI_RELAY_FORCE_TCP, VAPID_SUBJECT
- Add settings.json example with configuration priority explanation
- Create JSON Schema file for settings.json validation and editor autocompletion
with all fields, descriptions, and ENV variable references
clsoe #113
* feat(web): add About section to settings page
- Add website link to hapi.run
- Display app version from CLI package
- Display protocol version from shared module
- Add Vitest testing setup with settings page tests
🤖 Generated with Claude Code
* test(web): add tests for website link and i18n key usage
Address residual risks mentioned in PR review:
- Test website link URL and security attributes (target, rel)
- Verify correct i18n keys are used for About section via spy
Simplify test setup by using real I18nProvider and en locale.
🤖 Generated with Claude Code
- Add Settings > Display > Font Size selector (80/90/100/110/120%)
- Persist preference (hapi-font-scale) and apply globally via --app-font-scale
- Normalize main UI typography to match Settings
Move getInputString, getInputStringAny, and truncate functions from
individual ToolCard components into a dedicated toolInputUtils module
to eliminate duplication across PermissionFooter, ToolCard, and
knownTools components.
Corrects outdated information about HAPI's decentralized architecture compared
to Happy's centralized approach. Updates user model, encryption strategy,
and deployment details to reflect current design. Clarifies that HAPI supports
both self-hosted and relay modes with proper security implications.
- Define PROTOCOL_VERSION constant in shared/src/version.ts
- Server sets X-Hapi-Protocol-Version header on /cli/* responses
- Server includes protocolVersion in /health endpoint
- CLI extracts serverProtocolVersion from API responses
- CLI shows version mismatch hints in both directions
- Add tests for error utilities and version extraction
close#104
Add ability to resume inactive sessions and automatically continue with new
session ID. Includes message merging for preserving conversation history,
UI improvements to allow sending during inactive state, and database schema
migration. close#87