Releases: topcheer/ggcode
Releases · topcheer/ggcode
v1.3.60
v1.3.60
CI 修复与 IM 互斥逻辑。
CI 修复
macOS DMG 构建修复
- 修复
.app在 notarize staple 之前被删除导致 DMG 构建失败的问题 - 清理步骤移至所有 DMG 操作完成后
Windows 构建修复
- 移除动态 go-winres 调用(PowerShell 7 语法在 PS 5.1 runner 上不兼容)
.syso资源文件改为直接提交到仓库
Release workflow 磁盘空间优化
- 所有桌面构建 job 添加
Free disk space步骤 - 关闭构建 job 的 Go module 缓存
- Linux 构建脚本编译后清理 Go cache
Desktop
Windows 图标和应用名
- 嵌入
.syso资源文件,任务栏/资源管理器正确显示 GGCode 图标 - Fyne app ID 改为
gg.ai.ggcode-desktop - WiX 安装器快捷方式添加图标引用
IM 互斥逻辑
- Desktop 启动时调用
RegisterInstance()注册实例 - 检测到 TUI 或其他实例运行时自动静音 IM adapters
- 退出时调用
Unregister()清理注册 - 与 TUI 行为完全一致
v1.3.59
v1.3.59
Desktop UI 修复与 CI 稳定性改进。
Desktop
Windows 图标和应用名
- 嵌入
.syso资源文件到 Windows.exe,任务栏/资源管理器/快捷方式现在正确显示 GGCode 图标 - exe 元数据包含 ProductName、FileDescription、CompanyName
- Fyne app ID 从
com.ggcode.desktop改为gg.ai.ggcode-desktop,Windows 任务管理器正确显示 "GGCode Desktop" - WiX 安装器的桌面/开始菜单快捷方式添加了图标引用
状态栏(v1.3.58 延续)
- 底部紧凑状态栏:vendor/model 徽章 + context 用量 + in/out/cache token 指标
- 移除了侧边栏的 Session Usage 卡片
Session 切换(v1.3.58 延续)
- 切换历史 session 时显示 "Loading session..." 动画指示器
- 防抖机制避免重复点击
Tool Call 图标着色(v1.3.58 延续)
- 进行中:黄色 | 成功:绿色 ✓ | 失败:红色 ✗
消息卡片紧凑化(v1.3.58 延续)
- Badge/Tag 缩小,卡片间距优化
- Markdown 渲染行间距大幅减小
CI
Release workflow 磁盘空间优化
- 所有桌面构建 job 添加
Free disk space步骤(删除 dotnet/Android/ghcActions,释放 ~5GB) - 关闭构建 job 的 Go module 缓存(
cache: false),减少 ~1GB 开销 - macOS 构建脚本:lipo 后删除单架构二进制、DMG 打包后清理 staging、
go clean -cache - Linux 构建脚本:编译后
go clean -cache
v1.3.58
v1.3.58
Desktop UI 改进版本。
Desktop
Session 切换 Loading 效果
- 切换历史 session 时立即清空聊天区域,显示 "Loading session..." 带动画省略号指示器
- 耗时操作移至后台 goroutine,UI 保持响应
- 添加
sessionLoading防抖,防止切换中重复点击
状态栏重设计
- 移除 侧边栏中的 Session Usage 卡片
- 新增 底部紧凑状态栏,一行展示所有关键指标:
- 左侧:
vendor/model蓝色徽章 →ctx上下文用量 →in输入 token →out输出 token →cache缓存命中率 - 右侧:状态文字(如 "ready")
- 左侧:
- 8-10px 等宽字体 + 颜色编码(蓝色/绿色/灰色)
Tool Call 图标着色
- 进行中:黄色录制圆点(
WarningThemedResource) - 成功:绿色 ✓ 对勾(
SuccessThemedResource) - 失败:红色 ✗ 叉号(
ErrorThemedResource) - 之前所有状态均为白色图标,深色背景下难以区分
消息卡片紧凑化
- Badge 图标 16→12px,尺寸 30→22px
- Tag 字号 CaptionText(~11) → 9px
- 卡片间间距从默认 8px → 4px
- 卡片内容区 padding 优化
Markdown 渲染行间距优化
- MarkdownWidget 主容器 VBox 间距从默认 8px → 1px
- 段落/标题 block 用
compactRichText()负 padding 抵消 Fyne InnerPadding - 表格 cell padding 从 8px → 2px 上下 + 4px 左右
- 代码块/引用块/列表块内部间距统一缩小
v1.3.57
ggcode v1.3.57
Highlights
- MCP stdio subprocess lifecycle fix: MCP stdio server subprocesses (e.g. Pencil) are no longer killed when the connection timeout context expires. The subprocess now runs under an independent lifecycle context, fixing the "broken pipe" errors that caused all stdio MCP servers to die shortly after startup.
- ACP client v2 with streaming events: Major rewrite of the ACP client (
internal/acp/client.go) with idle timeouts, stderr capture, activity tracking, and real-time prompt events (text, tool calls, tool results) flowing through the delegate/subagent pipeline. - Sub-agent tool display enrichment: Tool calls from sub-agents and delegate agents now carry
DisplayNameandDetailmetadata through the full pipeline (subagent manager → tunnel broker → mobile TUI), replacing the raw tool-name-only display with rich inline labels.
Fixes and improvements
- MCP client deadlock fix: Resolved a deadlock in
Client.Abort()wheresync.Oncecould block while holding a mutex thatreadResponseWithCancelalso needed. - ACP delegate streaming: The
delegatetool now emits real-timeACPPromptEventcallbacks (text, tool_call, tool_result) that flow throughsubagent.Manager→ TUI follow strip → tunnel broker, giving live visibility into what delegate agents are doing. - Sub-agent callback signatures:
SetOnToolCallandSetOnToolResultcallbacks now includedisplayNameanddetailparameters, propagated consistently through TUI, desktop, and tunnel paths. - Tunnel broker tool metadata:
subagentToolArgsmap upgraded tosubagentToolMetastruct carryingRawArgs,DisplayName, andDetail, enabling mobile clients to render rich tool labels. - Tool label external wrapper: New
DescribeExternalToolCallfunction normalizes ACP/external tool call titles while preserving meaningful CLI-provided names and deduplicating generic ones. - TUI program.Send safety: Sub-agent callbacks now go through a centralized
sendProgramMsgshelper instead of scatteredr.program.Send()calls, reducing nil-pointer risk. - Desktop agent bridge: Updated to use enriched tool metadata from sub-agent callbacks for tunnel forwarding to mobile.
- ACP E2E test coverage:
acp_e2e_test.goexpanded from ~50 to 800+ lines covering prompt lifecycle, streaming events, idle timeouts, error recovery, and concurrent sessions. - Go version: Bumped from 1.26.1 to 1.26.2.
- Dependency: Added
github.com/topcheer/ggcode-acp-go v0.1.5(ACP protocol library).
Changed files (53)
go.mod,go.sum— Go 1.26.2, ggcode-acp-go v0.1.5internal/mcp/client.go— subprocess lifecycle fix (independent context), deadlock fixinternal/acp/client.go— full rewrite with streaming, idle timeout, stderr captureinternal/acp/— adapter, types, transport, tests all updatedinternal/subagent/— enriched tool metadata in callbacks and eventsinternal/tool/delegate.go— ACP prompt event streaming integrationinternal/tool/labels.go— external tool call label normalizationinternal/tui/— repl callbacks, subagent follow, tool labels, tunnel streaminternal/tunnel/broker.go— subagent tool metadata propagationdesktop/ggcode-desktop/— agent bridge callback signature updatesmobile/flutter/— protocol and chat provider for enriched tool display
Upgrade notes
- No breaking configuration changes.
- MCP stdio servers should now remain stable across long-running sessions.
- Sub-agent tool display in mobile/TUI will show richer labels automatically.
Compare
v1.3.56
ggcode v1.3.56
Highlights
- ACP MCP Server passthrough: ggcode MCP server configurations are now forwarded to ACP delegate agents via
NewSessionRequest.mcpServers, enabling delegate agents to use the same MCP tools available to the host. - ACP permission policy integration: ACP agent file operations (
fs/read_text_file,fs/write_text_file) are now gated by ggcode's permission policy with path validation. ACPrequest_permissionrequests bridge to ggcode's approval UX — auto-allow in daemon mode, auto-deny in pipe mode, interactive approval in TUI mode. - TUI cancel state fix:
cancelActiveRun()now keepsloading=truewith a "cancelling" spinner untilagentDonearrives, preventing the UI from briefly showing an editable input during the cancellation unwind. Hidden pending submissions are no longer incorrectly restored to the input field.
Fixes and improvements
- ACP discovery security:
findBinarynow rejects workspace-local paths (binaries in the current working directory subtree) and resolves symlinks before path validation, preventing accidental discovery of project-local scripts as ACP agents. - ACP session lifecycle: New
EnsureReady()method provides lazy start + session with automatic rebuild when the working directory changes.session/prompt_completenotification replaces the goroutine return channel for more reliable prompt completion tracking. - ACP entry point unification:
root.go,daemon.go, andpipe.goall initializeClientManagerwith the permission policy and MCP configs.DelegateToolusesWorkingDirFnfor dynamic working directory resolution. - DelegateTool working dir: The
delegatetool now propagates the current working directory to the ACP manager before each execution, ensuring delegate agents always see the correct project root.
New files
internal/acp/mcp_passthrough.go— MCP server config conversion from ggcode format to ACP formatinternal/acp/client_permission_test.go— tests for permission policy integration and approval flow
Compare
v1.3.55
ggcode v1.3.55
Highlights
- Daemon tunnel share controller: New
daemonTunnelShareControllerincmd/ggcode/daemon.gocentralizes all tunnel event routing — stream events, run state transitions, inbound user messages, and snapshot generation — replacing inline lambda wiring with a well-structured, testable controller with full round-tracking and stable message IDs. - Reaction-based typing acknowledgements: IM adapters (Discord, Slack, Matrix, Telegram, Feishu, Mattermost) now add a reaction-style acknowledgement (emoji) on the latest user message instead of only triggering a native typing indicator. A deduplication layer (
reactionAckState) prevents duplicate reactions within the same channel/thread context. Falls back gracefully when no target message is available. - Relay graceful shutdown: The relay server now sends
server_offlinenotices with arelay_restartingreason to all connected clients before closing WebSocket connections withCloseServiceRestart(1012), enabling mobile clients to reconnect faster (15s default instead of 60s). - Unicode-correct message splitting:
SplitMessageand all per-adapter split helpers now count runes instead of bytes, preventing mid-character splits on CJK and emoji content.
Fixes and improvements
- Provider token usage:
TokenUsage.DisplayInputTokens()subtracts cache-read tokens whenPromptTokensTotalis available, showing the normalized input count;Total()usesTotalInputTokens()for accurate totals. - DaemonBridge hooks: New
SetRunStateHookandSetUserMessageHookallow tunnel and other subsystems to observe run state changes and user message submissions without coupling to the bridge internals. - DaemonBridge interrupt:
InterruptActiveRun()exposes a safe way to cancel the active agent run from outside the bridge (used by tunnel inbound commands). - Flutter relay restart recovery:
ConnectionServicedetects relay restart close codes/reasons and uses a shorter 15-second reconnect delay instead of the 60-second server-offline wait. - Flutter
server_offlinereason label: Shows "Relay restarting" vs "Relay recovering" in the error message based on the reason field. - TUI sidebar: Minor cleanup in
view_sidebar.go. - Desktop tests:
safe_ui.goandui_test.goadapted for updated APIs. - IM adapters unified: All adapters with custom message split helpers now delegate to
splitMessageRunes()for consistent behavior.
New files
cmd/ggcode/daemon_tunnel_test.go— unit tests fordaemonTunnelShareController(event routing, user message forwarding, history conversion)internal/im/reaction_ack.go— reaction acknowledgement state tracking and platform-specific emoji selection
Compare
v1.3.54
ggcode v1.3.54
Highlights
- Projection authority epoch: Desktop tunnel projection now tracks an authority epoch per session, preventing stale relay history from being trusted after a desktop restart or session switch. Broker validates relay history epoch before accepting it.
- Projection store fallback: When the projection SQLite store fails to init or write, the desktop falls back to recording events through the main tunnel ledger, preventing silent data loss.
- QR code terminal rendering: New compact terminal QR code renderer for workspace sharing with reduced quiet zone modules.
Fixes and improvements
- Tunnel broker:
AuthorityEpoch()/SetAuthorityEpoch()APIs for relay history validation;trustRelayHistorynow checks epoch match and canonical replay availability instead of just history count - Desktop:
AgentBridgetrackstunnelProjectionBrokenstate and falls back to main ledger when projection store fails;hydrateProjectionReplayFromSessionLedgerseeds projection from main session ledger on first bind - TUI: Tunnel lifecycle refactored to use
tunnelMainStreamActive/resetTunnelMainStreamhelpers instead of direct field manipulation; relay room seeding moved before QR overlay display - Flutter:
bindRemoteUserMessagesupportslocalMessageIdfor precise message matching;finalizeStreamingMessagesForSourceensures clean stream termination; newworkspace_cacheandconnection_providerimprovements - Protocol:
active_sessionandserver_readyevents now carryauthority_epochfield - CI: Auto-update Homebrew Formula and desktop Cask on release via GitHub Actions
- Docs: Install instructions updated across all channels
New files
internal/tui/qrcode_terminal.go— compact terminal QR code rendererinternal/tunnel/projection_hash.go— SHA-256 event hash for projection deduplication
Upgrade notes
- Desktop and mobile must both be updated for the authority epoch handshake; older mobile clients will ignore the epoch field and fall back to existing behavior
- Projection store now records
authority_epoch; existing stores will start at epoch 1
Compare
- Full diff: v1.3.53...v1.3.54
v1.3.53
ggcode v1.3.53
Highlights
- Relay readiness gate: Mobile clients now wait for the desktop host to signal
server_readybefore proceeding with relay sync, preventing premature state reads from an uninitialized relay room. - Smarter relay recovery: The broker uses a
relayRecoveryPlanto decide whether to trust relay history, do a partial suffix replay, or reset and reseed — instead of the previous binary trust/reject logic. - Relay room hydration: Server rooms are hydrated from SQLite before the first server attaches, so mobile clients can see the server is already present with state rather than getting "room empty" errors.
- Mobile connect progress UI: Connect screen shows phase-aware progress (restoring local, waiting for host, replaying, stalled) with i18n strings in English and Chinese.
Fixes and improvements
- Relay:
active_sessionsupportsresume_mode=replace_historyto clear stale relay history;server_readyevent marks room as ready for clients;resume_fromlets clients request targeted replay from a specific cursor - Broker:
AnnounceActiveSessionandSwitchSessionboth emitserver_ready; recovery plan computes suffix replay offset instead of always replaying from scratch - Flutter: New
RelaySyncPhaseenum (restoringLocal, waitingHost, waiting, replaying, snapshot); connect screen shows phase-specific titles and detail text;sessionReadyflag gates UI - Tests: 209 new broker tests, 135 new relay tests, 156 new Flutter tests covering recovery plans, readiness gating, and connect progress
Upgrade notes
- Desktop and relay must both be updated for the readiness gate to work; older desktops won't send
server_readyand mobile clients will see "waiting for host" - Relay rooms are now hydrated from SQLite on server attach, which may increase memory usage for deployments with many persisted rooms
Compare
- Full diff: v1.3.52...v1.3.53
v1.3.52
ggcode v1.3.52
Highlights
- Tunnel share invite refresh:
/shareon an active tunnel now refreshes the QR code and auth tickets instead of showing the stale invite. A new/share/session/refreshrelay endpoint issues fresh client auth and server renew tokens without disconnecting. - Replay event ordering: Tunnel replay events are now sorted by event ID before delivery, preventing out-of-order rendering on mobile reconnect.
- Mobile workspace cache refactoring: Session index changed from
workspaceKey::sessionIdto puresessionId, enabling cross-workspace session reuse. Snapshots are coalesced to preserve richer data. Sparse reconnect snapshots are detected and handled safely.
Fixes and improvements
- Relay: Added
/share/session/refreshendpoint for share session renewal with renew token verification - Tunnel session:
Info()returns a clone to prevent external mutation; newRefreshInvite()method - Tunnel share protocol: Extracted
shareEndpointhelper; addedrefreshIssuedShareSessionandpublicShareDescriptorFromServer - TUI:
/sharecommand on active tunnel triggers async refresh with new QR overlay - Mobile: Session-first cache lookup, snapshot merge logic, non-authoritative projection protection, sparse snapshot identity reset
- iOS Fastfile: Changelog unified to "Bug fixes and stability improvements."; auto-set What's New for App Store
Upgrade notes
- Mobile clients should update to this version for correct session restore behavior after tunnel reconnect
- Relay servers should be updated to support the new
/share/session/refreshendpoint
Compare
- Full diff: v1.3.51...v1.3.52
v1.3.51
ggcode v1.3.51
Highlights
- Fix mobile infinite spinner after QR scan — the
resume_hellomessage was sent before the WebSocket connection was established, causing mobile to never receive relay events after scanning a QR code.
Fixes and improvements
- Mobile: fix
resume_hellosend timing — IntroducedarmResumeHello()+_flushPendingResumeHello()pattern soresume_hellois only sent after the relay'sconnectedmessage is processed, not beforeWebSocket.connect()completes. - Mobile: fix
sendResumeHelloduplicate protection — Added_resumeHelloSentflag to prevent re-sending on reconnect without_resetHandshakeState(). - Mobile: fix
connect()duplicate connection guard — Re-scanning the same QR code while connecting no longer creates a secondConnectionService. - Mobile: fix v3 URL
cryptoMaterialcheck — Share v3 URLs without a publiccrypto_keyno longer fail the early validation. - Mobile: defensive
connectedmetadata parsing — Non-string fields in relay'sconnectedJSON (e.g.room_id: 123) are tolerated instead of crashing. - Mobile: fix AppShell bootstrap auto-restore — Workspace selection changes after startup no longer trigger spurious
restoreSelectedWorkspace()calls. - Mobile: add debug logging throughout connection lifecycle —
connect,connected,resume_hello,resume_ack,relaySynctransitions now emitdebugPrintfor diagnostics. - Desktop/TUI: rename
destroy_room→stop_sharing— Control message name aligned with relay's handler for clarity. - Desktop/TUI: use
DestroyGracefullyinstead ofStopGracefullyfor legacy share sessions.
Upgrade notes
- Relay should be updated first (already deployed).
- Desktop and mobile can upgrade independently — full backward compatibility with v1.3.50 relay.
Compare
- Full diff: v1.3.50...v1.3.51