Skip to content

0.2.16#531

Merged
XingYu-Zhong merged 97 commits into
masterfrom
develop
Jun 23, 2026
Merged

0.2.16#531
XingYu-Zhong merged 97 commits into
masterfrom
develop

Conversation

@XingYu-Zhong

Copy link
Copy Markdown
Collaborator

No description provided.

musnows and others added 30 commits June 20, 2026 12:30
…close

fix(installer): stop bundled processes before windows upgrade
fix(ui): prevent jump rail number clipping
…povers

fix(composer): anchor execution dropdowns under zoom
…rectly (v2) (#448)

* Implement event throttling for SSE messages

Added a message throttling queue and timer to batch events before sending to the frontend.

* fix(desktop): throttle SSE events across IPC and add unit tests

---------

Co-authored-by: xingyu <1736101137@qq.com>
feat(speech): add local whisper transcription
The SDD requirement status pills (planned/building/done/verified) only
overrode the text color for the dark theme while keeping the light-mode
background, which is a saturated translucent fill tuned for light
surfaces. On the dark canvas the pill background stayed too bright and
clashed with the already-adjusted light text color.

Add matching dark-theme background overrides so the pill fill tracks the
text color at a soft opacity, and add dark-theme segments for the SDD
requirement progress bar so the filled segments use the lighter tailwind
shades instead of the vivid base hues.
Add the Retroma parchment-inspired light palette from Talkcody as a
built-in color mode in the mode workshop, toggled via a palette button
on the default Kun card. Light-only: all Retroma selectors carry a
:not([data-theme='dark']) guard so dark mode falls back to the Kun
default. Activation mirrors iKun (data-retroma-mode DOM attribute +
full --ds-* token block in base-shell.css), with no mascot figures.
XingYu-Zhong and others added 29 commits June 22, 2026 02:30
feat(lsp): language server diagnostics (#466) + review fixes
feat(plugins): OAuth connector previews (#480) + URL validation
feat(cache): cache diagnostics (#485) + aggregation fixes
feat(terminal): monochrome + custom colors + CJK (#497) + fixes
feat(skills): import from GitHub (#464) + security hardening
Plan Mode was a single useState on the singleton Workbench, so toggling it in one chat affected every chat. Move the mode into useChatStore as composerMode, keyed per-thread via kun.threadComposerMode.v1 (mirroring the existing per-thread composerModel pattern), with a global kun.composerMode default for the no-active-thread case.

- chat-store-helpers: add ComposerPlanMode type, normalize/read/persist helpers, per-thread remember/read map (capped at MAX_THREAD_COMPOSER_SELECTIONS), and composerModeForThread (prefers stored value, falls back to thread.mode === 'plan', else 'agent').
- chat-store-types/chat-store: add composerMode state + setComposerMode action; initialize from readStoredComposerMode.
- chat-store-app-actions: setComposerMode writes the per-thread map when a thread is active, else the global default.
- chat-store-thread-actions: selectThread hydrates composerMode via composerModeForThread.
- Workbench/workbench-plan-controller: consume composerMode/setComposerMode from the store instead of local useState.

Tests: add per-thread persistence and global-default isolation coverage in chat-store-helpers.test.ts and chat-store-app-actions.test.ts.
…mode

feat(composer): make plan mode per-thread
fix(settings): 优化设置页布局
…icons

fix(editor): load cross-platform picker icons
…56-mac-topbar

# Conflicts:
#	src/renderer/src/components/chat/WorkbenchTopBar.tsx
The PR widened modelIdSchema to 512 chars (MAX_MODEL_ID_LENGTH) but two
modelHint fields in clawTaskFromTextPayloadSchema and
scheduleTaskFromTextPayloadSchema were still hard-capped at 128, which
re-triggers issue #473 on the IM/fromText IPC route. Reuse modelIdSchema
for both modelHint fields and add a regression test that exercises a
256-char id on each schema.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Rewrite rollbackWorkspaceConfirmDetail (EN/ZH) to disclose that
  git reset --hard + git clean -fd will permanently destroy uncommitted
  edits, untracked files, and commits since the checkpoint. The old
  copy said 'only restores workspace files' which hid the destruction.

- Surface rescueCheckpointId after a successful restore. Previously
  the action discarded it, leaving users with no path back if the
  rollback was a mistake. Now the id is console.info-logged for
  power users and shown in the transient store notice via the new
  rollbackWorkspaceSuccessWithRescue locale key.

- Re-check busy AFTER the confirm dialog resolves. The user can type
  and send during the await; running git reset --hard mid-turn would
  wipe files the agent is actively editing. Reuse the existing
  rollbackWorkspaceBusyError key.

- Gate rewindFileRollbackNotice on block.meta.workspaceCheckpointId.
  Users in non-git workspaces no longer see a 'file changes will be
  rolled back' notice when nothing actually rolls back.

- Add store tests covering busy-after-confirm short-circuit and
  rescueCheckpointId surfacing (log + notice).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, add tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two HIGH-severity correctness fixes on top of #478's queued-task feature:

1. Worktree slot cleanup. Scheduled agent runs always leave changesCount>0,
   so findAvailablePoolIndex would permanently skip every used slot after a
   few runs. releaseWorktree now resets HEAD and runs git clean -fd in the
   slot before dropping the lease. Failure is best-effort: a slot that
   refuses to clean stays dirty (same as today) rather than blocking the
   release. Chose the worktree-service location so any future caller
   (renderer-side maintenance, removeWorktree, etc.) benefits — added an
   opt-out skipClean for callers that need it.

2. Concurrency cap race. runTask used to do `size < MAX_CONCURRENT` then
   await store.load() then enter runTaskInternal. Two concurrent IPC
   callers could both pass the size check before either incremented
   runningTaskIds. All paths now route through enqueueTask + drainQueue;
   the size check sits inside drainQueue (serialized by the drainingQueue
   flag), and the running slot is reserved synchronously inside drainQueue
   before runTaskInternal awaits anything. Immediate-run semantics are
   preserved via a per-task completion deferred so the caller still
   awaits the eventual ScheduleRunResult.

Bonus: when a useWorktree task can't acquire a slot and other worktree
tasks are running, the task is re-enqueued (with a short setTimeout
backoff) instead of failing — once a slot frees, drainQueue picks it up.

Tests: added (a) a four-runs-at-once race that verifies the cap holds,
and (b) a slot-reuse test that confirms the same pool index is reusable
across three back-to-back runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix(settings): accept long provider model ids (#475) + close modelHint gap
feat(memory): compact record details dialog (#502) + UX safety
feat(schedule): queued worktree task execution (#478) + correctness fixes
feat(chat): git rollback action (#458) + safety fixes
fix: macOS top-bar alignment + workflow sidebar back (#456) + develop merge
Plugin tokens were injected only on <html>, but in dark mode the
`[data-theme='dark'] .ds-workbench-shell` rule re-declares the palette
tokens locally, shadowing the injected values for the entire conversation
subtree. Settings/sidebar live outside `.ds-workbench-shell`, so they
themed correctly while the Workbench kept the default Kun blue. Light
mode has no such local re-declaration, hence the dark-only symptom.

Extend the generated token selector to also target `.ds-workbench-shell`
(specificity 0,3,1 > the 0,2,0 base rule), mirroring the existing iKun
`[data-ikun-mode='on'] .ds-workbench-shell` handling, so plugin tokens
win inside the Workbench too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Forking inherited the parent's `mode` and could carry a GUI plan context
bound to the source workspace. A forked "new conversation" then ran as a
plan turn against a stale plan context, producing both reported errors:
  - "tool workspace does not match the active GUI plan workspace" from
    create_plan (the plan context's workspace != the forked thread's), and
  - a provider 400 "A parameter specified in the request is not valid"
    (plan mode narrows the tool set to create_plan, which the cloned
    history's other tool calls/results can't satisfy).

Root cure, two layers:
  - fork() starts a fresh agent conversation (`mode: 'agent'`) instead of
    inheriting plan mode; the plan artifact and its workspace belong to the
    source thread.
  - agent-loop ignores a plan context whose workspace doesn't match the
    thread (isStalePlanContext) and no longer treats such a turn as a plan
    turn, so it runs as a normal agent turn instead of hard-failing.

Adds tests for both layers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- workbench-plan-controller: set in-flight thread marker *before* awaiting
  sendMessage to prevent fast-response race where create_plan block lands
  before the ref is tagged (new threads get re-tagged after send resolves)
- workbench-plan-controller: extract shouldAutoOpenPlanPanel() pure helper
  + thread-id-tagged ref so a plan turn in thread A can't pop open thread B
- Workbench.tsx: pass activeSkillWorkspace (thread's workspace, not the
  global workspaceRoot) to PlanPanel so guiPlanMatchesContext succeeds on
  the freshly-created plan and clearActivePlan() is not triggered
- PlanPanel: temporary console.warn on both clear paths to diagnose the
  workspace/thread values when clearing does fire (remove after root cause
  is confirmed)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@XingYu-Zhong XingYu-Zhong merged commit 80e5d6f into master Jun 23, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants