Skip to content

Releases: topcheer/ggcode

v1.3.163

Choose a tag to compare

@topcheer topcheer released this 17 Jul 17:59

ggcode v1.3.163

Highlights

Strategist context enrichment

  • The autopilot strategist now receives tool call summaries in its conversation context. Previously, all tool_use and tool_result blocks were stripped, leaving only text — the strategist could see the assistant's claims ("tests pass now") but had no evidence (test output, file contents, command results) to verify them.
  • Tool calls are summarized as [Tool Call: read_file(path=/foo.go)] and results as [Tool Result OK: PASS\nok ...] or [Tool Result ERROR: ...], capped at 500 runes per result for token efficiency.

GOAL_COMPLETE instruction cleanup

  • Removed all GOAL_COMPLETE instructions from every LLM-facing prompt (system prompt in agentruntime/prompt.go and goal-collection instruction in agent_autopilot.go). The LLM was previously told to output GOAL_COMPLETE when done, but the main agent loop no longer checks for it — goal completion is determined exclusively by the strategist via GOAL_ACHIEVED.

Goal achievement notification

  • When the strategist determines the goal is achieved, a system event is now emitted: [Strategist: goal achieved — autopilot complete. <summary>]. Previously the agent would silently return with no indication to the user why it stopped.

Upgrade notes

No breaking changes. No config migration needed.

Compare

v1.3.162...v1.3.163

v1.3.162

Choose a tag to compare

@topcheer topcheer released this 17 Jul 17:37

ggcode v1.3.162

Highlights

Autopilot goal declaration and strategist connection

  • The autopilot goal was never set in production code — SetAutopilotGoal() was only called from tests. This meant the strategist cruise logic and GOAL_COMPLETE detection were dead code (hasAutopilotGoal() always returned false).
  • The LLM is now instructed to declare its goal using a GOAL: <description> sentinel line at the start of its first response. The runtime parses this line to set autopilotGoal, which activates the strategist and goal-completion machinery.
  • Goal completion is now solely determined by the strategist (which analyzes the full conversation context before deciding), not by the LLM self-declaring GOAL_COMPLETE. The old isAutopilotGoalComplete check is removed — it could fire on the first text-only response before any real work was done.

Autopilot strategist safety

  • Added maxAutopilotStrategistCalls = 10 cap to prevent infinite cruise loops when the strategist keeps returning guidance but the LLM keeps producing text-only responses.
  • Fixed byte-level truncation in extractStrategistContext that split multi-byte UTF-8 characters (CJK text). Replaced with rune-safe truncation.

Fixes and improvements

  • Global memory files restoredProjectMemoryFilesForPath now includes ~/.ggcode/GGCODE.md and other global memory files again. The lazy-loading refactor had accidentally dropped them, causing global conventions to silently disappear from the agent's awareness.
  • Full paths for global memory hintBuildProjectMemoryHint now shows full absolute paths for files outside the working directory (e.g. /Users/name/.ggcode/GGCODE.md), while local files still show only the base name. Without the full path the agent cannot locate global files via read_file.

Upgrade notes

No breaking changes. No config migration needed.

Compare

v1.3.161...v1.3.162

v1.3.161

Choose a tag to compare

@topcheer topcheer released this 17 Jul 15:15

ggcode v1.3.161

Highlights

Project Memory lazy loading

  • Project Memory files (GGCODE.md, AGENTS.md, CLAUDE.md, etc.) are no longer loaded into the system prompt in full. Instead, only file names are injected as an index hint — the LLM loads full content via read_file when relevant to the current task.
  • This keeps the system prompt small regardless of how large memory files grow, saving thousands of tokens per request on projects with extensive conventions.
  • Unified all 5 injection paths (interactive TUI, pipe mode, ACP, desktop, TUI model update) to use the same BuildProjectMemoryHint helper.
  • Startup assets optimized: replaced LoadAll with LoadIndex — only reads file paths, not contents — eliminating unnecessary I/O during launch.

Tool description optimization (~6 KB system prompt reduction)

  • Systematically reviewed and trimmed all 90+ tool descriptions in internal/tool/.
  • Removed information duplicated in Parameters JSON schema (action enums, field descriptions, format details) and the system prompt (mode definitions, collaboration routing, plan mode tool lists).
  • Compressed verbose phrasing while preserving all behavioral constraints, safety warnings, and tool selection guidance.
  • Biggest savings: lanchat_tool (1.3 KB), config_tool (800 B), im_tool (800 B), switch_mode (600 B), all 10 LSP tools (300 B from removing redundant "using a locally installed LSP server").

I/O parallelization for multi-file tools

  • multi_file_read and multi_file_edit now read files concurrently (semaphore-limited to 5) instead of sequentially, significantly reducing latency for large batches.

Fixes and improvements

  • OpenRouter attribution headers — requests to openrouter.ai endpoints now include HTTP-Referer, X-Title, and X-OpenRouter-Categories headers for proper attribution and app ranking.
  • Test coverage — added unit tests for BuildProjectMemoryHint (empty/single/multiple/dedup) and isOpenRouterEndpoint (host matching, lookalike domain rejection).

Upgrade notes

No breaking changes. No config migration needed.

Compare

v1.3.160...v1.3.161

v1.3.160

Choose a tag to compare

@topcheer topcheer released this 17 Jul 13:00

ggcode v1.3.160

Highlights

Named Subagent tool experience

  • Human-readable labels for all named subagent tools (create_namedagent, use_namedagent, list_namedagent, delete_namedagent) in both TUI and daemon/desktop surfaces, with full i18n support (en/zh-CN).
  • Structured result rendering — daemon, IM, and desktop now show concise summaries (e.g. "Created agent reviewer", "Started agent architect") instead of raw multi-line text dumps.
  • Verbose body suppression in TUI chat — the header label carries the key info, so the multi-line result body is hidden to reduce visual noise.
  • Fixed created/updated detectioncreate_namedagent now correctly reports "created" vs "updated" by checking template existence before saving, replacing the fragile time-based heuristic.
  • Preserved CreatedAt on updatesTemplateStore.Save now loads the existing template's CreatedAt before overwriting.

Multi-file tool TUI rendering

  • multi_file_read, multi_file_write, and multi_file_edit upgraded from generic text dump to structured catFile rendering with line counts and diff stats (+N -M).
  • DescribeToolResult entries added for all three tools, providing structured summaries ("Read 3/3 files", "Wrote 2/2 files") to daemon/IM/desktop.

Fixes and improvements

  • UTF-8 safe truncation — replaced all 93 byte-level s[:N] truncations with rune-safe string([]rune(s)[:N]) across 37 files. Previous code split multi-byte UTF-8 characters (Chinese, emoji) causing mojibake in terminal display.
  • Fixed panic in summarizeDescriptionskills_panel.go mixed byte offsets (from LastIndexByte) with rune slice indices, causing a slice-bounds panic on any skill description >80 runes containing multi-byte characters.
  • Fixed use_named_agent slice aliasingallowedTools[:0] corrupted the template's backing array; replaced with make([]string, 0, len(allowedTools)).
  • Budget guard advice fix — efficiency guidance now encourages optimization rather than premature stopping.
  • Removed orphaned npm tab from website.
  • Removed dead JSON fields with wrong tags in describeMultiFileEditResult.

Upgrade notes

No breaking changes. No config migration needed.

Compare

v1.3.159...v1.3.160

v1.3.159

Choose a tag to compare

@topcheer topcheer released this 17 Jul 06:53

ggcode v1.3.159

Highlights

npm and PyPI wrappers deprecated

  • Removed npm and PyPI publish workflows from GitHub Actions — no more automatic wrapper publishing on new releases.
  • Marked both wrapper packages as deprecated in their READMEs and package metadata.
  • Cleaned all project documentation — removed npm/pip install methods from the website, install guide, architecture docs, and release process checklist.

Fixes and improvements

  • npm package.json restored: Fixed accidental scoped name loss (@ggcode-cli/ggcode) from a previous overwrite.

Upgrade notes

  • No breaking changes to the ggcode CLI or desktop app
  • If you previously installed ggcode via npm or pip, switch to Homebrew (brew install topcheer/ggcode/ggcode), winget (winget install gg.ai.ggcode-cli), or download native packages from GitHub Releases

Compare

Full changelog

v1.3.158

Choose a tag to compare

@topcheer topcheer released this 17 Jul 06:01

ggcode v1.3.158

Highlights

npm trusted publishing fix

  • Removed --provenance=false from npm publish workflow, which was disabling OIDC-based trusted publishing. npm tightened 2FA token restrictions on 2025-07-17, breaking the old workflow. Trusted publishing via id-token: write permissions bypasses 2FA requirements.

Provider error messages improved

  • finish_reason/stop_reason translation: Stream termination errors from all three providers (OpenAI finish_reason=length/content_filter/network_error, Anthropic stop_reason=max_tokens/refusal, Gemini FinishReason=MAX_TOKENS/SAFETY) now produce bilingual user-friendly messages with actionable hints (increase max_tokens, /compact, /retry).

Fixes and improvements

Reverted

  • write_file overwrite protection (from v1.3.157 cycle): Removed — LLM already checks file existence via read_file before deciding write_file vs edit_file. The protection was redundant and created a dead-end loop.

Upgrade notes

  • No breaking changes
  • No config migration required

Compare

Full changelog

v1.3.157

Choose a tag to compare

@topcheer topcheer released this 17 Jul 04:41

ggcode v1.3.157

Highlights

Concurrency safety hardening

  • Broker data race fixed: onCommand/onConnect callback fields were read in Session goroutines without locks while being written by setters. Added callbackMu (RWMutex) with copy-then-call pattern.
  • Nested lock order eliminated: enqueueWithBytes/enqueueSnapshotEvent held outMu while calling SessionID()/AuthorityEpoch() which internally acquire sessionMu.RLock(). Moved reads before lock acquisition to remove the implicit outMu → sessionMu dependency.

Data integrity fixes

  • migrateMessageIDs: WriteString/Close errors were silently ignored — disk-full conditions would lose session data without any error. All write paths now check errors and clean up.
  • backfillIDs/backfillTimestamps: Same write-error ignoring pattern fixed with error checking + Sync().
  • 8 session persistence sites: AppendMetaToDisk errors were silently swallowed (_ =) across sidebar preference, model selection, context window probe, binding state, and async usage recording. All now log via debug.Log.

Crash prevention

  • git commit nil panic: When injecting Co-Authored-By trailer, the shell command was rebuilt with cmd, _, _ = NewShellCommandContext(...) — ignoring the error. If rebuild failed, cmd was nil and subsequent cmd.Dir / configureCommandCancellation(cmd) would panic. Now returns a proper error Result.

Fixes and improvements

Performance

  • emitUsage/emitMetric Lock→RLock: High-frequency read-only callbacks used exclusive Lock(), causing unnecessary contention. Switched to RLock().
  • HandleInbound persistBinding merge: Each inbound IM message wrote binding state to disk twice (once for ChannelID, once for LastInboundMessageID). Merged into a single write.
  • CountTokens capability caching: context.WithTimeout was created on every Add() call even for providers (OpenAI/Gemini) that use pure local estimation. After first probe, local-estimation providers skip context creation entirely. Cache is reset on SetProvider.

User experience

  • Bilingual error messages: UserFacingError always returned Chinese text regardless of interface language. New UserFacingErrorLang(err, lang) provides English equivalents for all 12+ error categories (401/403/429/timeout/network/400/etc.). English TUI users no longer see Chinese errors.
  • Model switch feedback: Selecting a model from the panel silently closed it. Now shows a system message confirming the switch.
  • /help completeness: 15+ slash commands were missing from help output (/retry, /edit, /files, /chat, /nick, /tunnel, /rules, /allow, /inspector, /reflect, /impersonate, /stream, /stats, etc.). Both EN and ZH catalogs updated.
  • /retry hint in errors: Transient error messages (429/timeout/network) now suggest "Type /retry to resend".
  • Keyboard shortcut docs corrected: Ctrl+T was documented as "open tunnel" (actually config scope toggle), Ctrl+N/P descriptions were wrong, and Ctrl+G/Ctrl+\/Esc+Esc/Alt+Up-Down were missing. Both EN and ZH help texts corrected.

Reverted

  • Stream UI throttle (from auto-optimization round): Added 50ms time-based throttle to appendStreamChunk to reduce markdown re-renders. Reverted because it broke assistant message rendering — the existing three-layer cache (SetText dedup → streamRenderCache incremental blocks → CachedItem width cache) already handles this efficiently.

Upgrade notes

  • No breaking changes
  • No config migration required
  • All fixes are backward compatible

Compare

Full changelog

v1.3.156

Choose a tag to compare

@topcheer topcheer released this 16 Jul 15:44

ggcode v1.3.156

Highlights

Named subagents

Define and invoke reusable subagent roles with persistent per-workspace templates. The LLM can now create specialized agents (e.g. "code-reviewer", "test-writer") with custom system prompts, tool allowlists/denylists, MCP server bindings, and model overrides — then reuse them across sessions via use_namedagent.

Tools: create_namedagent, use_namedagent, list_namedagent, delete_namedagent.

Templates are stored under ~/.ggcode/subagents/<workspace-hash>/ and automatically injected into the system prompt on startup.

Session persistence — incremental append only

Session Save() was refactored to never rewrite the JSONL file. Messages are now persisted exclusively via incremental appends (AppendMessageToDisk). This eliminates a data-loss path where compaction would replace ses.Messages in memory, and a subsequent Save() call would overwrite pre-compaction history on disk.

Fixes and improvements

Session switch stale references (critical)

Fixed multiple bugs where /clear and /sessions switch left subsystems bound to the old session:

  • persistHandler/checkpointHandler wrote messages to the old session's JSONL file because r.model (a Bubble Tea value-type copy) always returned the initial session. Fixed via thread-safe currentSession pointer on REPL, updated atomically through sessionUpdateCallback.
  • Exit cleanup used stale r.model.session for CleanupIfEmpty and persistFullSessionMessages. Fixed by syncing finalModel after program.Run() returns.
  • RuntimeStatus reported stale permission_mode from the old session snapshot.
  • LAN Chat SetSessionID was only called at startup, not on /clear or /sessions switch. Messages and nick persistence went to the old session's store. Fixed by moving the call into Model.SetSession().
  • Checkpoint/undo was not cleared on session switch — /undo in a new session could revert the old session's file edits. Fixed by calling cpMgr.Clear() in switchToSession.
  • Sub-agent/swarm were not cancelled on /clear — running agents continued in the background and their results were routed to the new session. Fixed by adding a loading guard (consistent with /sessions resume) and CancelAll() for both sub-agents and swarm teammates.

Orphaned IM adapter bindings

When an empty session is deleted during exit cleanup, IM adapter bindings referencing that session's LastSessionID become orphaned — no new ggcode instance would auto-claim them. Fixed by adding ClearSessionBindings / ClearSessionBindingsGlobal to clear LastSessionID for all affected bindings, called from both TUI and desktop exit paths.

Upgrade notes

  • No breaking changes. All fixes are backward-compatible.
  • Session JSONL files from previous versions are fully compatible — the incremental append model is a superset of the old behavior.
  • Named subagent templates are created on-demand; existing workspaces without templates are unaffected.

Compare

Full changelog

v1.3.155

Choose a tag to compare

@topcheer topcheer released this 16 Jul 05:13

v1.3.155

Fixes

Context usage display — baseline collapse & CacheRead semantics

TUI ctx indicator showed absurdly small numbers (e.g. ctx 76/358K instead of ctx 204/358K).

Root cause was three-fold:

  1. RecordUsage ignored CacheRead for Anthropic protocol — Anthropic's SSE events split input tokens into input_tokens (non-cached only) and cache_read_input_tokens (cached portion). RecordUsage only used input_tokens, producing a baseline roughly 3–4× too small. Now detects Anthropic additive semantics via PromptTokensTotal > InputTokens and adds CacheRead. OpenAI/Gemini InputTokens already includes cached tokens (no double-counting).

  2. RecordUsage collapsed on InputTokens=0 — when a provider fallback path didn't fill InputTokens, the old code set baselineTokens = 0 + OutputTokens. Now skips the baseline update entirely when InputTokens <= 0, preserving the previous estimate.

  3. Anthropic message_delta overwrote message_start usage — the message_delta SSE event only carries output_tokens reliably; its input_tokens field is often 0 or partial. The old code unconditionally overwrote the correct values from message_start. Now only updates from message_delta when the value is non-zero and message_start hadn't already set it.

Session restore — all context messages lost on resume

Resuming a session after compaction loaded zero context messages, causing the agent to lose all conversation history.

  • store.go sets CheckpointMessageCount = len(ContextMessages) (the full post-compaction message list).
  • The old restore code in sessions.go did msgs = msgs[CheckpointMessageCount:], producing an empty slice.
  • Fix: removed the obsolete slicing — ContextMessages is already the checkpoint-aware slice built by loadSession().

Anthropic provider fallback — missing InputTokens

When the stream completed without receiving usage events (e.g. retry fallback), the provider only set OutputTokens. Now estimates InputTokens via CountTokens, matching the OpenAI provider's behavior.

v1.3.154

Choose a tag to compare

@topcheer topcheer released this 15 Jul 17:08

v1.3.154

Highlights

  • Fix: vision-enabled models causing 400 errors on non-vision endpoints. When switching from a vision-capable endpoint (e.g. kimi) to a non-vision endpoint (e.g. zai/glm-5.2), the agent incorrectly kept vision mode enabled, sending image data in tool results that the API rejected. Now SetSupportsVision is called on every provider switch, and historical image data in old sessions is automatically stripped before sending.

Fixes and improvements

  • ApplyProviderToAgent now calls SetSupportsVision — the root cause of the 400 error loop. Previously SupportsVision was only set once at startup; switching endpoints/model in TUI never updated it.
  • Image stripping in ensureMessagesSendable — when the active endpoint does not support vision, image data in tool_result content blocks is stripped from the message history before sending to the provider. This repairs old sessions that recorded images when a different endpoint was active.
  • Added glm-5.2 to the built-in model capability database — ensures correct ContextWindow (204800) and MaxOutputTokens (65536) values, and correctly marks it as non-vision.
  • Session restore baseline improvement — token baseline now uses the last real usage entry from UsageHistory instead of relying solely on CheckpointTokens, giving more accurate context fill estimates after resume.
  • Anthropic provider token calibrator — periodic real-API token calibration for more accurate context window tracking on Anthropic endpoints.
  • Gemini provider session ID injectionSetSessionID now available on the Gemini provider for consistent request tracing.
  • LAN chat inbound DM callback — fires an onInboundDM callback for non-broadcast messages so the rate limiter can reset the DM cooldown for the sender on the HTTP transport path.

Upgrade notes

  • If you experienced messages.content.type 参数非法 errors when resuming old sessions on Z.ai GLM endpoints, this release fixes it. No manual intervention needed — image data in old sessions is automatically stripped.

Compare

v1.3.153...v1.3.154