Skip to content

Releases: topcheer/ggcode

v1.3.60

03 Jun 07:15

Choose a tag to compare

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

03 Jun 06:51

Choose a tag to compare

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

03 Jun 04:39

Choose a tag to compare

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

02 Jun 16:19

Choose a tag to compare

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 DisplayName and Detail metadata 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() where sync.Once could block while holding a mutex that readResponseWithCancel also needed.
  • ACP delegate streaming: The delegate tool now emits real-time ACPPromptEvent callbacks (text, tool_call, tool_result) that flow through subagent.Manager → TUI follow strip → tunnel broker, giving live visibility into what delegate agents are doing.
  • Sub-agent callback signatures: SetOnToolCall and SetOnToolResult callbacks now include displayName and detail parameters, propagated consistently through TUI, desktop, and tunnel paths.
  • Tunnel broker tool metadata: subagentToolArgs map upgraded to subagentToolMeta struct carrying RawArgs, DisplayName, and Detail, enabling mobile clients to render rich tool labels.
  • Tool label external wrapper: New DescribeExternalToolCall function 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 sendProgramMsgs helper instead of scattered r.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.go expanded 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.5
  • internal/mcp/client.go — subprocess lifecycle fix (independent context), deadlock fix
  • internal/acp/client.go — full rewrite with streaming, idle timeout, stderr capture
  • internal/acp/ — adapter, types, transport, tests all updated
  • internal/subagent/ — enriched tool metadata in callbacks and events
  • internal/tool/delegate.go — ACP prompt event streaming integration
  • internal/tool/labels.go — external tool call label normalization
  • internal/tui/ — repl callbacks, subagent follow, tool labels, tunnel stream
  • internal/tunnel/broker.go — subagent tool metadata propagation
  • desktop/ggcode-desktop/ — agent bridge callback signature updates
  • mobile/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...v1.3.57

v1.3.56

01 Jun 04:10

Choose a tag to compare

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. ACP request_permission requests 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 keeps loading=true with a "cancelling" spinner until agentDone arrives, 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: findBinary now 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_complete notification replaces the goroutine return channel for more reliable prompt completion tracking.
  • ACP entry point unification: root.go, daemon.go, and pipe.go all initialize ClientManager with the permission policy and MCP configs. DelegateTool uses WorkingDirFn for dynamic working directory resolution.
  • DelegateTool working dir: The delegate tool 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 format
  • internal/acp/client_permission_test.go — tests for permission policy integration and approval flow

Compare

v1.3.55...v1.3.56

v1.3.55

31 May 17:11

Choose a tag to compare

ggcode v1.3.55

Highlights

  • Daemon tunnel share controller: New daemonTunnelShareController in cmd/ggcode/daemon.go centralizes 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_offline notices with a relay_restarting reason to all connected clients before closing WebSocket connections with CloseServiceRestart (1012), enabling mobile clients to reconnect faster (15s default instead of 60s).
  • Unicode-correct message splitting: SplitMessage and 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 when PromptTokensTotal is available, showing the normalized input count; Total() uses TotalInputTokens() for accurate totals.
  • DaemonBridge hooks: New SetRunStateHook and SetUserMessageHook allow 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: ConnectionService detects relay restart close codes/reasons and uses a shorter 15-second reconnect delay instead of the 60-second server-offline wait.
  • Flutter server_offline reason 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.go and ui_test.go adapted 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 for daemonTunnelShareController (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...v1.3.55

v1.3.54

31 May 14:08

Choose a tag to compare

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; trustRelayHistory now checks epoch match and canonical replay availability instead of just history count
  • Desktop: AgentBridge tracks tunnelProjectionBroken state and falls back to main ledger when projection store fails; hydrateProjectionReplayFromSessionLedger seeds projection from main session ledger on first bind
  • TUI: Tunnel lifecycle refactored to use tunnelMainStreamActive / resetTunnelMainStream helpers instead of direct field manipulation; relay room seeding moved before QR overlay display
  • Flutter: bindRemoteUserMessage supports localMessageId for precise message matching; finalizeStreamingMessagesForSource ensures clean stream termination; new workspace_cache and connection_provider improvements
  • Protocol: active_session and server_ready events now carry authority_epoch field
  • 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 renderer
  • internal/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

v1.3.53

31 May 06:47

Choose a tag to compare

ggcode v1.3.53

Highlights

  • Relay readiness gate: Mobile clients now wait for the desktop host to signal server_ready before proceeding with relay sync, preventing premature state reads from an uninitialized relay room.
  • Smarter relay recovery: The broker uses a relayRecoveryPlan to 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_session supports resume_mode=replace_history to clear stale relay history; server_ready event marks room as ready for clients; resume_from lets clients request targeted replay from a specific cursor
  • Broker: AnnounceActiveSession and SwitchSession both emit server_ready; recovery plan computes suffix replay offset instead of always replaying from scratch
  • Flutter: New RelaySyncPhase enum (restoringLocal, waitingHost, waiting, replaying, snapshot); connect screen shows phase-specific titles and detail text; sessionReady flag 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_ready and 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

v1.3.52

30 May 16:37

Choose a tag to compare

ggcode v1.3.52

Highlights

  • Tunnel share invite refresh: /share on an active tunnel now refreshes the QR code and auth tickets instead of showing the stale invite. A new /share/session/refresh relay 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::sessionId to pure sessionId, 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/refresh endpoint for share session renewal with renew token verification
  • Tunnel session: Info() returns a clone to prevent external mutation; new RefreshInvite() method
  • Tunnel share protocol: Extracted shareEndpoint helper; added refreshIssuedShareSession and publicShareDescriptorFromServer
  • TUI: /share command 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/refresh endpoint

Compare

v1.3.51

30 May 05:30

Choose a tag to compare

ggcode v1.3.51

Highlights

  • Fix mobile infinite spinner after QR scan — the resume_hello message 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_hello send timing — Introduced armResumeHello() + _flushPendingResumeHello() pattern so resume_hello is only sent after the relay's connected message is processed, not before WebSocket.connect() completes.
  • Mobile: fix sendResumeHello duplicate protection — Added _resumeHelloSent flag 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 second ConnectionService.
  • Mobile: fix v3 URL cryptoMaterial check — Share v3 URLs without a public crypto_key no longer fail the early validation.
  • Mobile: defensive connected metadata parsing — Non-string fields in relay's connected JSON (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 lifecycleconnect, connected, resume_hello, resume_ack, relaySync transitions now emit debugPrint for diagnostics.
  • Desktop/TUI: rename destroy_roomstop_sharing — Control message name aligned with relay's handler for clarity.
  • Desktop/TUI: use DestroyGracefully instead of StopGracefully for 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