mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
release: v0.3.1
Prepare the desktop release metadata, concise release notes, and the final terminal help polish for the 0.3.1 release. The release note groups the post-0.3.0 work by user-facing area instead of listing every commit, and the desktop version metadata is aligned for the tag-triggered packaging workflow. Constraint: GitHub Release body is sourced from release-notes/v0.3.1.md in the tagged commit Rejected: List every post-0.3.0 commit in the release note | too noisy for this patch release Confidence: high Scope-risk: narrow Tested: cd desktop && bun run test -- src/pages/TerminalSettings.test.tsx --run Tested: bun run check:desktop Tested: bun run check:native Tested: bun run verify (passed=8 failed=0 skipped=2) Not-tested: Live provider release gate
This commit is contained in:
parent
990733cf2c
commit
1464ef538e
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "claude-code-desktop",
|
||||
"private": true,
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
2
desktop/src-tauri/Cargo.lock
generated
2
desktop/src-tauri/Cargo.lock
generated
@ -482,7 +482,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "claude-code-desktop"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"portable-pty",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "claude-code-desktop"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/nicegui/nicegui/main/nicegui/static/tauri-schema-v2.json",
|
||||
"productName": "Claude Code Haha",
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.1",
|
||||
"identifier": "com.claude-code-haha.desktop",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
|
||||
@ -179,6 +179,7 @@ export const en = {
|
||||
// Settings > Terminal
|
||||
'settings.terminal.title': 'Terminal',
|
||||
'settings.terminal.description': 'Run host-machine commands for plugin, skill, and MCP setup. The desktop app includes claude-haha; replace documented claude <args> with claude-haha <args>, for example: claude-haha plugin install ... or claude-haha mcp add ...',
|
||||
'settings.terminal.infoLabel': 'Terminal setup help',
|
||||
'settings.terminal.clear': 'Clear',
|
||||
'settings.terminal.restart': 'Restart',
|
||||
'settings.terminal.windowTitle': 'Host shell',
|
||||
|
||||
@ -181,6 +181,7 @@ export const zh: Record<TranslationKey, string> = {
|
||||
// Settings > Terminal
|
||||
'settings.terminal.title': '终端',
|
||||
'settings.terminal.description': '直接运行宿主机命令,用于安装插件、Skills、MCP 等扩展。桌面端已内置 claude-haha;文档里的 claude <参数> 可替换成 claude-haha <参数>,例如 claude-haha plugin install ... 或 claude-haha mcp add ...',
|
||||
'settings.terminal.infoLabel': '终端安装说明',
|
||||
'settings.terminal.clear': '清屏',
|
||||
'settings.terminal.restart': '重启',
|
||||
'settings.terminal.windowTitle': '宿主机 Shell',
|
||||
|
||||
@ -138,6 +138,20 @@ describe('TerminalSettings', () => {
|
||||
expect(screen.queryByText('Host shell')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('shows setup guidance from the terminal info button', () => {
|
||||
render(<TerminalSettings />)
|
||||
|
||||
const button = screen.getByRole('button', { name: 'Terminal setup help' })
|
||||
const help = screen.getByRole('tooltip')
|
||||
expect(button).toHaveAttribute('aria-expanded', 'false')
|
||||
|
||||
fireEvent.click(button)
|
||||
|
||||
expect(button).toHaveAttribute('aria-expanded', 'true')
|
||||
expect(help).toHaveTextContent('plugin, skill, and MCP setup')
|
||||
expect(help).toHaveTextContent('claude-haha plugin install')
|
||||
})
|
||||
|
||||
it('lets the settings page keep scrolling when the terminal is not focused', async () => {
|
||||
terminalMocks.available = true
|
||||
const container = document.createElement('div')
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState, type WheelEvent } from 'react'
|
||||
import { useCallback, useEffect, useId, useMemo, useRef, useState, type WheelEvent } from 'react'
|
||||
import { Info } from 'lucide-react'
|
||||
import { useTranslation, type TranslationKey } from '../i18n'
|
||||
import { terminalApi } from '../api/terminal'
|
||||
import { useSettingsStore } from '../stores/settingsStore'
|
||||
@ -359,6 +360,7 @@ export function TerminalSettings({
|
||||
<h2 className={`${docked ? 'text-[13px]' : 'text-sm'} shrink-0 font-semibold text-[var(--color-text-primary)]`}>
|
||||
{t('settings.terminal.title')}
|
||||
</h2>
|
||||
<TerminalHelpHint compact={docked} />
|
||||
<StatusPill status={status} label={t(STATUS_LABEL_KEYS[status])} compact={docked} />
|
||||
{shellInfo && (
|
||||
<div className="flex min-w-0 items-center gap-1.5 text-xs text-[var(--color-text-tertiary)]">
|
||||
@ -534,6 +536,37 @@ export function TerminalSettings({
|
||||
)
|
||||
}
|
||||
|
||||
function TerminalHelpHint({ compact = false }: { compact?: boolean }) {
|
||||
const t = useTranslation()
|
||||
const tooltipId = useId()
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<span className="group relative inline-flex shrink-0">
|
||||
<button
|
||||
type="button"
|
||||
aria-label={t('settings.terminal.infoLabel')}
|
||||
aria-describedby={tooltipId}
|
||||
aria-expanded={open}
|
||||
onClick={() => setOpen((value) => !value)}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Escape') setOpen(false)
|
||||
}}
|
||||
className={`${compact ? 'h-6 w-6' : 'h-7 w-7'} inline-flex items-center justify-center rounded-full text-[var(--color-text-tertiary)] transition-colors hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-border-focus)]`}
|
||||
>
|
||||
<Info className={compact ? 'h-3.5 w-3.5' : 'h-4 w-4'} aria-hidden="true" strokeWidth={2.2} />
|
||||
</button>
|
||||
<span
|
||||
id={tooltipId}
|
||||
role="tooltip"
|
||||
className={`${open ? 'visible opacity-100' : 'invisible opacity-0'} absolute left-0 top-full z-30 mt-2 w-[min(340px,calc(100vw-3rem))] rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-surface-container-high)] px-3 py-2 text-left text-xs leading-5 text-[var(--color-text-secondary)] shadow-[var(--shadow-dropdown)] transition-opacity group-hover:visible group-hover:opacity-100 group-focus-within:visible group-focus-within:opacity-100`}
|
||||
>
|
||||
{t('settings.terminal.description')}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
function StatusPill({ status, label, compact = false }: { status: TerminalStatus; label: string; compact?: boolean }) {
|
||||
const color =
|
||||
status === 'running'
|
||||
|
||||
40
release-notes/v0.3.1.md
Normal file
40
release-notes/v0.3.1.md
Normal file
@ -0,0 +1,40 @@
|
||||
# Claude Code Haha v0.3.1
|
||||
|
||||
这是一个以**桌面端配置准确性、工作区引用、终端体验和跨平台稳定性**为主的修复版本。
|
||||
|
||||
相比 `v0.3.0`,本次重点不是引入大功能,而是把桌面端在真实项目切换、MCP 作用域、便携配置、Windows 路径和终端面板里的细节打磨稳定。
|
||||
|
||||
## Highlights
|
||||
|
||||
- **MCP 作用域更准确**:桌面端现在按 CLI 语义区分 local / project / user scope;创建或编辑 local/project MCP 时需要显式选择目标项目,避免写到当前 session worktree 或 server 启动目录。
|
||||
- **MCP 设置页更可信**:设置页会从活动项目、最近项目和已有 user-private MCP key 聚合配置;project-scoped 条目不会因为目标项目不同而消失,初次加载时也不会闪一下空列表。
|
||||
- **工作区文件引用更顺手**:普通 dotfile / dotfolder 会在文件树中显示,文件和目录都可以从工作区菜单添加到聊天;常用复制路径改为项目相对路径,绝对路径保留为显式次级操作。
|
||||
- **便携模式和插件 Skills 更稳定**:桌面 CLI wrapper 会携带选定的 `CLAUDE_CONFIG_DIR`,插件或 Skill 安装后可通过 reload 刷新出来,不需要重启桌面端。
|
||||
- **终端面板体验更稳**:隐藏 docked terminal 或提升为 tab 时不会误杀正在输入的 shell;终端页去掉重复 chrome,保留更多可用空间,并改善未聚焦时的滚动交互。
|
||||
- **Windows drive root 支持更可靠**:`C:` / `D:` 这类 drive-root 输入会被规范化,避免 session、workspace、文件访问或侧边栏隐藏项目逻辑把 drive root 和子项目混淆。
|
||||
|
||||
## Fixes
|
||||
|
||||
- 修复 interleaved `tool_use ... text ... tool_use` 历史在 Bedrock 等严格 provider 下可能触发 400 的问题。
|
||||
- 修复桌面端 sleep / wake 或重连后把已完成 assistant 回复重复追加的问题。
|
||||
- 修复 Windows WebView2 下聊天内容因 1px 级高度震荡出现上下抖动的问题。
|
||||
- 修复模型选择器在未登录 OAuth 时仍显示 Claude Official / ChatGPT Official 分组的问题,并修复上弹菜单与触发按钮之间的定位空隙。
|
||||
- 修复 bypass 权限确认弹窗显示旧项目路径的问题;路径现在跟随当前活跃 tab。
|
||||
- 修复 IM 适配器在桌面会话被删除后复用 stale session binding 的问题。
|
||||
- 修复 shared directory picker 在窗口右侧触发时菜单溢出 viewport 的问题。
|
||||
- 修复 H5 access 测试会被环境变量 `CLAUDE_H5_AUTO_PUBLIC_URL` 污染的问题。
|
||||
- 回滚 `v0.3.0` 后引入的会话父子树侧边栏展示;响应中途不开放分支切换仍是当前预期行为。
|
||||
|
||||
## Notes
|
||||
|
||||
- GitHub Release 正文继续以 `release-notes/v0.3.1.md` 作为来源。
|
||||
- 本版本包含 MCP local/project/user 配置路径、便携配置目录、终端 runtime 生命周期和 Windows drive-root 处理变化;发布前建议重点跑一次桌面端 MCP 设置、工作区文件引用、终端 dock/tab 切换和 Windows 路径 smoke。
|
||||
- 打包发布仍由 tag 触发 GitHub Actions;本地可先用 `bun run scripts/release.ts 0.3.1 --dry` 检查版本和 release note 对齐。
|
||||
|
||||
## macOS
|
||||
|
||||
首次打开如果提示"已损坏"或"无法验证开发者",请执行:
|
||||
|
||||
```bash
|
||||
xattr -cr /Applications/Claude\ Code\ Haha.app
|
||||
```
|
||||
Loading…
x
Reference in New Issue
Block a user