PR #79 (suppress consecutive identical retry errors) merged after the
v0.5.20 release commit but before the tag was pushed. The released
build will contain its code, so the notes need to mention it. Title
broadened to cover both retry-link denoise changes (#78 + #79).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
One PR merged into main since v0.5.19:
- #78 fix(agent-limiter): add streak gate + raise verification cap to 12
The original limiter only had a single total-count cap (verification=5)
that hard-blocked the 6th call regardless of whether prior calls
succeeded or failed. Five PRs each verified successfully and the 6th
PR was blocked anyway. Replaced with two complementary gates: total
cap raised to 12, and a new consecutive-FAIL streak gate (3 FAILs in
a row caps immediately, any PASS clears the streak). The streak gate
catches verifier-loop pathology faster and more accurately than a
count-only cap, while the raised total leaves headroom for legitimate
multi-step work.
This release commit prepares v0.5.20 metadata. Tag will be pushed
separately when ready to trigger the desktop release workflow.
See release-notes/v0.5.20.md for full details.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5 PRs merged into main since v0.5.18:
- #73 fix(skills): activation scope button contrast + project picker
- #74 feat(sidebar): delete all sessions for a project
- #75 feat(sidebar): export/import session as JSONL
- #76 fix(sidebar): keep an explicitly opened sub-directory as its own project
- #77 feat(skills): allow activating a skill in multiple projects at once
See release-notes/v0.5.19.md for full details.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Skills system upgrade: built-in Karpathy Guidelines, active skills
auto-injection mechanism, and CLAUDE.md project rules management UI.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tested: bun run scripts/release.ts 0.4.3 --dry
Tested: git diff --check
Tested: bun run verify (artifacts/quality-runs/2026-06-16T16-48-12-824Z/report.md; passed=8 failed=0 skipped=2)
Confidence: high
Scope-risk: narrow
Combine main's Workspace LSP release notes with image-gen plugin
feature notes. Keep main's editor-lsp-foundation content and add
new sections for image-gen MCP plugin, desktop plugin config, and
inline image rendering.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HIGH fixes:
- SSRF protection: block private/link-local IPs and file:// URLs
in edit_image image_url parameter
- Mask sensitive values in GET /api/plugins/options response
MEDIUM fixes:
- Clamp n parameter to 1-10 to prevent API bill exhaustion
- Validate prompt is non-empty string before API call
- Return empty array when no providers configured (clear error)
- Add 1MB buffer limit for JSON-RPC line accumulation
- Fix PluginConfigModal useEffect re-fetch loop on parent re-render
LOW fixes:
- Remove unused requestId variable
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pulls 21 upstream commits (147 files, +17234 / -317) since merge-base
4bea9ee6. Major upstream additions:
- feat(trace): session trace monitoring + LangSmith-style two-pane UI
(large new subtree under src/server/services/traceCaptureService.ts,
src/server/api/traces.ts, desktop/src/components/trace/, lib/trace/)
- feat(adapters): WhatsApp linked-device adapter (new sub-tree)
- feat(adapter): Telegram command menu
- feat(desktop): plugin list bulk toggles
- feat(desktop): output style desktop config
- fix(agent): defer permission/runtime restarts during active turns
- fix(agent): avoid concurrent worktree config writes
- fix(desktop): native preview screenshots, memory file preview-first
Conflict resolution (8 files, all handled by hand):
- desktop/package.json: kept fork version 0.5.8 (vs upstream 0.4.1)
and the fork's homepage URL.
- src/server/router.ts: kept BOTH /api/projects (fork) and
/api/traces (upstream) handlers + imports.
- desktop/src/components/chat/chatBlocks.test.tsx: kept fork's
"expanded by default" thinking-block tests; upstream had the old
"collapsed by default" assertions which contradict the live
ThinkingBlock.tsx default (`useState(true)`).
- desktop/src/pages/Settings.tsx: merged imports — added
`type TranslationKey` (upstream, used by trace tab) plus kept
fork's providerCompat store imports.
- desktop/src/components/plugins/PluginList.tsx: integrated
upstream's bulk-toggle (selectedPluginIds, ConfirmDialog,
bulkEnable/Disable) on top of fork's catalog/marketplace/inline
actions. Row layout now has checkbox + details button + inline
toggle/uninstall + chevron all coexisting. Both ConfirmDialog
instances (uninstall + bulk-batch) kept.
- src/server/api/sessions.ts: kept BOTH session-summary (handoff,
fork) and trace-call (upstream) handler functions and imports.
Routing dispatch was auto-merged correctly.
- src/server/services/conversationService.ts: unified
SessionStartOptions to carry fork's coordinatorMode +
handoffSystemPrompt AND upstream's resumeInterruptedTurn.
- src/server/ws/handler.ts: unified RuntimeOverride type to keep
fork's `thinkingEnabled` field (used 30+ times elsewhere) AND
upstream's new ActiveUserTurnState plus the deferred-restart Maps
(activeUserTurns, deferredRuntimeRestarts, deferredPermissionModes).
cleanupSessionRuntimeState now drains both fork's session sets
(coordinatorModeSessions, handoffSummarySessions) and upstream's
new Maps.
Verification:
- bun run lint (desktop): clean.
- bun test src/server/__tests__/mcp.test.ts -t marketplace: 2/2 pass.
- bun test src/server/__tests__/sessions.test.ts: 76/77 pass. The
single failure (slash-commands legacy custom commands) reproduces
on un-merged origin/main and is pre-existing — not introduced by
this merge.
Not-tested:
- Full bun run verify gate. Recommended before push/PR.
- Live trace UI smoke (no provider creds in this environment).
- Plugin list bulk-toggle smoke (no headed Electron available).
- WhatsApp adapter (separate sub-tree, not exercised by typecheck).
Confidence: medium-high (typecheck clean, no markers, conflicts all
semantically reasonable). Recommend a maintainer eye on
ws/handler.ts and conversationService.ts before merging upward,
since the deferred-restart vs handoff-injection paths touch the
same Map-of-pending-state surface.
Scope-risk: broad (147 files brought in via merge). Risk surface is
contained because trace + WhatsApp are independent subtrees and the
hand-resolved conflicts kept both sides additive rather than
rewriting either's logic.
When a third-party Anthropic-compatible gateway (typical: Bedrock-backed
proxies like the user's mimo setup) can't relay Anthropic's `thinking`
field, it returns 400s like
"该模型不支持 'additionalModelRequestFields' 字段" — the gateway has
wrapped the unknown Anthropic param into AWS Bedrock's
`additionalModelRequestFields`, and Bedrock rejects on the target
model. The user reported a 4.5 model on mimo failing this way while the
same model on kiro-account-manager 1.7.5 (which doesn't go through
Bedrock) was fine.
End-to-end fix: detect the failure pattern, sticky-mark the provider,
auto-restart the sidecar with `CLAUDE_CODE_DISABLE_THINKING=1`, and
surface a Settings badge so the user knows what happened. Mirrors the
desktop providerCompatStore pattern from PR #4 (fake tool_use detection)
— two compat dimensions, same re-arm-on-edit semantics, same UX shape.
Server side
-----------
- `SavedProvider` schema gains `thinkingIncompatible?: boolean` and
`thinkingIncompatibleReason?: string` (max 500 chars). Fully
back-compat: missing field reads as undefined.
- `ProviderService.markThinkingIncompatible(id, reason)` writes the
flag, idempotent for identical reasons (no thrash on a burst of the
same error). Returns null for unknown ids and openai-official.
- `ProviderService.updateProvider` auto-clears the flag on any edit —
user changing config = "I'm fixing it" → fresh chance.
- `buildProviderManagedEnv` injects `CLAUDE_CODE_DISABLE_THINKING=1`
when the flag is true, so the next sidecar launch goes out without
thinking entirely.
- WS handler runs `detectThinkingIncompatMessage` on every error
ServerMessage forwarded to the desktop. On match, fires:
1. `markThinkingIncompatible` (persists)
2. `provider_compat_event` WS message to the desktop
3. `enqueueRuntimeTransition` → `scheduleRestartSessionWithRuntimeConfig`
(same graceful path used by set_runtime_config — never tears
down a streaming response mid-flight)
Process-local dedup so a burst of identical errors doesn't restart
the sidecar repeatedly.
- Detection regex deliberately narrow:
/additionalModelRequestFields/i
/\bthinking\b[^.]*\b(not supported|unsupported|invalid|
disabled|rejected)\b/i
/unknown.{0,40}\bthinking\b/i
False positives would permanently disable thinking on the wrong
provider until the user edited its config.
Desktop side
------------
- New ServerMessage variant `provider_compat_event` plumbed through
both server and desktop chat type unions.
- `providerCompatStore` gains `thinkingIncompatibleProviderIds:
Set<string>`, `recordThinkingIncompatible(id, reason)` action,
`hasProviderThinkingIncompatible(id)` helper. Persisted to the
same localStorage key as the fake-tool_use counter, alongside
it. Dedup: re-firing for an already-flagged provider doesn't
re-toast.
- `clearProvider(id)` now clears BOTH dimensions, matching the
server-side updateProvider behavior.
- `chatStore` switch dispatches the new event to the store.
- `Settings → Provider` row renders a separate "思考不兼容" badge
(psychology_alt icon) next to the existing "工具调用异常" badge.
Both badges can show simultaneously when a provider has both
problems; both are cleared by the same edit-and-save action.
- 5 locales (en/zh/zh-TW/jp/kr) get 3 new keys each: badge label,
badge tooltip, and toast message.
Tests
-----
- `src/server/ws/thinkingIncompat.test.ts` (NEW, 6 cases): regex
pinning — Bedrock additionalModelRequestFields rejections /
thinking-rejection phrases / unrelated 4xx / passing mentions of
thinking / null-empty defensive / case-insensitive.
- `src/server/__tests__/providers.test.ts` (5 added): markThinkingIncompatible
persists / truncates 500-char reason / idempotent / null-for-unknown-id
/ null-for-openai-official / updateProvider auto-clears.
- `src/server/__tests__/provider-runtime-env.test.ts` (2 added):
`CLAUDE_CODE_DISABLE_THINKING=1` injected when flag true / absent
when flag false (back-compat with v0.5.7 providers.json).
- `desktop/src/stores/providerCompatStore.test.ts` (6 added):
records flag + one-time toast / persists set / hydrates from
localStorage / clearProvider clears both dimensions / null-empty
defensive / hasProviderThinkingIncompatible reflects current state.
Folded into the unreleased v0.5.8 release notes — fold both this fix
and the PR #5 (handoff fixes) into the same 0.5.8 release.
Tested:
- bun run lint (desktop) clean
- bun test src/server/{ws/thinkingIncompat,__tests__/providers,
__tests__/provider-runtime-env}.test.ts → 87 + 6 = 93 pass
- bunx vitest run src/stores/providerCompatStore.test.ts → 14 pass
- bunx vitest run src/components/chat/AssistantMessage.faketooluse.test.tsx
→ 6 pass (regression check, no breakage from the new chatStore
dispatcher case)
Confidence: high
Scope-risk: narrow — additive types throughout (back-compat with
v0.5.7 providers.json), narrow detection regex, dedup guard prevents
restart loops, edit-to-clear gives users an easy escape hatch.
Co-authored-by: 你的姓名 <you@example.com>
Two bugs in the v0.5.7 "Continue from here" hand-off path landed in
the wild and the user caught them while exercising 0.5.8 prep:
1. **Stray empty session.** When the user previously opened a "New
session in X" tab from the sidebar, then closed the tab to
declutter, the freshly-created empty session was already on disk
and visible in the sidebar. Coming back to the welcome screen
(activeTabId = null → EmptySession route) and clicking "Continue
from here" called `createSession` unconditionally, minting yet
another empty session next to the now-stale one. The user ended up
with `Untitled Session 27 minutes ago` lingering in the sidebar
while the hand-off ran in a completely separate fresh session.
Extract the picker into `desktop/src/lib/sessionReuse.ts` —
`pickReusableEmptySession(sessions, workDir, excludeSessionId?)`
filters by exact-workDir match, `messageCount === 0`, excludes the
previous session being handed off FROM, and sorts by `modifiedAt`
desc. Caller in `EmptySession.onAutoHandoff` runs this before
`createSession`; on hit, openTab on the existing sessionId and let
ContentRouter switch to ActiveSession naturally; on miss, create
fresh as before.
7 unit tests cover the boundaries: workDir mismatch, non-zero
messageCount, excludeSessionId honored, null workDir treated as
"no candidates" (so we never silently merge home-dir sessions
into a project hand-off), empty workDir argument, empty session
list, freshness sort order.
2. **Summary too abstract; AI doesn't know specific recent state.**
The previous implementation only injected the LLM-summarized
`main` + `recent` paragraphs into the next session's system
prompt. That summarization tends to wash out exact wording, file
paths, error messages, and the user's literal last question — the
user reported "AI doesn't know what we just hit a wall on."
Add `recentRaw?: string` to `SessionSummary`. New helper
`buildRecentRawSlice` keeps the LAST ~12 turns (env-tunable via
`CLAUDE_CODE_HANDOFF_RAW_TURNS`, range 0–50, default 12), each
truncated to 400 chars preserving the `USER:` / `ASSISTANT:`
role prefix, total capped at ~8000 chars (env-tunable via
`CLAUDE_CODE_HANDOFF_RAW_CHARS`, range 500–30000, default 8000).
Older turns drop first when the total cap is busted by dense
recent turns.
`formatHandoffSystemPrompt` renders the raw slice inside a fenced
code block AFTER the abstracted recent summary, so the next
session sees both the digest and the literal text. Section is
omitted entirely when `recentRaw` is absent — v0.5.7 caches still
load and produce the exact same prompt bytes (back-compat).
8 unit tests cover the formatter's back-compat path, the raw
block placement, fence rendering, tail-N selection, all-fits
case, per-turn truncation with role prefix preservation, total
cap busting (older drops first), and the `RAW_TURNS=0` opt-out.
Both fixes fold into the unreleased v0.5.8 — release-notes/v0.5.8.md
gets two new fix bullets and the 范围 / 验证 sections call out the
new files and 15 added tests.
desktop/package.json bump to 0.5.8 stays as-is (preset earlier in
the same worktree before this commit).
Tested:
- bun run lint (desktop) clean
- bunx vitest run sessionReuse.test.ts → 7/7 pass
- bun test sessionSummaryService.test.ts → 8/8 pass
- bunx vitest run EmptySession.test.tsx → 22/22 pass (regression check
after the helper extraction — the existing tests don't go through
the hand-off branch but exercise the rest of the file)
Confidence: high
Scope-risk: narrow (no shape changes to any persistence — recentRaw
is an additive field, old caches deserialize cleanly because
`tryParseSummaryResponse` already only required main+recent)
Co-authored-by: 你的姓名 <you@example.com>
Two context-management fixes (CLI/sidecar side):
1. Re-compaction loop (方案1+2). Auto-compaction previously only circuit-broke
on hard failures; a compaction that succeeded but left context still over
threshold reset the failure counter and re-compacted every turn, burning a
summary API call each time.
- autoCompact.ts: isIneffectiveCompaction() — when truePostCompactTokenCount
is still >= threshold, count it toward the existing circuit breaker instead
of resetting to 0; query.ts now honours that count on the success path.
- shouldThrottleAutoCompact() — suppress proactive autocompaction for a few
turns after a compaction, unless at the hard blocking limit (so we never
risk prompt-too-long by throttling).
2. Post-compact context meter stuck at ~100% (sessionService.ts). The transcript
context estimate counted the entire pre-compact history plus the summarization
call's huge input_tokens, pinning the indicator near full until the next turn.
Now the estimate is scoped to messages after the latest compact_boundary, with
a model fallback for the just-compacted/no-new-turn case. Non-compacted
sessions are unchanged.
Tested:
- bun test src/services/compact/autoCompact.test.ts (12 pass; throttle + ineffective predicates)
- bun test src/server/__tests__/conversations.test.ts -t "context" (6 pass incl. new compact-boundary scoping case)
Not-tested: 4 pre-existing WebSocket runtime-restart integration tests fail in this env (CLI subprocess code 143); unrelated to these changes.
Confidence: high
Scope-risk: moderate
- Update source: desktop/package.json publish.owner NanmiCoder -> 706412584 (electron-updater
now checks this fork's releases via app-update.yml). Also bump homepage and the legacy
Tauri updater endpoint to the fork.
- About page: GITHUB_REPO / issues / releases / changelog and the displayed repo name now
point to 706412584/cc-haha. Sidebar repo link and ActivitySettings profile subtitle too.
- Attribution: original author (NanmiCoder + Bilibili/Douyin/Xiaohongshu social links) is
preserved unchanged. Added a new "Fork maintainer" credit (706412584) with i18n keys
settings.about.forkMaintainer / forkMaintainerHint across en/zh/zh-TW/jp/kr.
Why: this is a self-maintained fork shipping its own builds; pointing the updater at upstream
risked overwriting custom builds with upstream releases and hid the fork's own releases.
Tested:
- bunx vitest run src/pages/ActivitySettings.test.tsx src/__tests__/generalSettings.test.tsx (59 pass)
- cd desktop && bun run lint (clean)
Not-tested: full verify (long-running)
Confidence: high
Scope-risk: moderate
Built-in agents:
- Add debugger, security-reviewer, refactor, migration, docs-writer, performance, commit-pr built-ins and register them in getBuiltInAgents().
Desktop:
- AskUserQuestion prompts no longer vanish silently: when an unanswered question card is cleared by turn end (message_complete / error) — e.g. a malformed question call — a visible system notice (chat.questionDropped) is appended instead. Added across en/zh/zh-TW/jp/kr.
Versioning:
- Bump desktop/package.json to 0.5.5 and add release-notes/v0.5.5.md.
Tested:
- bunx vitest run desktop/src/stores/chatStore.test.ts (99 pass, incl. dropped-question notice for message_complete + error, and no notice for non-AskUserQuestion)
- bun test src/tools/AgentTool/builtInAgents.test.ts (pass)
- cd desktop && bun run lint (clean)
- build:windows-x64 + package-smoke (PASS, Claude-Code-Haha-0.5.5-win-x64.exe)
Not-tested: full bun run verify / check:server (long-running)
Confidence: high
Scope-risk: moderate
v0.5.3's one-shot skip only blocked a single auto-drain, but a Stop emits
multiple idle events (message_complete + status idle); the second one still
drained one queued message and flipped the button back to running. Replace
the one-shot skip with a sticky queueDrainPaused flag: Stop pauses all
auto-drains until the user sends their next message (which clears it and
fires immediately, ahead of the queue). The queue then resumes FIFO on the
next idle. Bumps desktop app to 0.5.4 with release notes.
Tested: tsc --noEmit; Vitest chatStore 94 passed (incl. multi-idle stop /
priority message / queue resume); browser end-to-end (Stop keeps button at
Run with queue intact, priority send immediate, queue resumes); Windows x64
NSIS package + package-smoke PASS.
Scope-risk: narrow
Confidence: high
Stop no longer flushes the queue: a user-initiated Stop now skips exactly the
auto-drain triggered by its resulting idle (one-shot guard). The queue stays
intact, the next message the user sends fires immediately (priority, not
queued — even with items waiting), and the queue resumes FIFO on the next idle
after that turn. Queue enqueue/drain/edit mechanics are otherwise unchanged.
Also removes the Buy-Me-a-Coffee / donation section from README (zh/en).
Bumps desktop app to 0.5.3 with release notes.
Tested: desktop tsc --noEmit; Vitest chatStore 94 + pages/ActiveSession 43
passed (incl. stop-no-flush / priority-message / queue-resume case); Windows
x64 NSIS package + package-smoke PASS.
Scope-risk: narrow
Confidence: high
Desktop chat message queue (v0.5.2):
- Queue follow-up messages (Enter) while the agent is busy; FIFO auto-drain
on true idle. Collapsible, height-capped to-do panel above the composer so
it never inflates the composer. Per-item move-to-top/edit/delete/clear.
Never drains mid-stream, during tool execution, or while a permission
prompt is pending; Stop cancels the current turn but keeps the queue.
Per-session isolation. In-memory only (no persistence schema change).
Also included in this commit:
- Settings provider form: model-id comboboxes + fetch-models + per-slot
context-window auto-fill.
- Bundled skills: defineGoal, pdf, screenshot.
- Bump desktop app to 0.5.2 with release notes.
Tested: desktop tsc --noEmit; Vitest chatStore/pages/ActiveSession 136 passed
(incl. 7 queue tests); browser end-to-end queue smoke; Windows x64 NSIS
package + package-smoke PASS.
Not-tested: full check:desktop suite has pre-existing unrelated failures
(electron packaging, theme cycling, ThinkingBlock label); check:server.
Scope-risk: moderate
Confidence: medium
In-progress generations were interrupted when a set_runtime_config
arrived mid-stream: the handler immediately stopped and restarted the
CLI subprocess. Track per-session busy state from outbound status
events and queue the restart, applying it (with the latest override,
collapsing multiple toggles) once the session returns to idle.
Bumps desktop app to 0.5.1 with matching release notes.
Tested: desktop tsc --noEmit; Windows x64 NSIS package + package-smoke.
Not-tested: check:server, desktop Vitest.
Scope-risk: narrow
Confidence: medium
- Intro now explains why we migrated: users reported macOS performance
issues and Windows behaviour diverging from the macOS dev environment;
Electron's bundled Chromium unifies the rendering layer at the cost of a
larger installer.
- Fixes section rebuilt from the real v0.3.2..HEAD commits, keeping the
upstream issue numbers (#665#653#351#672#678#671#681#658#651#620)
so they can be closed against this release.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Real-world testing showed the unsigned app just needs the original 0.3.2
one-liner after the "damaged" prompt (System Settings "Open Anyway" also
works). Drop the Sequoia / "don't trash it" / clear-DMG-first / script
walkthrough noise and match the historical release-note style.
- release-notes/v0.4.0.md: macOS = drag in + `xattr -cr ...`, Windows one
line, Linux kept short.
- docs/desktop/04-installation.md: same trim, remove duplicated FAQ entry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Rewrite release-notes/v0.4.0.md to match the historical style (no emoji,
Highlights/Fixes/Notes), keep it user-facing only (drop release-process
notes), and correct Linux (supported since the Tauri builds, not new).
- README.md / README.en.md: replace Tauri references with Electron, list
macOS / Windows / Linux, and point first-launch approval to the guide.
- Rewrite docs/desktop/04-installation.md for Electron: Electron asset
names, Linux section, and the unsigned-macOS flow (clear the DMG quarantine
before double-clicking; drop the WebView2/right-click-open leftovers).
- install-macos-unsigned.sh: keep the same-folder DMG flow, no online download.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove maintainer-facing release workflow notes from the public release markdown and keep the macOS unsigned install guidance concise.
Tested: git diff --check
Tested: bun run check:docs
Confidence: high
Scope-risk: narrow
Bump the Electron desktop package version to 0.4.0, publish a macOS unsigned install helper, and let the release workflow continue when Developer ID signing is not configured.
Tested: bash -n desktop/scripts/install-macos-unsigned.sh
Tested: bun test scripts/pr/release-workflow.test.ts
Tested: bun run scripts/release.ts 0.4.0 --dry
Tested: git diff --check
Tested: bun run check:docs
Tested: bun run check:policy
Confidence: high
Scope-risk: moderate
Summarize the v0.3.2 to v0.4.0 Electron migration window and document the installer paths users should follow.
Tested: bun run scripts/release.ts 0.4.0 --dry
Tested: git diff --check
Tested: bun run check:docs
Confidence: high
Scope-risk: narrow
Prepare the desktop release metadata and concise release notes while keeping
tagging and release publishing for a later step. The staged local build-script
updates keep desktop commands on checked-in local toolchain paths and avoid
rewriting preview-agent output when the built content is unchanged.
The persistence-upgrade gate now runs the focused desktop Vitest migration
suite in non-watch mode, matching the broader desktop quality lane and avoiding
pre-push termination during release preparation.
Constraint: Release publishing is intentionally deferred per request
Constraint: Desktop release metadata must keep package, Tauri config, Cargo metadata, and Cargo.lock aligned
Confidence: medium
Scope-risk: moderate
Directive: Do not tag v0.3.2 until release dry-run and final release verification are rerun on the release candidate
Tested: bun run scripts/release.ts 0.3.2 --dry
Tested: cd desktop && bun run lint
Tested: bun run check:persistence-upgrade
Tested: git diff --check
Not-tested: Full bun run verify
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
Bump version from 0.2.9 to 0.3.0 across desktop/package.json,
tauri.conf.json, and Cargo.toml. Add v0.3.0 release notes covering
desktop long-session performance, streaming tool previews,
AskUserQuestion reliability, multi-client streaming, and H5 network
fixes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This records the v0.2.9 release notes and aligns desktop package,
Tauri, and Cargo metadata so the release script can create the final
annotated tag after manual validation.
Constraint: Release tag creation is intentionally deferred for manual smoke validation.
Rejected: Run scripts/release.ts now | it would create the release commit and annotated tag before manual review.
Confidence: high
Scope-risk: narrow
Directive: Do not create v0.2.9 tag until the manual release check is complete.
Tested: bun run scripts/release.ts 0.2.9 --dry
Tested: bun run check:native
Not-tested: Full bun run verify and live ChatGPT Official OAuth smoke
The release boundary was already prepared, but recent desktop Agent display fixes landed after it and /goal needed to be described as a new user-facing feature rather than a restored hidden workflow. Update the release body before tagging so GitHub Release content matches the shipped surface.
Constraint: release workflow reads release-notes/v0.2.8.md from the tagged commit
Rejected: Leave /goal as recovery wording | users never saw the hidden implementation as a public feature
Confidence: high
Scope-risk: narrow
Tested: git diff --check -- release-notes/v0.2.8.md
Tested: bun run scripts/release.ts 0.2.8 --dry
Tested: cd desktop && bun run test -- run src/components/chat/MessageList.test.tsx -t agent
Tested: cd desktop && bun run build
Not-tested: Full live release gate in this turn
The desktop release workflow expects app version files, Cargo.lock, and release-notes/vX.Y.Z.md to agree with the tag. Bump the desktop package and Tauri metadata to 0.2.8 and add the release note that will be used as the GitHub Release body.
Constraint: The release pipeline reads release-notes/v0.2.8.md from the tagged commit.
Confidence: high
Scope-risk: narrow
Directive: Keep desktop/package.json, Cargo.toml, tauri.conf.json, Cargo.lock, and release-notes/vX.Y.Z.md aligned before tagging.
Tested: Not rerun for this metadata-only release prep commit; previous push gate passed for the workflow fix immediately before this commit.
Not-tested: Full release workflow and packaged artifact smoke after tagging.
The goal workflow remains in code but is intentionally hidden for this release, so the public release note should not market or validate it as a shipped feature.
This keeps the release body aligned with the enabled entry points and shifts the highlight back to Project Memory, project sessions, plugin refresh, chat input, and desktop stability.
Constraint: /goal is not being published in v0.2.7 because defects remain
Rejected: Leave /goal in the release note | would ask reviewers and users to validate a hidden feature
Confidence: high
Scope-risk: narrow
Tested: rg -n 'goal|/goal|目标' release-notes/v0.2.7.md
Tested: git diff --check
Tested: bun run scripts/release.ts 0.2.7 --dry
The release branch has moved substantially past v0.2.6, so this records the desktop version bump and the release note that will be reviewed before the tag is created. The note groups the large post-v0.2.6 range by user-facing areas instead of replaying the raw commit list.
Constraint: The user wants to push the release-prep commit for manual GitHub development testing before any tag is created.
Rejected: Run scripts/release.ts directly | it would create the release commit and annotated tag before review.
Confidence: high
Scope-risk: narrow
Directive: Do not create v0.2.7 tag until manual GitHub validation is complete.
Tested: bun run scripts/release.ts 0.2.7 --dry
Tested: git diff --check
Not-tested: Full release gate or tag-triggered release workflow.