🚀 CodeBuddy Code v2.97.0 Release
✨ New Features
Complete Keybindings System
Implemented a keybindings system referencing the CodeBuddy Code architecture, supporting context conditions, chord sequences (e.g. Ctrl+X Ctrl+K), and user-defined overrides.
- Configuration file:
~/.codebuddy/keybindings.json - 16 contexts (Global / Chat / Terminal / Autocomplete, etc.) with 60+ actions
/keybindingsslash command for quick management- Web UI adds visual configuration (grouped by context, search, recording, real-time conflict detection)
- REST API:
/api/v1/keybindings(GET/PUT/POST reset/POST validate)
Skill / Subagent Frontmatter Hooks
Aligned with CodeBuddy Code behavior, the hooks: field is now supported in the YAML frontmatter of .codebuddy/agents/*.md and .codebuddy/skills/*/SKILL.md, and is automatically registered and cleaned up during the sub-agent / fork skill lifecycle.
- Supports four hook types:
command/prompt/agent/http once: truefor automatic removal, with event matcher semantics- Default Safety Gate: Frontmatter hooks from non-product built-in sources are disabled by default (including local and plugin marketplace), and require enabling
allowUntrustedFrontmatterHooks: trueinsettings.jsonto take effect
Hook Events Fully Aligned with CodeBuddy Code
Added 20+ hook events covering tool failures, sub-agent lifecycle, task management, permission approvals, file watching, and more:
- Lifecycle: PostToolUseFailure / SubagentStart / StopFailure / PostCompact / ConfigChange / InstructionsLoaded
- Permissions and Tasks: PermissionRequest / PermissionDenied (can intercept approvals), TaskCreated / TaskCompleted, TeammateIdle, Setup
- File Watching: FileChanged (declares watchPaths), CwdChanged (triggered on cwd change)
- New Hook Types:
http(POST to any URL),agent(reuses prompt path) - New Fields:
if(matches by tool name/parameters),shell(switch to PowerShell),once(no longer triggers after success),asyncRewake,allowedEnvVars,statusMessage - Async Protocol: Hook output
{"async": true, "asyncTimeout": N}immediately releases as fire-and-forget
Variable Placeholders for Skills / Commands / Subagents
.md files now support variable placeholder substitution: ${CODEBUDDY_PLUGIN_ROOT} / ${CODEBUDDY_SKILL_DIR} / ${CODEBUDDY_SESSION_ID} and any uppercase environment variables, with ${MY_ENV_VAR:-default} default value syntax. Unset placeholders are preserved as-is to avoid silently losing configuration.
Third-Party Plugin Marketplace Auto-Update
Added the autoUpdateThirdPartyMarketplaces product configuration and the CODEBUDDY_AUTO_UPDATE_THIRD_PARTY_MARKETPLACES environment variable, supporting global enabling of third-party plugin marketplace auto-updates. The marketplace configuration entry adds an optional autoUpdate field for individual control.
Configurable Remote Gateway Task Timeout
The default timeout for the /api/v1/runs endpoint has been raised from 10 minutes to 30 minutes, so long-running tasks are no longer forcibly interrupted:
- New
gateway.runTimeoutMssettings configuration (milliseconds) - New HTTP header
X-Codebuddy-Run-Timeoutfor single-request override - Set to 0 or negative to disable timeout protection
Web UI PWA Auto-Detects New Versions
After releasing a new version, already-opened Web UI tabs no longer require a manual hard refresh:
- Automatically asks the backend whether a new Service Worker is available every 15 minutes
- Automatically refreshes to the new version when the conversation is idle
- During an ongoing conversation, a toast pops up retaining the "Refresh Now" button; subscribed run state will auto-refresh after the Agent becomes idle
UE Projects Automatically Exclude Monorepo Noise Directories
When *.uproject is detected in the cwd, Grep / Glob automatically applies !Intermediate/ !DerivedDataCache/ !Saved/ !Binaries/ !Build/ !.vs/ exclusions to avoid build artifacts of Unreal Engine projects (typically 100K+ source files / 3M+ total files) polluting search results. This can be disabled via settings.disableUEAutoExclude: true. Grep content search adds --max-columns 500 to prevent single-line MB-sized content from flooding stdout.
Desktop Filesystem ACP Methods
Implemented the complete fs/* methods (list / read / write / exists / makeDir / remove / rename / getInfo / watchDir / unwatch) in ACP StreamManager, enabling the WorkBuddy Desktop "All Files" tab to work properly.
🔧 Improvements
- PowerShell Multi-Layer Security Defense: CLM type whitelist (~90 types), Git security protection (bare repo / NTFS 8.3 / archive extractor), dangerous Cmdlet classification (7 sets + 120+ aliases), destructive command UI warnings (16 patterns), Unicode dash support
- ACP Connection Stability: GET SSE connection 30-second heartbeat to prevent reverse proxy (cloudflared / nginx) recycling; waits for history writes to complete on connection close to prevent JSONL log truncation
- Bash Tool Timeout Hint Made Dynamic: The "max timeout" in the tool description was previously hardcoded to 600000ms; now it is dynamically injected to stay consistent with the runtime's actual clamp value
- TUI Ctrl+F / Ctrl+B Cursor Navigation: Supports bash readline-style left/right one-character movement, consistent with existing Ctrl+A / Ctrl+E / Ctrl+K / Ctrl+U; emoji multi-byte character movement is correct
- Web UI Canvas-Embedded Terminal Text Selection: After a tile is focused, the overlay passes pointerdown through to xterm to support select-and-copy; middle / right click / Space + left click still drive canvas panning
- Channel Permission deny_and_exit_plan: WeChat / WeChat Work users can exit Plan mode by replying
q; the ExitPlanMode tool adds a dedicated prompt - Request Purpose Tagging: New
X-Agent-PurposeHTTP header to add classification labels to different types of LLM requests, enabling Langfuse trace analysis - Image Compression Interceptor: Uniformly compresses base64 images sent by users to a 2000px long edge, ensuring images from ACP / TUI / plugin-chat sources all undergo size optimization
- Worktree Directory Switching: After creating or reusing a worktree, tries to enter the relative subdirectory corresponding to the current directory whenever possible
- Unified Session API: Merged
listWorkspacesandlistAcrossProjectsinto a unifiedGET /api/v1/sessionsendpoint, withcwdquery parameter support - Auto-Recovery for Model Permission Errors: When the backend returns "model unavailable", the product configuration is automatically refreshed and the latest available model list is displayed
- Removed Legacy Models and Refreshed Credit Coefficients: Removed the HY 2.0 series (3 models) and GPT-5.2/5.1, totaling 4 legacy models; refreshed model credits per the latest official pricing table (iOA / China Edition / Cloud-Hosted Edition)
- Plugin Loading Concurrency and Caching: Introduced concurrency limits for marketplace plugin list / metadata / component loading to avoid startup jitter; added marketplace plugin list caching and load deduplication
- Automation Task Langfuse Tags: Requests triggered by scheduled tasks automatically carry the
automationtag for easy filtering
🐛 Bug Fixes
ACP Protocol and Stability
/clearSeparator Lost After Restart: Fixed an issue where/clearseparators inserted in CBC / WorkBuddy Desktop sessions disappeared after restart or loadSession replay, along with the resulting 400 errors/compactEffective in IM Scenarios: WorkBuddy Desktop IM's/compact//总结previously had no effect; now compaction is invoked via_metashort-circuit- Cancel Barrier: If a new
session/promptarrives the moment a cancel completes, it would be treated as a new conversation start; added a 500ms cancel barrier - Cancel Marker Leak: When prompt terminal state and
session/cancelhappen simultaneously, the pending cancellation marker was not consumed, causing subsequent AskUserQuestion rounds to be misjudged as canceled - Streaming Reply Repeats Reasoning Content: Fixed WorkBuddy chat streaming reply repeatedly outputting reasoning content
- AskUserQuestion Shows "Unanswered": In ACP mode, the UI displayed "Unanswered" after the user answered AskUserQuestion
- AskUserQuestion Misjudged as "Refused to Answer": The approval signal arrived before the tool execution path established a waiter, causing the answer to be discarded
- Session Lookup Race Condition:
session/promptnow usesgetRuntimeSessionto prioritize active sessions, avoiding "Session not found" - Sessions Inherit CLI Startup Parameters: Sessions created via ACP in
--servemode did not inherit--permission-mode/--modeland other parameters session/loadTimeout: Timeouts occurred in some Windows environments; added a 25s fallback at the protocol entry layer- Model Switch Not Effective:
unstable_setSessionModelnow writes the new model into the runtime session immediately, no longer relying solely on subscription side effects - No Longer Exposes Built-in Commands as Skills:
/clear/help/model/theme/status/resume/renameare no longer mixed into theSkilltool list
Context Compaction (Compact)
- Auto-Cancel Loop: Compaction would falsely appear "auto-canceled" in some scenarios and then immediately retrigger; the compaction call wait limit was relaxed from 60 seconds to 20 minutes
- Residual XML Tags: Residual
</conversation_history_summary>tag remained when tasks ended abnormally - Summary and User Message Misaligned: In request-level auto pre-compaction scenarios, the compaction summary and the original user message were misaligned in history
- Degenerate Summary: After auto-compaction of long sessions, when there was insufficient effective new content, compaction could still trigger again and generate an invalid summary
- History View Stuck After Failure: After a failure/cancellation, retriggering compaction was still stuck
- Timeout Deadlock and Cancellation: Sub-agent compact state machine would deadlock after timeout; the cancellation signal was swallowed when the user actively canceled
- Custom Model Auto-Compaction Window: Falls back to the
CODEBUDDY_AUTO_COMPACT_WINDOWfallback window whenmaxInputTokensis not configured - SDK Mode Auto-Compaction Disconnect: Compaction output leaked to stdout in SDK / headless mode causing disconnection
- Auto-Compaction Renders Raw XML: The chat interface rendered raw
<conversation_history_summary>tags; now uses the same rendering as/compact - Failure Preserves User Message: After auto pre-compaction before sending fails, the user message is preserved and a clear failure prompt is shown
- History
Unknown contentError: Continuing a conversation from history could throwUnknown contentand cause interruption
Models and Request Handling
- PTL Context Overflow Recovery: Added a fallback mechanism that precisely truncates history by API turn, covering common model error messages
- Empty Stream Auto-Retry: Recognizes "empty stream" scenarios where the upstream gateway sends only placeholder/heartbeat frames before disconnecting, and auto-recovers
- Request Body Size Limit Recovery: Explicitly sets
maxBodyLength: Infinityon axios to avoid follow-redirects' default 10MB limit intercepting locally Tool X not foundError Handling: Errors no longer carry agent names with product implementation details;ModelBehaviorErrorno longer pops a client error dialog and instead ends the round viaend_turn- Custom Model Gzip Detection: Fixed an issue where the
custom-local:prefix stripping caused product.models configuration to fail to match - Custom Model Loading 400: Supports both top-level array and object-wrapped formats of models.json
History and Sessions
- First User Message Lost: The user's first message containing hidden context disappeared in the UI
- Model Error Rendered as Assistant Reply: Rounds interrupted by model errors (6004/429) were rendered as normal answers
- Orphaned tool_call Replay: Skips replay for interrupted tool calls and injects a system notification
- Task List Display in Old Sessions: Sessions migrated from older versions rendered an empty task list after restoration
- Image Message Title Pollution: Local image paths leaked in history replay and session title generation scenarios
- Plan Mode Permission Recovery:
prePlanPermissionModewas not correctly passed when starting Plan mode from the Desktop side
Tools and Permissions
- Restored Grep/Glob Tool Registration: Grep/Glob were previously incorrectly removed from 5 product.json files, causing fallback to Bash+rg
--disallowedToolsSubcommand Rules: Rules with subcommands (e.g.,Bash(pkill:*)) were removing the entire tool- Tool Filter Bypass Vulnerability: ToolSearch lookup mode and DeferExecuteTool did not check tool availability
- Glob/Grep Empty Result Hint: Returns meaningful text hints instead of empty arrays
- rm Bulk Deletion Risk Level: Raised from MEDIUM to HIGH to ensure bulk deletion on the IM side triggers user confirmation
- Sandbox strip_write False Success: Silently dropped writes/deletions did not trigger the elevation UI
Configuration Directory
- Bash Sandbox Configuration Directory Path: The Bash sandbox whitelist was ineffective under custom
CODEBUDDY_CONFIG_DIRdirectories - Hardcoded Paths in Prompt Templates: TeamCreate / TeamDelete / statusline-setup tool description templates now render the actual directory via
- Hardcoded Paths in UI Panels: Permissions / Agents / Skills / Memory panels display real paths
- Sandbox Toggle Storage Tier: The Desktop sandbox toggle changed from persistent to in-memory (session-level) to avoid polluting workspace directories
Plugin Marketplace
- MCP Static Authorization Overridden by OAuth: Fixed an issue where the OAuth flow was still triggered when
headers.Authorizationwas explicitly configured - Marketplace Duplicate Names: Name collisions resulted in two entries with the same name that could not be deleted
- Marketplace Duplicate Add Error: Changed to automatically trigger the update flow
- Marketplace Update Cache Not Refreshed:
lastUpdatedtime was not updated afterupdateMarketplace - GithubMarketplace Directory Name Alignment: Non-standard repo URL directory names were inconsistent with manifest.name
- Git Unavailable ZIP Fallback: Adding a plugin marketplace failed in Windows environments without Git installed
- Built-in Suite Marketplace ZIP Distribution: The default suite marketplace had no content; adding the marketplace failed
- Plugin Sub-Agent Description Refresh: Descriptions were not refreshed in time after loading or switching plugin sub-agents
- Skill Scan Dangling Symlinks: Previously caused the entire directory scan to abort
Windows Compatibility
- PowerShell Office Automation: Excel / Word / PowerPoint / Outlook creation was incorrectly intercepted by security policies
- PowerShell Command Wrapping: When
rawCommand=true, skips the bash wrapper to avoid backslashes/backticks being swallowed - Black Window Pop-up: conhost / Git Bash black windows popped up during
--bgbackground sessions and daemon startup - Plugin Commands Not Displayed:
CODEBUDDY_PLUGIN_DIRSnow usespath.delimiterto avoid drive letters being treated as separators - Bash Tool Chinese Garbled Text: Reassembles UTF-8 multi-byte sequences across chunks; injects
PYTHONUTF8=1on Windows
Others
- Daemon Port Race:
EADDRINUSEstartup failure or long connection blocking on restart - MessageQueueDeferredDispatch (Mode B): Agent queue messages could not be sent successfully; "send immediately" messages were lost
- Team Message Real-Time Delivery: While the leader was busy, member SendMessages were stuck in the message queue and not consumed
- Playbook Team Spinner: The agent on the left kept spinning after task completion
- Expert Built-in Skills Invisible: Skill / SlashCommand / ToolSearch tool description caches were not invalidated after
rebuildAgentscompleted - Session Title and Summary Triggers: Ensures title updates, content summarization, and pre-compaction refresh take effect as expected
- ImageGen / ImageEdit Cancellation Support: Image generation requests continued executing after cancellation
- Self-Hosted Deployment Detection: Configurations with enterprise endpoints but actually cloud-hosted were incorrectly marked as Self-Hosted
anydevRemote IDE/ideCommand: AddedCODEBUDDY_IDE_PORT/CODEBUDDY_IDE_HOST/CODEBUDDY_IDE_SKIP_VALID_CHECKenvironment variables- Web UI Editor Save Empties File: The frontend
writeFiledid not explicitly set Content-Type and was consumed by body-parser - Gateway CORS Static Resources: Same-origin IP access to static resources was incorrectly intercepted when the CORS whitelist was enabled
- Read Tool Image Return Format: Returns image content block format
- Worktree Relative cwd: When reusing a worktree, the relative directory was not entered correctly
📝 Documentation Updates
- Deprecated sandboxing.md Documentation: Related links now point to bash-sandboxing.md