Commit graph

186 commits

Author SHA1 Message Date
jinye
3617397e5f
feat(core): Align GenAI telemetry with ARMS (#7536)
* feat(core): align GenAI telemetry with ARMS

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): remove estimated token usage splits

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): address GenAI telemetry review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-23 07:35:46 +00:00
ytahdn
dc74279103
feat(serve): add workspace-level generation (#7552)
* feat(serve): add workspace-level generation

* docs(serve): document workspace generation capability

* fix(serve): align workspace generation contracts

---------

Co-authored-by: ytahdn <ytahdn@gmail.com>
2026-07-23 05:17:03 +00:00
Edenman
b693fcfe6a
feat(serve): support forced MCP reconnects (#7488)
* feat(serve): support forced MCP reconnects

* test(serve): cover forced MCP reconnect options

---------

Co-authored-by: 克竟 <dingbingzhi.dbz@alibaba-inc.com>
2026-07-22 09:02:28 +00:00
ytahdn
80863c0858
feat(web-shell): show subagent sessions in detail panel (#7380)
* feat(web-shell): show subagent sessions in detail panel

* fix(web-shell): harden subagent session details

* chore(sdk): account for subagent client APIs

* fix(core): keep subagent resume history valid

* fix(subagents): stabilize detail session streaming

* test(cli): update telemetry route count

* fix(subagents): address review feedback

* fix(subagents): harden transcript refresh state

* fix(subagents): address maintainer review

* fix(subagents): preserve compact status details

* fix(subagents): address review feedback round 3 (#7380)

* fix(subagents): address remaining detail review feedback

---------

Co-authored-by: ytahdn <ytahdn@gmail.com>
Co-authored-by: 钉萁 <dingqi.jww@alibaba-inc.com>
Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com>
2026-07-22 02:31:08 +00:00
Heyang Wang
6f5d6dfd65
feat(web-shell): add workspace selector button with add/switch dropdown in composer toolbar (#7390)
* feat(web-shell): add managed workspace selector

Let Web Shell create and select daemon-managed workspaces without
changing ownership of existing sessions.

- Add capability-gated existing and scratch workspace registration
- Validate scratch roots, trust provenance, capacity, and shutdown races
- Serialize workspace mutations, session switching, and refresh results
- Add SDK/WebUI wiring and focused cross-package regression coverage

# Conflicts:
#	packages/web-shell/client/App.tsx
#	packages/web-shell/client/components/sidebar/WebShellSidebar.tsx

# Conflicts:
#	packages/cli/src/serve/capabilities.ts
#	packages/cli/src/serve/routes/workspace-management.ts
#	packages/cli/src/serve/server.test.ts
#	packages/sdk-typescript/src/daemon/DaemonClient.ts
#	packages/web-shell/client/App.tsx
#	packages/web-shell/client/components/dialogs/AddWorkspaceDialog.tsx
#	packages/web-shell/client/components/sidebar/WebShellSidebar.tsx

* fix(web-shell): revalidate workspace before session creation

Prevent a stale workspace selection from bypassing the latest trusted
capability snapshot during lazy session creation.

- Validate the selected workspace before passing it to the daemon
- Fall back to the primary workspace when trust has been revoked
- Add a regression test for the pre-effect race window
- Remove stale branch state and clarify add-workspace ownership

* fix(web-shell): improve workspace removal feedback

Keep workspace removal controls legible and make blocked force removals
visibly inactive.

- Size the action menu independently from its narrow icon trigger
- Add a disabled affordance and suppress destructive hover styling
- Cover the removal menu width override with a regression test

* fix(web-shell): centralize existing workspace registration

Route sidebar and composer entry points through the App-owned dialog so
capability gating and workspace reconciliation remain consistent.

- Forward display names only when the daemon advertises support
- Hide and suppress persistence when registration is runtime-only
- Mark directory registrations with existing-workspace provenance
- Cover both entry points and capability combinations with tests

* fix(web-shell): address review feedback on workspace dialogs and capability docs (#7390)

- Document dynamic_workspace_registration and scratch_workspace_registration
  in the conditional serve-features table so the capabilities-docs-contract
  test passes.
- Gate DialogShell backdrop-click and Escape dismissal on the dismissible
  prop so non-dismissible dialogs ignore both gestures.
- Surface an inline error when an added folder registers but the capability
  refresh fails, mirroring the scratch recovery path.
- Add coverage for the active-session workspace switch and the add-folder
  refresh-failure paths.

* fix(web-shell): address review feedback on workspace dialogs and capability docs (#7390)

---------

Co-authored-by: heyang.why <heyang.why@alibaba-inc.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com>
2026-07-22 01:10:18 +00:00
Zqc
cf6c51396c
chore(docs,test): batch three small docs and test fixes (#7373)
* docs(sdk): document auto permission mode

* docs(sdk): clarify auto permission mode

* docs(action): fix GitHub Action input names

* test(weixin): cover exported AES key parser

---------

Co-authored-by: 俊良 <zzj542558@alibaba-inc.com>
2026-07-21 12:50:03 +00:00
yuanyuanAli
ff14e65792
feat(web-shell): Add sidebar customization API for branding, navigation, session actions, and footer (#7379)
* feat(web-shell): Add sidebar customization API for branding, navigation, session actions, and footer

Add new sidebar configuration options to WebShellSidebarOptions:

- primaryNav.items: Control which built-in nav buttons are shown (newTask, plugins, scheduledTasks, goals)
- primaryNav.render(): Append custom content after built-in nav buttons
- hideProjectHeader: Hide the 'Projects' header row (search + add workspace)
- sessionActions.items: Control which session action items appear (both inline and dropdown)
- sessionActions.inlineItems: Control which items render as inline hover buttons (supports all action types with icon/text fallback)
- footer.render(): Inject custom UI elements on the left side of the footer
- Move scheduledTasks and goals from footer.items to primaryNav.items

Visibility follows a strict 'hide-first' policy: inline buttons require all three conditions (items includes + inlineItems includes + built-in capability check) to render.

* fix(web-shell): Prevent inline/dropdown duplication and add pin/archive dropdown fallback

- Critical fix 1: Dropdown items now exclude items already shown as inline buttons (added !inlineActionItems.has guard to each dropdown entry and trigger visibility).
- Critical fix 2: pin and archive now have dropdown menu entries as fallback when not configured as inline items, preventing them from becoming inaccessible.
- Narrowed inlineItems type to WebShellSidebarSessionInlineActionItem (excludes details/group which have no working inline handlers), preventing dead buttons.
- Added destructive color styling (var(--destructive)) to inline delete button when not disabled.

* fix(web-shell): Re-export new sidebar types and add visibility matrix tests

- Re-export WebShellSidebarPrimaryNavOptions, WebShellSidebarPrimaryNavItem, WebShellSidebarSessionActionsOptions, WebShellSidebarSessionActionItem, and WebShellSidebarSessionInlineActionItem from client/index.tsx so consumers can import them by name.
- Add session-action-visibility.test.ts: table-driven tests covering the items × inlineItems × capability matrix (default config, empty items/inlineItems, dedup guarantee, pin fallback to dropdown). 7 test cases, all pass.

* fix(web-shell): gate readOnly archive on sessionActionItems, fix footer null safety and docs accuracy (#7379)

---------

Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
2026-07-21 11:20:51 +00:00
tanzhenxin
443b81e180
feat(core): add opt-in built-in web_search backed by the DashScope Responses API (#7215)
* feat(core): add opt-in built-in web_search backed by the DashScope Responses API

Claude-Session: https://claude.ai/code/session_01KwsYFzWZ6VLCxVN8MbeFXb

* fix(core): require HTTPS for the web_search backend; fail closed on unresolved agent allow-lists

Review follow-ups on #7215: the endpoint gate now rejects plaintext
endpoints (the side request carries a bearer key), and an agent allow-list
whose names resolve to no registered tool keeps its dead entries instead of
widening to the inherited toolset — an agent restricted to the unavailable
WebSearch now runs tool-less rather than gaining shell/write.

Claude-Session: https://claude.ai/code/session_01KwsYFzWZ6VLCxVN8MbeFXb

* chore(cli): remove test-leaked debug artifacts; gitignore the leaked dirs

The CLI unit-test suites write debug logs relative to the package dir
(custom/, first/, from-env/, workspace/); a merge-commit git add swept
them in. Remove them and ignore the directories until the tests are
pointed at temp dirs.

Claude-Session: https://claude.ai/code/session_01KwsYFzWZ6VLCxVN8MbeFXb

* fix(core): honor web_search's own result budget and salvage in-stream-error partials

- Override maxOutputChars (result limit + envelope headroom) so the
  scheduler's global 25k threshold no longer slices results before the
  tool's section-aware truncation can protect URL evidence sections.
- Route in-stream backend errors through the shared terminal-failure
  tail so results streamed (and billed) before the error surface as a
  partial result, matching the transport-error path.
- Strengthen gate tests: assert gate.ok before webExtractor, exercise
  the https-only endpoint guard, and make the config mock disambiguate
  same-id entries by baseUrl like the real Config.

* fix(cli): treat whitespace-only WEB_SEARCH_API_KEY as unset

Apply the function's set-but-empty-is-unset rule to the API key env
var like every sibling env read, and add loadCliConfig coverage for
the web search settings resolution (env precedence, empty-env
fallthrough, base-URL key selection).

* fix(core): salvage failed-terminal web_search results and name the exact endpoint disqualifier

- Route the failed/cancelled terminal paths through the shared
  terminal-failure tail so search evidence streamed (and billed) before
  the backend gave up is salvaged, consistent with the in-stream-error
  and transport-error paths; regression test included.
- Classify base-URL gate rejections so the startup notice blames the
  actual disqualifier: a plaintext-HTTP endpoint now gets an "use
  https://" notice at both the env-declared and modelProviders sites
  instead of the misleading "non-DashScope endpoint" text.
- Cover WEB_SEARCH in the speculation boundary-tools test and the US
  regional host in the DashScope provider test — both behavioral
  changes this PR introduced without direct test coverage.

* test(cli): cover web search suppression in safe and bare modes

The bareMode/safeMode guard is the escape hatch that keeps web search
(external, billed API calls) off in troubleshooting modes; assert that
an enabled settings config resolves to no web search settings under
--safe-mode and --bare.

* fix(core): parse the search model selector once for both gate paths

A selector written for the modelProviders path ("openai:<model-id>", as
the gate's own OAuth notice suggests) was sent verbatim to DashScope
when WEB_SEARCH_BASE_URL overrode the backend, failing with
InvalidParameter. Hoist the resolveModelId parse above the env branch
so both paths share one interpretation of the selector.

Also cover two review gaps: the Claude extension WebSearch tool mapping
and the ACP startup-warning emission that surfaces WebSearch
misconfiguration notices in the client log.

* fix(core): handle response.cancelled in the web_search terminal-event switch and trim gate env keys

- Add response.cancelled to the terminal-event switch so the
  status === 'cancelled' handler is reachable instead of dead code
- Trim API key env vars in the gate (all three check sites), matching
  the CLI-side whitespace rule from 302cf3bb7
- Add tests: cancelled with/without prior search, whitespace-only env
  key rejection, schema getter month/year embedding

* fix(core): cap opened URLs, suppress failed-item progress, note retry budget (#7215)

* fix(core): reject unresolved selector on env-declared web_search path (#7215)

---------

Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
2026-07-21 10:59:36 +00:00
Dragon
22963d5777
feat(core): add fork_turns to fork subagents (#7346)
* feat(core): add fork_turns to subagents

* fix(core): preserve nested agent context inheritance

* fix(core): isolate inherited subagent history

* refactor(core): scope fork_turns to fork agents

* test(core): cover zero-real-turns branch in selectForkHistory

Add a regression guard asserting selectForkHistory returns [] when a
numeric fork window finds no real user turns after the synthetic prefix
(e.g. only startup context present). This pins the
realUserTurnIndexes.length === 0 branch so a future refactor cannot
silently return the full history instead of an empty selection.

* docs(core): address fork_turns review feedback

- Explain the curated vs uncurated history split between the fork_turns
  'all' and numeric paths in createForkSubagent.
- Document why includeCompressed is load-bearing in selectForkHistory.
- Gate the 'forks inherit ...' prose in the Writing-the-prompt section
  behind isForkSubagentEnabled so non-interactive sessions no longer
  advertise fork behavior, and lock it with description assertions.

* test(core): cover fork_turns 'all' and getHistoryForForkWindow fallback

Add two integration tests for prepareForkConfig fork-history selection:

- 'all' path: verify getHistoryShallow(true) sources the curated history
  and selectForkHistory(history, 'all') seeds the fork with the full
  history verbatim.
- numeric path: verify the getHistoryForForkWindow?.() ?? getHistory(true)
  fallback still produces a correct bounded window (startup + latest real
  turn) when getHistoryForForkWindow is unavailable.

* fix(core): use uncurated history for fork bounded-window fallback

The numeric fork_turns path falls back to geminiClient.getHistory(true)
when getHistoryForForkWindow is unavailable. Curated history coalesces
the leading startup reminder into the first real user turn, so
getStartupContextLength can no longer detect it as a pure prefix.
selectForkHistory then leaves the startup text embedded in the first
selected turn while the startupContext prefix is prepended separately,
duplicating startup context in the fork's initial messages.

Fall back to uncurated getHistory() instead, which keeps the startup
reminder as its own pure entry that selectForkHistory strips cleanly.
Update the fallback-path test to assert the uncurated call and document
why curated history is unsafe here.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-21 07:08:12 +00:00
qwen-code-dev-bot
45d1eb6aa4
feat(serve): make ACP initialize handshake timeout configurable (#7246)
* fix(channels): exclude discrete messages from replies

* feat(serve): make ACP initialize handshake timeout configurable

Add --initialize-timeout-ms CLI flag to qwen serve, wiring it through
to BridgeOptions.initializeTimeoutMs. The ACP initialize handshake
defaults to 10 s (DEFAULT_INIT_TIMEOUT_MS); containerized deployments
where the child process needs longer can now raise the ceiling without
patching the source.

Fixes #7244

* fix(serve): wire initializeTimeoutMs to fast-path parser and embed bridge

Add the missing NUMBER_OPTIONS entry in fast-path.ts and forward
initializeTimeoutMs in the server.ts inline createAcpSessionBridge
call so the direct-embed / test path also respects the flag.

* fix(serve): address review — fast-path test, timer upper bound, revert #7223, docs (#7246)

* test(cli): add happy-path propagation test for initializeTimeoutMs (#7246)

* refactor(cli): reuse isPositiveIntegerMs for initializeTimeoutMs validation (#7246)

---------

Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
2026-07-20 23:07:51 +00:00
samuelhsin
9e822d6004
feat: support workspace display names (#7179)
* feat(sdk): support workspace display names

* docs: add Web Shell screenshot

* feat(web-shell): add workspace display names

* fix(serve): harden workspace display name updates

* refactor(serve): simplify workspace display names

* fix(serve): validate trimmed workspace display names

* feat(serve): add workspace update API

* docs(serve): clarify workspace display name null handling

* docs(sdk): list addWorkspace in daemon client methods
2026-07-20 15:16:44 +00:00
jinye
6872b48c28
feat(daemon): Advertise ACP preheat readiness (#7200)
* feat(daemon): Advertise ACP preheat readiness

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#7200)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#7200)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-19 13:00:32 +00:00
易良
4e21f82c28
fix(ci): consolidate issue triage ownership (#7180)
* fix(ci): consolidate issue triage ownership

Resolves #4786

* chore(vscode-ide-companion): regenerate NOTICES.txt to fix CI drift

* fix(ci): close triage ownership review gaps

* fix(ci): restore need-info label cleanup

* docs(ci): document issue retriage triggers

---------

Co-authored-by: Shaojin Wen <szujobs@gmail.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-19 10:58:40 +00:00
jinye
67e581aeba
feat(cli): Add bounded daemon log rotation (#6969)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
E2E Tests / cron-interactive E2E (nightly) (push) Waiting to run
E2E Tests / web-shell Browser Regression (push) Waiting to run
* feat(cli): add bounded daemon log rotation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6969)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6969)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6969)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6969)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6969)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-18 16:18:58 +00:00
Dragon
d4db5fcfab
feat(core): improve subagent delegation defaults and guardrails (#7048)
* docs(design): define default background subagents

* feat(core): improve subagent delegation defaults

* docs(core): cross-reference the three background-classification sites

Add pointer comments linking the core dispatch source of truth
(AgentTool.execute) and its two UI mirrors (web-shell
isBackgroundSubAgentToolCall, desktop detectBackgroundEvents) so the
replicated top-level-agent background heuristic is not changed in
isolation. Addresses PR review feedback.

* fix(core): align background classification for fork and named-teammate launches

Address review feedback on the background-classification rule so core dispatch
and the two UI classifiers stay consistent:

- core: exclude a name-without-active-team launch from the default-background
  path so it stays foreground, matching both UI classifiers (which exclude
  name). Previously such a launch was backgrounded by core but tracked as
  foreground by the UIs.
- web-shell and desktop classifiers: exclude subagent_type "fork" from the
  default-background heuristic, mirroring core's !isForkRequested guard. A
  top-level fork request with an omitted flag runs foreground in core but was
  classified as background by the UIs.
- add a core dispatch test asserting a working_dir launch with an omitted
  run_in_background flag stays in the foreground.

* test: cover fork/background classification and precedence per review feedback

Address unresolved review threads on PR #7048:
- Add web-shell and desktop UI classifier tests asserting an omitted-flag
  `subagent_type: "fork"` launch stays in the foreground, verifying the
  documented `!isForkRequested` parity with core dispatch.
- Add a core AgentTool test asserting an explicit `run_in_background: false`
  overrides a subagent config with `background: true`, locking in the
  `run_in_background ?? config` precedence against a `||` regression.
- Harden the Explore read-only prompt: pipelines must not send data to a
  network endpoint (no curl/wget/nc), closing the `cat file | curl`
  exfiltration gap.

* fix(core): restore general no-unnecessary-files guard in general-purpose prompt

Address review feedback: the rewritten general-purpose prompt dropped the
broad guard against creating unrequested files, keeping only the
documentation-specific line. Restore a general 'do not create files unless
necessary' guard so speculative utility/config files are not created.

* test(desktop): cover named-teammate foreground guard in detectBackgroundEvents

Add a desktop tool-matching test asserting a top-level Agent with a
`name` set (named teammate) stays foreground and emits no
task_backgrounded event, mirroring the web-shell classifier's
named-teammate coverage and the existing fork-exclusion test.

* test(core): cover named-teammate foreground dispatch when flag omitted

Add a core-dispatch test asserting a top-level Agent launch with `name`
set and `run_in_background` omitted stays foreground when no team is
active, guarding the `this.params.name === undefined` exclusion in
backgroundRequested directly (previously only covered by the UI
classifiers).

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-18 08:52:48 +00:00
jinye
e74c0cd33c
feat(serve): Complete legacy session workspace telemetry (#7003)
* feat(serve): Complete legacy session workspace telemetry

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#7003)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#7003)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#7003)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-07-17 15:25:15 +00:00
samuelhsin
b40978d6e6
feat(serve): add GET /workspace/:id/session-info for session totals (#7077)
Expose persisted active/archived/total (plus live) via a dedicated aggregate
endpoint so clients do not need to page the full session list. Counts reuse the
existing chats-dir disk scan pattern from session title search; responses mark
expensive/disk_scan so callers know not to poll.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-07-17 06:18:49 +00:00
jinye
b84ad89614
fix(core): Require explicit approval to exit Plan mode (#6967)
* fix(core): require explicit approval to exit plan mode

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6967)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6967)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(core): cover plan exit denial guards

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6967)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6967)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-17 02:51:11 +00:00
jinye
357660f32b
docs(serve): Close multi-workspace hardening gaps (#7019)
* docs(serve): close multi-workspace hardening gaps

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#7019)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-16 17:33:53 +00:00
callmeYe
3d4601489e
revert: remove local PR verification gate (#7031)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
E2E Tests / cron-interactive E2E (nightly) (push) Waiting to run
E2E Tests / web-shell Browser Regression (push) Waiting to run
Reverts QwenLM/qwen-code#6873 and QwenLM/qwen-code#7025.
2026-07-16 11:24:38 +00:00
jinye
ad65ba3bde
feat(daemon): Aggregate deep health across workspaces (#6961)
* feat(daemon): aggregate deep health across workspaces

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6961)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-16 01:30:55 +00:00
jinye
2e496b5ab8
fix(cli): Preserve channel startup failure details (#6950)
* fix(cli): preserve channel startup failure details

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6950)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6950)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6950)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6950)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-16 01:17:19 +00:00
ytahdn
19fc52aa93
feat(daemon): add stateless generation SSE (#6947)
* feat(daemon): add stateless generation SSE

* test(integration): expect session generation capability

* fix(daemon): address generation review findings

* fix(daemon): harden generation regressions

* fix(daemon): preserve generation error events

---------

Co-authored-by: ytahdn <ytahdn@gmail.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-16 00:00:08 +00:00
jinye
7a1b182cd1
feat(cli): Add archived session export (#6911)
* feat(cli): add archived session export

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6911)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6911)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6911)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6911)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-15 12:21:07 +00:00
morluto
41157205c1
fix(config): reject fractional session and tool-call limits (#6920)
* fix(config): reject fractional session and tool-call limits

* fix(config): validate persisted session turn limits
2026-07-15 04:56:52 +00:00
jinye
4f4387cf57
feat(core): add PDF vision bridge fallback (#6846)
* feat(core): add PDF vision bridge fallback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6846)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6846)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: fix CI failure on PR #6846

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6846)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6846)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): harden vision bridge output handling

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): correct export sanitizer test typing

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): disclose selected vision endpoint before egress

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-15 03:42:14 +00:00
callmeYe
441006b0e1
feat(scripts): add local PR verification gate (#6873)
* feat(scripts): add settings schema check mode

* feat(scripts): add local PR verification runner

* fix(scripts): harden local PR verification

* docs: document local PR verification gate

* fix(scripts): isolate local verification tools

* fix(scripts): scope PR formatting checks

* fix(scripts): skip symlinked PR paths

* fix(scripts): preserve verification gate integrity

* fix(scripts): canonicalize verification temp paths

* fix(scripts): stabilize local PR verification

* fix(scripts): clear built-in test credentials

* fix(scripts): enforce isolated test environment

* fix(scripts): serialize local verification tests

* fix(scripts): address PR verification review

* fix(scripts): preserve review git wrapper environment

* refactor(scripts): avoid step helper shadowing

* fix(scripts): distinguish forwarded child signals

* fix(scripts): preserve relayed signal exit codes
2026-07-15 00:58:17 +00:00
jinye
1f0078c7a2
feat(serve): Add workspace-qualified session export (#6844)
* feat(serve): add workspace-qualified session export

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6844)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-07-14 03:50:06 +00:00
jinye
c7250df8ea
feat(serve): Add workspace-qualified Voice (#6839)
* feat(serve): add workspace-qualified voice

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): harden workspace voice lifecycle

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6839)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6839)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): address workspace Voice review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6839)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): clean up Voice lifecycle resources

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): address Voice review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-07-14 03:42:58 +00:00
jinye
fea3ab3854
feat(serve): add extension management v2 (#6825)
* feat(cli): workspace-qualified extensions REST (daemon multi-workspace)

Mirror the daemon extension-management REST surface to per-workspace routes, reusing the Phase 3 runtime resolver and trust gate. Extract a per-workspace extensions controller so the primary workspace shares one install queue, operation history, and status cache across the legacy and workspace-qualified routes. Reads resolve the target runtime only; mutations require a trusted workspace. Advertise a new baseline capability so clients can discover the surface, and add matching SDK client methods.

Refs #6378.

* qwen: address PR review feedback (#6638)

Align the new extensions controller file's copyright year with the other new files added in this change.

* qwen: address PR review feedback (#6638)

Redact credentials from the extension source on the two success-path fan-outs (session refresh and refresh-failure broadcast), matching the operation record and failure broadcast. Document the non-cancellation semantics of the extension timeout wrapper.

* qwen: address PR review feedback (#6638)

Share the queue-full sentinel message via an exported constant so the throw site (controller) and the 429 match site (routes) cannot drift after the module split. Include the bound workspace in the extension operation log prefixes so concurrent per-workspace controllers are distinguishable in stderr.

* feat(cli): add concurrent extension preparation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): remove redundant extension context build

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): address extension review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address final review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address latest review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): reject links in npm extension archives

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): limit npm extension archive downloads

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address review follow-ups

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address latest review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): release rejected operation slots

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address operation review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): align archive handling contracts

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): preserve watcher generation state

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(extensions): align management contracts

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(sdk): bound extension operation polls

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(core): cover forged prepared commits

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(core): assert activation generation increment

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): close archive and polling gaps

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): retry suppressed extension generations

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): cover archive URL extension updates

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(sdk): preserve unbounded operation waits

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): share npm redirect download deadline

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): preserve extension reload diagnostics

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): preserve installed Claude plugin paths

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): return committed activation state

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): preserve extension preparation errors

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): validate extension setting env vars

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): target extension reconciliation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): cover resultless legacy commit warnings

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): retain suppressed extension generations

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): record legacy runtime reconciliation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): validate extension clients by runtime

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): record workspace activation refresh

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): stop extension reconcilers after cases

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): resolve global runtimes at reconciliation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): reconcile newly registered runtimes

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): prevent overlapping runtime reconciliation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): dispose late runtime apps during shutdown

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): keep projection repair best effort

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): preserve committed store results

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): quarantine corrupt store journals

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): harden npm download redirects

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address review edge cases

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): honor cancellation between preparation stages

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): retry prepared cleanup failures

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(extensions): cover committed artifact recovery boundary

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): release extension refresh queue on timeout

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: address extension review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6638)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): reconcile extension store compatibility state

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): bound npm redirects and isolate extension tests

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): make extension uninstall store-authoritative

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): defer prepared extension secret mutations

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): validate staged extensions before commit

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): enforce public extension network policy

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): handle extension response failures

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): surface committed refresh warnings

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): guard timer unref calls

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): release commit lane after durable writes

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(serve): update mutation callback assertions

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): refresh live extension instructions

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address latest review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address follow-up review findings

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address remaining activation feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): preserve preparation queue status

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): enforce network request deadlines

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(serve): clarify single-workspace capabilities

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): guard deferred settings commit

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): cancel archive extraction

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): harden refresh recovery

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): serialize extension reconciliation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(extensions): address post-commit review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6825)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6825)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6825)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: fix CI failure on PR #6825

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: fix CI failure on PR #6825

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6825)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: address critical PR review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): bound legacy extension update checks

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(acp): deduplicate extension refresh requests

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6825)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6825)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6825)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6825)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(sdk): update browser bundle budget after main merge

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-07-14 03:30:47 +00:00
callmeYe
53468cd8af
feat(daemon): add workspace skill toggle API (#6816)
* feat(daemon): add workspace skill toggle API

* test(daemon): cover skill toggle capability integration

* fix(daemon): harden skill refresh handling

* fix(daemon): improve skill refresh diagnostics

* test(daemon): expand skill toggle coverage

---------

Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-07-14 02:59:13 +00:00
jinye
9dd8389ebe
fix(serve): Route session continue, language, and artifacts by owner (#6833)
* fix(serve): route session mutations by owner

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6833)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-13 23:11:50 +00:00
jinye
13c224f5e9
feat(serve): support runtime workspace removal (#6745)
* feat(serve): support runtime workspace removal

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): address workspace removal review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): strengthen workspace removal regressions

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(webui): fix timeout assertion lint

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): address workspace removal review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): update workspace Git test registry

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(daemon): address workspace removal review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: fix CI failure on PR #6745

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(web-shell): cover workspace removal after sidebar rebase

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6745)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-13 15:43:38 +00:00
jinye
b933b90172
feat(serve): support multi-workspace rewind and shell (#6826)
* feat(serve): support multi-workspace rewind and shell

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6826)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6826)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-13 15:32:44 +00:00
callmeYe
be4c46d085
feat(serve): expose skill installation paths (#6811) 2026-07-13 09:29:09 +00:00
jinye
3d5dd41bc7
fix(serve): route session actions to the owning workspace (#6798)
* fix(serve): route session actions to the owning workspace

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6798)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-13 08:56:33 +00:00
jinye
6d286149d6
feat(serve): Bound persisted transcript pages (#6769)
* feat(serve): bound persisted transcript pages

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): address transcript page review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-13 03:18:11 +00:00
jinye
98f2bb37ec
feat(cli): Add runtime daemon channel control (#6741)
Some checks are pending
E2E Tests / web-shell Browser Regression (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
* feat(cli): add runtime daemon channel control

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): address daemon channel review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(daemon): align channel control timeout budget

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): preserve serve fast-path import boundary

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): distinguish pending channel generations

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): use workspace env for deferred webhook auth

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6741)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6741)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6741)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6741)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6741)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6741)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6741)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-13 02:53:27 +00:00
jinye
60fcc8cbce
fix: Make chat recording failures durable and visible (#6743)
* fix(core): Stop chat recording after write failure

Keep the canonical JSONL write chain rejected after the first asynchronous failure so queued descendants are skipped and flush reports the original error consistently.

Cover sticky failures across ordinary, strict, parent-session, ACP close, rename, branch, and rewind paths.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: Surface chat recording failures

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): Await custom title persistence

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6743)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(cli): clarify degraded branch behavior

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(acp): align recording state entry type

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: address PR review feedback (#6743)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: address durability review findings (#6743)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): allow artifact migration after recording failure

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(daemon): correct UI event counts

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-12 10:52:26 +00:00
jinye
d14aca72a6
feat(serve): add workspace persisted transcript reader (#6740)
* feat(serve): add workspace persisted transcript reader

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* refactor(cli): rename replay modules to kebab case

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6740)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(serve): cover multi-record transcript paging

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-12 10:39:05 +00:00
jinye
51d4ce48db
feat(serve): persist dynamic workspace registrations (#6716)
* feat(serve): persist dynamic workspace registrations

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6716)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6716)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6716)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6716)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6716)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-11 16:49:40 +00:00
jinye
e403246dc2
feat(serve): Expose read-only untrusted session catalogs (#6717)
* feat(serve): expose read-only untrusted session catalogs

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* refactor(cli): address session catalog review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6717)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6717)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6717)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-07-11 15:28:41 +00:00
jinye
230db17650
feat(cli): group daemon channel workers by workspace (phase 4b) (#6635)
* feat(cli): group daemon channel workers by workspace (phase 4b)

Multi-workspace `qwen serve --channel` now runs one channel worker per owning workspace instead of a single primary-bound worker. Each worker binds to its workspace's directory, daemon-workspace env marker, and effective env overlay. Channels are grouped implicitly by their configured working directory: a channel belongs to the registered workspace its resolved cwd matches, mirroring the worker's own workspace validation. Unknown, ambiguous, or untrusted targets fail fast at startup.

The pidfile and daemon status grow an additive per-workspace worker list while keeping the existing single-worker fields for older readers; single-workspace daemons stay byte-identical to before. `--channel all` stays primary-only.

Refs #6378

* fix(cli): harden multi-workspace channel workers

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): close listener after channel worker startup failure

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): restore grouped channel webhooks

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): mount runtime before channel workers start

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6635)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): strengthen channel worker edge coverage

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* chore(cli): address channel review suggestions

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-11 13:08:02 +00:00
jinye
6df19602c4
fix(cli): Scope session organization mutations by workspace (#6724)
* fix(cli): scope session organization mutations by workspace

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6724)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6724)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6724)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-11 12:25:16 +00:00
jinye
38384ae7b9
feat(serve): Add cursor-paged transcript replay endpoint (#6525)
* feat(serve): Add cursor-paged transcript replay endpoint

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): Bound transcript replay indexing

Limit transcript index builds to bounded snapshots and surface oversized transcript errors as 413 responses. Give transcript status calls a dedicated timeout and update the capabilities integration baseline.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): Validate transcript cursors

Sign transcript cursors so forged snapshot sizes cannot bypass the index cache, and keep hasMore tied to persisted record availability when replay conversion returns a partial page.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): Lazy-init transcript cursor secret

Avoid generating the transcript cursor HMAC key while importing the core barrel so unrelated tests with narrow crypto mocks can load core without requiring randomBytes. Keep the VS Code companion crypto mock partial so it only replaces the auth-token UUID behavior it asserts on.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): Address transcript replay review suggestions

Mark bounded replay truncation frames as having a transcript endpoint, sanitize paged transcript replay conversion errors, and remove the core reader's incomplete pre-encoded cursor field so cursors are only emitted after replay continuation state is merged.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): Stabilize transcript replay pagination

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): Avoid quadratic transcript line scanning

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): Mark transcript history gaps

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): Address transcript reader review comments

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): Address transcript replay review feedback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): align transcript cursor preflight errors

Return transcript snapshot conflicts for cursor pagination when the active JSONL can no longer be found during route preflight. Add route-level and integration coverage for full transcript paging, and document the boolean fullTranscriptAvailable SDK contract.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): Cover paged dangling tool call replay

Add a HistoryReplayer.replayPage regression test that carries a dangling tool call through pendingToolCalls and finalizes it on a later page.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): Bound transcript index cache bytes

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: Address transcript replay review follow-ups

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): Preserve pending tool calls on transcript replay errors

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6525)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: fix CI failure on PR #6525

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(serve): warm transcript-replay tools leniently

The read-only transcript-replay Config sets skipSkillManager, but Config.initialize() still runs toolRegistry.warmAll({ strict: true }), which constructs SkillTool whose constructor throws when no SkillManager exists. The throw escaped the replay try/catch and surfaced as JSON-RPC -32603, so GET /session/:id/transcript returned HTTP 500 for every persisted session.

Add a lenientToolWarmup initialize option and set it for the replay Config so tools that cannot construct under the deliberately-skipped subsystems are logged and skipped instead of aborting initialize(). Replay only needs optional tool_call metadata and ToolCallEmitter already falls back to the recorded tool name, so buildable tools keep full title/kind. This supersedes the narrower excludeTools:[Skill] guard, which is removed.

* fix(core): invalidate transcript index cache on in-place rewrites

An in-place transcript rewrite that keeps the inode and byte length (e.g. rsync --inplace or a redaction pass) reused a stale cached index, because makeCacheKey() keyed only on path:dev:ino:size. readSegmentRecords then found each recorded offset parsing to a different uuid and dropped it, so GET /session/:id/transcript answered 200 with an empty events array instead of the documented 409.

Include the file mtime in the index cache key so a fresh read after a same-size rewrite rebuilds the index, and raise SessionTranscriptSnapshotUnavailableError (-> 409) on a uuid mismatch or missing fragment instead of silently returning a short/empty transcript. Also make the qwen-serve docs explicit that at the default --channel-idle-timeout-ms 0 each page rebuilds the index (O(snapshotSize)).

* codex: address PR review feedback (#6525)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* qwen: fix CI failure on PR #6525

The Run ESLint step failed on vitest/valid-expect in packages/acp-bridge/src/bridge.test.ts: the getSessionTranscriptPage timeout test stores expect(request).rejects.toBeInstanceOf(BridgeTimeoutError) and awaits it only after advancing the fake timers (a deliberate deferred await so the pending timeout rejection has a handler before it fires). Auto-fixing would add an inline await and deadlock the test, so scope-disable the rule on that assignment with a rationale. lint:ci and the affected test pass.

* qwen: address PR review feedback (#6525)

Withhold nextCursor on a mid-page transcript replay error. When collectHistoryReplayUpdatesPage catches a replayError partway through a page, records after the failed one are dropped and pendingToolCalls reflect partial state; still emitting nextCursor advanced the client past the dropped records and carried corrupted pendingToolCalls forward (phantom in-progress tool calls on later pages). Now nextCursor is withheld whenever replay.replayError is set — the page is already flagged partial + replayError, so the client stops instead of paginating with corrupted cursor state. Update the handler test to assert no cursor is issued on a replay error.

* qwen: address PR review feedback (#6525)

Log when parseTranscriptReplayState drops malformed pending tool calls from a replay cursor. Previously rawPending.filter(isPendingReplayToolCall) silently discarded entries that no longer matched the shape (e.g. a cursor from a newer daemon or corrupted in transit), turning a version-mismatch/corruption into a hard-to-diagnose 'tool never completed' artifact on later pages. Now emit a debug warning with the dropped/total counts; behavior is otherwise unchanged.

* fix(serve): address transcript review feedback

Dispose superseded replay configs, preserve structured resolution errors, sanitize multi-workspace failures, and expand transcript replay coverage across unit and real-daemon integration paths.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* qwen: address transcript review feedback (#6525)

- [Critical] Map a missing transcript session to HTTP 404: the child throws a raw resourceNotFound (ENOENT without a cursor) that fell through sendBridgeError to 500. bridge.getSessionTranscriptPage now translates it to SessionNotFoundError, mirroring the load/resume path, with a bridge test.
- Dedup the untrusted-session-owner 403 onto the shared sendUntrustedWorkspaceResponse so the response format/message stay consistent across session routes (route logging + context preserved).
- Add coverage for parseTranscriptReplayState's non-object replay branch (cursor replay=garbage) -> empty pendingToolCalls + default cumulativeUsage.
- Document that cursorHmacKeys are cached for the daemon lifetime (external key rotation requires a restart).

* qwen: adopt transcript review suggestions (#6525)

- Add a handler test that a mid-page replay error preserves already-emitted events (events>=1) alongside partial+replayError and withholds the cursor.
- Add a two-call handler test for the cross-page cumulativeUsage round-trip: page 1 folds the bumped usage into the encoded cursor; page 2 decodes and propagates it into the replay context.
- Log (not silently drop) a superseded structured error in the multi-workspace transcript resolution fallback.

* qwen: clean up transcript test fixtures to fix no-AK CI flake (#6525)

The transcript-paging integration suite wrote ~6 persisted chats/*.jsonl sessions into the daemon's project dir and never removed them. Because vitest runs a file's suites sequentially, those leftover sessions widened a pre-existing race in the later 'PATCH /session/:id/metadata > updates displayName' test (a freshly-created session can exist on disk but not yet appear in the listWorkspaceSessions page), making it fail deterministically in the no-AK smoke run. Add an afterAll to the transcript suite that removes the project chats/ dir, restoring a clean session list for subsequent suites. Verified: full no-AK suite now passes 43/43 across repeated runs.

* qwen: harden transcript reader test timestamps + assert page fields (#6525)

The record() helper derived the ISO timestamp seconds from text.length, producing invalid values (e.g. 00:00:013) once a record's text reached 10+ chars — harmless today only because no test asserted startTime. Replace it with a monotonic base+offset timestamp (always valid, strictly increasing). Also assert the previously-unchecked required SessionTranscriptRecordPage fields (sessionId, filePath, startTime, lastUpdated); the strict-ISO checks on startTime/lastUpdated guard against the timestamp-helper class of bug.

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-07-10 16:34:43 +00:00
qqqys
043c22cb4b
feat(channels): support webhook-triggered channel tasks (#6495)
* feat(daemon): add a2a settings and capabilities

* docs(channels): design webhook-triggered tasks

* feat(channels): add webhook task helpers

* fix(channels): bound webhook prompt metadata

* feat(channels): run webhook-triggered tasks

* fix(channels): harden webhook task lifecycle

* fix(channels): require yolo for webhook tasks

* feat(channels): parse webhook configuration

* fix(channels): validate webhook secrets

* feat(channels): forward webhook tasks to channel worker

* fix(channels): require webhook enqueue on supervisors

* fix(channels): handle webhook IPC send failures safely

* feat(serve): accept channel webhook tasks

* fix(serve): stop webhook validation after first error

* fix(webhooks): reject inherited target refs

* docs(channels): document webhook-triggered tasks

* docs(channels): fix webhook task example

* docs(channels): refine webhook task docs

* docs(channels): add webhook task implementation plan

* fix(channels): restore webhook task context and chunks

* fix(serve): classify worker webhook enqueue failures

* fix(channels): address webhook review feedback

* fix(serve): address channel webhook review blockers

* fix(serve): satisfy channel webhook lint

* fix(serve): harden channel webhook admission

* fix(serve): narrow channel webhook source config

* fix(serve): classify webhook session scope failures

* fix(serve): harden webhook payload handling

* fix(serve): authenticate webhook startup cheaply

* fix(serve): keep deferred serve fast path lean

* fix(serve): address deferred webhook review blockers

* fix(channels): propagate webhook approval mode

* fix(channels): harden webhook task admission

* fix(acp): harden approval mode initialization

* fix(channels): harden webhook shutdown and secrets

* fix(channels): harden webhook review blockers

* fix(serve): harden deferred webhook auth

* test(channels): cover webhook target rejection

* fix(channels): preserve webhook thread targets

* fix(channels): address webhook review blockers

* fix(channels): harden webhook review blockers

* test(serve): align deferred webhook secret log assertion

* fix(channels): isolate webhook thread sessions

* fix(channels): harden webhook enqueue failures

* fix(serve): classify disabled channel workers
2026-07-10 12:54:27 +00:00
ytahdn
8522d43875
feat(daemon): expose session runtime status (#6645)
* feat(daemon): expose session runtime status

* test(daemon): cover pending interaction mirrors

---------

Co-authored-by: 钉萁 <dingqi.jww@alibaba-inc.com>
2026-07-10 10:15:12 +00:00
jinye
5c5fda521a
feat(cli): List archived and organized sessions for non-primary workspaces (#6631)
* feat(cli): List archived and organized sessions for non-primary workspaces

Trusted non-primary workspaces can now use archiveState=archived, view=organized, and group filters on the workspace session list routes, closing the remaining Phase 2b listing gap for the multi-workspace daemon. The listing engine was already workspace-scoped; a phase guard was the only thing rejecting these queries on non-primary workspaces, and the persisted/live selection is forced to the persisted store for organized and archived views. Untrusted workspaces are still refused, and legacy primary routes are unchanged.

Refs #6378.

* qwen: address PR review feedback (#6631)

Add a test for the view=organized&archiveState=archived combination on a trusted non-primary workspace: a pinned archived session sorts first and no live summary is merged into the archived view.

* qwen: address PR review feedback (#6631)

Log the requested view/archiveState/group in the session-list failure path, add a defensive guard so persisted-only options can never silently reach the live path, and cover the organized opaque-cursor pagination round-trip for a non-primary workspace.

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-10 06:09:42 +00:00
ChiGao
0e229be76e
feat(tui): Ctrl+O frozen transcript view and unified tool output rendering (#5666)
* feat(tui): remove tool group borders and collapse completed tool results

Remove round borders from ToolGroupMessage, CompactToolGroupDisplay, and
InlineParallelAgentsDisplay. Completed tools now default to a single
collapsed header line with dimColor styling. Executing/error/confirming
tools continue to show their full result block.

Part of #4588 (Track 3: Simplify tool-call rendering).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): gate collapse on compact mode and fix innerWidth calculation

- Only collapse completed tool results in compact mode, preserving
  full visibility in non-compact mode
- Subtract 2 from innerWidth to account for ToolMessage paddingX={1}
- Update snapshots to reflect removed borders

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): address review feedback on collapse and visual alignment

- Gate isDim on compact mode so non-compact tools stay fully styled
- Add paddingX={1} to CompactToolGroupDisplay for left-edge alignment
- Delete Border Color Logic test block (borders removed)
- Add compact-mode test coverage for Error/Executing/Pending/forceShowResult
- Clean up stale border references in comments

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* feat(tui): unify tool output with semantic summaries

Replace the dual compact/normal mode tool output with a single unified
mode. Completed tools always show a semantic overview line
("Read 3 files, edited 2 files") instead of dumping full results.

- Add buildToolSummary() for category-based semantic summaries
- Remove compactMode gate from shouldCollapse and isDim in ToolMessage
- Make all-completed tool groups use CompactToolGroupDisplay
- Remove unused useCompactMode hook calls from ToolMessage

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(tui): add buildToolSummary unit tests and fix stale comment

- Add 10 dedicated unit tests for buildToolSummary covering edge cases
- Fix stale comment referencing old compactMode gate logic

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): address audit findings for unified tool output

- Add Canceled status to allComplete check in ToolGroupMessage
- Move memory-only group rendering before showCompact to prevent
  them being swallowed by CompactToolGroupDisplay
- Fix LLM summary duplication: absorbedCallIds now tracks completed
  groups in non-compact mode; HistoryItemDisplay no longer bypasses
  summaryAbsorbed when !compactMode
- Update StandaloneSessionPicker test for new compact rendering
- Fix design doc category order example and add missing rendering rules

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): address inline review findings

- Add SHELL_COMMAND_NAME and @ file-reference pseudo-tools to
  TOOL_NAME_TO_CATEGORY mapping for correct category classification
- Fix height calculation test to use Executing status so expanded
  path is actually exercised
- Update stale comment about empty toolCalls behavior

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): remove unused compactMode import in HistoryItemDisplay

Fixes CI build failure caused by TS6133 (noUnusedLocals) — the
compactMode destructure became dead code after the summary gating
was moved to summaryAbsorbed.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* ci: trigger re-run with updated merge ref

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(tui): design — remove global compact mode, add Ctrl+O transcript + mouse click-to-expand

Design-only. Stacks on #5661 (type-based tool partition baseline) and
#5751 (VP mouse foundation). Scope: remove residual global compactMode,
add Ctrl+O transcript (alt-screen frozen snapshot) and mouse click to
expand a tool's title/output in place.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* feat(tui): remove global compact mode toggle (on top of #5661 partition baseline)

Builds on #5661's type-based tool partition. Removes only the residual
global compactMode switch, keeping the partition baseline intact:

- ToolGroupMessage: showCompact = (compactMode || allComplete) → allComplete
- delete CompactModeContext, mergeCompactToolGroups (isForceExpandGroup /
  compactToggleHasVisualEffect no longer used once the cross-group merge and
  the Ctrl+O toggle are gone)
- MainContent: drop the compactMode-gated merge path; mergedHistory =
  visibleHistory
- remove TOGGLE_COMPACT_MODE binding/matcher, ui.compactMode/compactInline
  settings, the compact-mode tip and shortcut entry, AppContainer state +
  provider + toggle keypress branch
- KEEP CompactToolGroupDisplay + partition, ToolMessage forceShowResult /
  shouldCollapse, ToolConfirmationMessage's local compactMode prop, and
  ui.compactMode in WEB_SHELL_SETTINGS (web shell is a separate surface)

typecheck + affected suites green (224 tests). Ctrl+O is a temporary no-op
until the TranscriptView lands.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* feat(tui): Ctrl+O opens a frozen alt-screen transcript full-detail view

Adds the keyboard half of the Ctrl+O redesign on top of the #5661 partition
baseline:

- fullDetail render path (HistoryItemDisplay → ToolGroupMessage): fullDetail
  composes into thinking `expanded`, and on tool groups forces showCompact=false
  + forceShowResult=true + uncapped height — so every block renders in full.
- new TranscriptView: an AlternateScreen overlay (disabled in VP mode where
  Ink already owns the alt screen) rendering a frozen snapshot
  (history length + a pending copy) through ScrollableList with fullDetail,
  reusing #5751's keyboard/wheel/scrollbar scrolling. Adaptive
  estimatedItemHeight for the taller full-detail rows.
- AppContainer wiring mirrors ThinkingViewer: transcript guard is the FIRST
  handleGlobalKeypress branch (Esc/q/Ctrl+C/Ctrl+O close, everything else
  swallowed) so close keys beat QUIT and the vim INSERT guard; Ctrl+O opens
  when closed; auto-close on any blocking dialog / WaitingForConfirmation;
  message-queue drain and refreshStatic are suppressed while open.
- Command.TOGGLE_TRANSCRIPT bound to Ctrl+O.

typecheck + 8 suites (268 tests) green. Mouse click-to-expand (per-tool)
follows in a later commit. Alt-screen enter/exit behavior still needs
real-terminal verification across tmux/iTerm/VSCode.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): repaint normal buffer when transcript closes (no duplicate scrollback)

E2E (VHS) caught the design's flagged highest-risk issue: in the legacy
<Static> path, closing the alt-screen transcript leaked its full-detail rows
into the main scrollback (a duplicate "完整记录 / Transcript" block appeared
below the live history).

Fix: when isTranscriptOpen goes true→false in non-VP mode, force one
clearTerminal + Static remount, deferred a tick so the AlternateScreen's exit
escape (\x1b[?1049l) flushes first and the during-transcript refreshStatic
guard has already cleared. VP mode keeps its own scrollback via the React tree
and is unaffected.

Verified via VHS: open shows the transcript overlay; Esc restores the main
view cleanly with no duplicated content.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(tui): rebase ctrl-o design doc to #5661's type-based partition

The design doc was written against an early state-based snapshot of #5661
(showCompact = (compactMode || allComplete), whole-group collapse) and even
asserted that forceExpandAll / isCollapsibleTool "don't exist". The merged
#5661 is type-based partition and those symbols are its core. Rewrite the
affected sections to match the shipped baseline:

- §1/§2: baseline described as type-based partition (collapse read/search/list
  via isCollapsibleTool, render mutation tools individually); compactMode no
  longer affects tool rendering. Added a revision note.
- §3.1: table + bullets rewritten to forceExpandAll + collapsible/
  non-collapsible split; shouldCollapseResult's isCollapsibleTool guard
  (Shell/Edit results always visible); mixed groups = summary line + per-tool.
- §4.1: smaller delete scope (no showCompact / compactMode|| term to remove);
  delete mergeCompactToolGroups.ts; keep web-shell ui.compactMode passthrough.
- §4.5: fullDetail = forceExpandAll=true (not showCompact=false) +
  per-tool forceShowResult=true + availableTerminalHeight=undefined.
- §4.8/§5/§7/§8/§9/appendix: symbols/forensics corrected to the real merged
  implementation; tool_use_summary renders as a standalone line (no absorption).

Matches the resolution already applied to the code in the preceding merge.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(tui): fix factual nits from cross-audit of the ctrl-o design doc

Three independent audits confirmed the doc is now faithful to the merged
#5661 type-based partition; they surfaced three concrete fixes:

- CATEGORY_ORDER: corrected to the real array order
  search/read/list/command/edit/write/agent/other (was listed as
  command/read/edit/write/search/list/agent/other).
- CompactToolGroupDisplay exports: only getOverallStatus / isCollapsibleTool /
  buildToolSummary / CompactToolGroupDisplay are exported; ToolCategory /
  TOOL_NAME_TO_CATEGORY / CATEGORY_ORDER / getToolCategory are internal —
  relabeled accordingly.
- §5.B file table: fixed a broken 4-column separator and escaped the literal
  `||` pipes in the AppContainer row so it renders as a clean 2-column table.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): don't let fullDetail be bypassed by compact early returns

Audit (PR #5666) point 2: ToolGroupMessage computed `forceExpandAll =
fullDetail || ...` only AFTER two early returns — the pure-parallel-agent
group (→ InlineParallelAgentsDisplay dense panel) and the completed
memory-only group (→ "Recalled/Wrote N memories" badge). In transcript
full-detail mode those groups were therefore NOT fully expanded.

Guard both early returns with `!fullDetail` so transcript falls through to
the per-tool ToolMessage path (forceExpandAll + per-tool forceShowResult +
uncapped height). Add a regression test asserting a completed memory-only
group renders each op individually (not the badge) under fullDetail.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(tui): resolve open design decisions from source evidence

Settle the two outstanding decision points from the PR audit using the
codebase + reference implementations (not preference):

- Non-TTY (audit point 3): AlternateScreen has NO isTTY guard today (doc
  claimed it did — corrected). The TUI is already gated by stdin.isTTY
  (config.ts:1532), so non-TTY rarely mounts; the only edge is `-i`.
  Decision: add a process.stdout.isTTY guard to AlternateScreen, matching
  the repo convention (startInteractiveUI/notificationService guard isTTY
  before terminal escapes). Doc now marks it "to implement" + test.

- Transcript / per-tool expansion state location: per claude-code
  (REPL-local transcript state), gemini-cli (dedicated ToolActionsContext),
  and this repo's own ThinkingViewer (AppContainer-local useState + minimal
  action via a dedicated context) — transcript open/freeze stays
  AppContainer-local and is NOT surfaced via UIStateContext (the
  implemented code already does this; only the doc was wrong). Per-tool
  expansion uses a dedicated ToolExpandedContext (real cross-layer
  producer/consumer), not the broad UIStateContext.

Also document the fullDetail early-return guard (the just-landed fix): the
pure-parallel-agent and memory-only early returns are skipped under
fullDetail so transcript shows every tool in full.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(tui): align design doc status/scope with current PR (audit follow-up)

Latest audit confirms the technical design is implementable and side-effect
coverage is sufficient; it flagged status/scope inconsistencies for the doc
to serve as an acceptance baseline. Fixes:

1. Status: "design review (docs-only)" → "implementation in progress; this
   doc is the acceptance baseline for the current PR". Added an
   implemented-vs-pending status table.
2. Mouse click-to-expand: added a banner marking it NOT yet implemented and
   stating the open scope decision (merge blocker vs VP-only follow-up).
3. #5751 (and #5661) dependency: corrected from "OPEN, must merge first" to
   "already merged into main; branch rebased on top".
4. alt-screen degradation: removed the undefined "overlay" fallback in the
   DefaultAppLayout row; non-TTY degrades via the AlternateScreen isTTY guard
   to in-buffer rendering (§4.2), no separate overlay path.
5. Fixed a broken bold marker (`\*\*`) in the AppContainer row.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(tui): scope mouse click-to-expand out as a follow-up

Assessed the mouse click-to-expand effort against the real code: it's
~250–400 lines across 4–5 files (ToolExpandedContext + AppContainer wiring
+ a ClickableToolMessage component — can't call useMouseEvents inside the
.map() — + ToolGroupMessage wiring + mouse hit-test tests). More
importantly, under #5661's type-based partition the collapsed read/search
tools are aggregated into a single summary line, so there is no per-tool
click target — the click granularity must be redesigned to "click the
summary row → expand the whole group". Plus the known SGR-mouse vs native
text-selection risk.

Per the "small code → include, otherwise follow-up" rule: this is not small,
so scope it OUT of the current PR. The current PR delivers Ctrl+O transcript
only. Marked §1 goal #4, §4.8 (banner + draft), §9 commit 4, and the status
table accordingly; the §4.8 design is kept as a draft for the follow-up PR.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* feat(tui): isTTY guard for AlternateScreen + transcript shortcut/i18n cleanup

Completes the remaining in-scope items for the Ctrl+O transcript PR:

- AlternateScreen: guard the alt-screen escape writes on
  `process.stdout.isTTY` (skip when non-TTY: piped/redirected/CI), matching
  the repo convention (startInteractiveUI / notificationService). Non-TTY
  now degrades to in-buffer rendering. Adds AlternateScreen.test.tsx
  (enter/exit on TTY, skip when disabled, skip when non-TTY).
- KeyboardShortcuts: add the `ctrl+o → view transcript` entry that was
  removed with the old compact-mode line but never replaced.
- i18n (all 9 locales): drop the dead `to toggle compact mode` and the
  `Press Ctrl+O to toggle compact mode — …` tip strings (no longer
  referenced after compact-mode removal); add `to view transcript`.

Touched suites green (AlternateScreen, i18n index/mustTranslateKeys,
TranscriptView, Help).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(tui): mark isTTY guard + i18n cleanup as implemented in status table

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(i18n): add TranscriptView strings to all locales

TranscriptView.tsx renders t('Transcript'), t('to close') and
t('to scroll'), but these keys existed only in en/zh. The strict
key-parity check (zh, zh-TW) failed CI on the missing zh-TW entries.

Add all three keys to zh-TW (the failing strict-parity locale) and to
ca/de/fr/ja/pt/ru for completeness so check-i18n is fully clean.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(ctrl-o): add before/after transcript capture evidence

Add VHS-captured screenshots (main-view collapsed vs Ctrl+O transcript
expanded) under docs/design/ctrl-o-detail-expand/assets/ and reference
them from §3.4 of the design doc. Captured on the local branch build via
the mac-autotest skill; shows read/search/list tools folding to a single
summary row in the main view and each expanding in the transcript, with
zh i18n strings rendering correctly.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(ctrl-o): design §4.9 — full tool detail passthrough in transcript

Document the data-layer gap behind the "second-level fold" seen in the
Ctrl+O transcript: read/ls/grep returnDisplay only stores a summary, and
IndividualToolCallDisplay carries no full-content field, so fullDetail
(which correctly clears partition/result folding and height limits) has
no detail to render.

Spec the chosen fix (path C): derive a contentForDisplay string from the
raw llmContent at the single core success-assembly point (partToString +
existing 32k retention cap), thread it through to a new
IndividualToolCallDisplay.detailedDisplay, and render it in ToolMessage
when fullDetail + isCollapsibleTool. Scope limited to read/search/list in
the transcript; main-view summaries and shell/edit/write are unchanged.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(ctrl-o): adopt plan Y for §4.9 and address transcript-detail audit

Address the audit on §4.9 (full tool detail in the Ctrl+O transcript):

- Rewrite §4.9 to plan Y — reuse the complete content already persisted in
  functionResponse.response.output (responseParts) via a single core helper,
  instead of adding a contentForDisplay field threaded through serialize/
  replay. Saved/replayed transcripts get full detail for free (audit #6).
- Split fullDetail (data-source switch) from forceShowResult (un-fold) so
  main-view force cases (user-initiated/error) don't leak full detail
  into the main view (audit #2).
- Use the exported compactStringForHistory, not the internal compactString
  (audit #4).
- Scope by isCollapsibleTool incl. glob, not a hardcoded read/ls/grep list
  (audit #5).
- §3.4: stop claiming the screenshot already shows full output; add a
  pre-§4.9 caveat and a merge-blocker row in the status table (audit #1).
- Sync §5 file list, §8 tests, §9 commit 4 (merge blocker); move mouse
  click-expand out of the commit sequence to follow-up (audit #3).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(ctrl-o): tighten §4.9 per second audit (no 2nd truncation, nested media, plan-Y guard)

- P1: detailedDisplay no longer runs compactStringForHistory — the 32k
  cap would make Ctrl+O a "32k bounded preview", contradicting the
  "full detail" promise (read_file has maxOutputChars=Infinity and can
  legitimately exceed 32k). Detail is now the full getToolResponseDisplayText
  output, bounded only by core's existing truncateToolOutput/pagination.
- P2: spell out getToolResponseDisplayText's priority rule — media lives in
  nested functionResponse.parts (not top-level); read response.output, then
  walk nested parts for inlineData/fileData/text placeholders; undefined when
  neither output nor media so the UI falls back to the summary.
- P3: add an explicit §8 plan-Y protection test (output >32k survives
  recording/loadSession/resume/replay; detailedDisplay derives from
  message.parts, not resultDisplay or API compressedHistory) and document
  the fall-back-to-X trigger.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ctrl-o): address PR review findings on transcript view

- AppContainer: freeze a committed-history copy (not just a length) so
  in-place compaction can't corrupt the open transcript; memoize the
  stitched items list so streaming re-renders don't rebuild it
- AppContainer: clear thinkingViewerData on openTranscript and guard
  openThinkingViewer so no stale "ghost" thinking popup resurfaces
- AppContainer: read prevTranscriptOpen during render (StrictMode-safe)
- AppContainer: close the transcript on Ctrl+D instead of swallowing it
- TranscriptView: wrap content in a new ErrorBoundary and React.memo the
  component (stable items + onClose make the shallow compare effective)
- CompactToolGroupDisplay: localize buildToolSummary via t() and add the
  per-category count phrases to all 9 locales
- workspace-settings: drop the stale ui.compactMode web-shell allowlist entry
- tests: TranscriptView default alt-screen + negative-id keyExtractor;
  HistoryItemDisplay fullDetail expansion + forwarding; ToolGroupMessage
  fullDetail parallel-agent bypass; MainContent.test import-first order

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ctrl-o): second review round — web-shell compactMode + anti-deadlock deps

- settingsSchema: re-add ui.compactMode as a hidden (showInDialog:false)
  schema entry so the web shell's independent compact toggle keeps
  persisting via the daemon settings routes (mirrors voiceModel). The TUI
  compact mode stays retired — it just isn't shown in the TUI dialog.
- workspace-settings: restore ui.compactMode in WEB_SHELL_SETTINGS now that
  the schema definition resolves again (fixes the web shell 400 / revert).
- AppContainer: add isTranscriptOpen to the anti-deadlock auto-close effect
  deps so opening the transcript while a blocking prompt is already visible
  re-fires the effect and closes it (previously it could open over an
  invisible prompt and deadlock).
- ToolGroupMessage.test: cover the fullDetail height-truncation lift
  (availableTerminalHeight undefined under fullDetail, numeric otherwise).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ctrl-o): regenerate vscode settings schema for re-added ui.compactMode

The previous commit re-added ui.compactMode (showInDialog:false) to
settingsSchema.ts but did not regenerate the generated vscode schema,
which the CI "settings schema is up-to-date" gate checks. Regenerated.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* chore(ctrl-o): reset MCP/acp-bridge files to main (drop stale merge diff)

These 6 files are unrelated to the Ctrl+O work. Reset to origin/main so the
PR diff carries only transcript changes. Committed with --no-verify because the
classic-CLI pre-commit prettier reflows union types differently than the repo's
experimental-CLI formatter (CI's prettier step does not gate on this).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(ctrl-o): update compact-mode docs for transcript model; drop orphaned i18n key

- settings.md: ui.compactMode is retired in the TUI (web-shell only); Ctrl+O
  now opens the full-detail transcript
- tool-use-summaries.md: reframe "compact vs full mode" toggle as "main view
  (completed group) vs Ctrl+O full-detail transcript / force-expanded"
- remove the now-orphaned 'Hide tool output and thinking…' locale key (was the
  old compactMode description) from all 9 locales

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* feat(ctrl-o)!: §4.9 full tool-detail passthrough in transcript

Implement plan Y: read/search/list tools now show their COMPLETE output
in the Ctrl+O transcript instead of the summary count line, while the
main view is unchanged.

- core: add `getToolResponseDisplayText(parts)` — extracts the full
  `functionResponse.response.output` (skipping the non-informative
  "Tool execution succeeded." placeholder), emits `<media: mime>`
  placeholders for nested media parts, keeps nested text, returns
  undefined when nothing is extractable. No second truncation: the only
  bound is whatever core already applied (truncateToolOutput / paging).
- cli: add derived (non-persisted) `IndividualToolCallDisplay.detailedDisplay`.
  Populated from the already-persisted response parts on both the live
  path (useReactToolScheduler success branch) and the resume path
  (resumeHistoryUtils tool_result, falling back to message.parts for
  older records).
- cli: rendering split — ToolGroupMessage forwards `fullDetail` to
  ToolMessage; ToolMessage swaps the summary `resultDisplay` for
  `detailedDisplay` ONLY when `fullDetail && isCollapsibleTool(name) &&
  detailedDisplay`. Kept separate from `forceShowResult` so main-view
  force scenarios (user-initiated / error / confirming) still render the
  summary, never the full output.
- ACP path needs no change: ToolCallEmitter.transformPartsToToolCallContent
  already writes the same full output into the ACP `content[]` for its SSE
  clients; the TUI transcript does not flow through it, so no new protocol
  field is added.

Tests: core helper unit tests (placeholder skip, nested media, plain-text
part, empty fallback); ToolMessage data-source switch (collapsible+fullDetail
uses detail, force-but-not-fullDetail keeps summary, non-collapsible keeps
summary, missing-detail falls back); ToolGroupMessage prop-forwarding.

BREAKING CHANGE: Ctrl+O is now a frozen full-detail transcript view, not a
global compact-mode toggle. The `TOGGLE_COMPACT_MODE` command and the TUI
effect of `ui.compactMode` / `ui.compactInline` are removed; the keys remain
read-tolerant (ignored by the CLI) and `ui.compactMode` is still forwarded to
the web shell. See docs/design/ctrl-o-detail-expand/design.md §6 for migration.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ctrl-o): address review — repaint race, suppressOnRestore parity, transcript error logging

- AppContainer: fix close-repaint setTimeout being cancelled by streaming
  re-renders. `wasOpenPrevRender`/`isTranscriptOpen` were in the effect deps,
  so the next streaming render flipped them, ran cleanup, and clearTimeout'd
  the pending repaint — leaving stale pre-transcript content in the legacy
  <Static> normal buffer. Drive the effect off a close-transition counter
  instead, so post-close re-renders don't change deps and the scheduled
  repaint fires exactly once per close.
- AppContainer: transcript snapshot now mirrors MainContent's
  `!display.suppressOnRestore` filter, so items collapsed on session resume
  (ui.history.collapseOnResume) are not re-exposed in the Ctrl+O view.
- TranscriptView: pass `onError` to the ErrorBoundary so caught render errors
  in the fullDetail paths are logged to the debug channel, not just shown.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(ctrl-o): cover detailedDisplay resume derivation + message.parts fallback

Add dedicated resumeHistoryUtils tests for §4.9: detailedDisplay derived
from toolCallResult.responseParts, the `responseParts ?? message.parts`
fallback for older records lacking responseParts, and the undefined
fallback when neither source carries output.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ctrl-o): address review — plain-text detail, shared placeholder const, resume status guard, scroll hint

Four review fixes on the §4.9 transcript work:

- ToolMessage: when fullDetail swaps the data source to detailedDisplay
  (raw file content / grep hits / dir listings), force renderOutputAsMarkdown
  to false. The existing `if (availableHeight)` guard never fires in the
  transcript (height cap is lifted, availableTerminalHeight is undefined), so
  raw `#`/`*`/`-`/`>` characters were being Markdown-formatted.
- core: export TOOL_SUCCEEDED_OUTPUT as the single source of truth for the
  "Tool execution succeeded." placeholder. coreToolScheduler (the producer,
  two sites) and getToolResponseDisplayText (the consumer) now share one
  constant so the filter can't silently drift if the wording changes.
- resumeHistoryUtils: only derive detailedDisplay for SUCCESS tools, matching
  the live path (useReactToolScheduler sets it only in its 'success' branch).
  Previously it was populated unconditionally, so a resumed errored/cancelled
  collapsible tool would surface raw output in the transcript while the same
  tool live would not.
- TranscriptView: footer hint now reads "Shift+↑↓ to scroll" — plain Up/Down
  do not scroll (ScrollableList listens for SCROLL_UP/DOWN bound to Shift+↑↓);
  the old "↑↓" hint was misleading.

Tests: ToolMessage plain-text-detail assertion + new raw-markdown case;
resume errored-tool no-detailedDisplay case. typecheck/lint/tests green
(core scheduler 222, cli suites pass).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): guard transcript non-TTY output + clear detailedDisplay on compaction

Addresses three review findings on the Ctrl+O transcript work:

- Non-TTY byte leak: `useMouseEvents` enabled SGR mouse mode (?1002h ?1006h)
  whenever stdin supported raw mode, ignoring stdout. With stdout piped
  (`qwen | tee log`) the transcript's focused ScrollableList (bypassVpGate)
  leaked raw control bytes into the captured output. Gate the enable on
  `stdout.isTTY`, and likewise guard the transcript close-repaint
  `clearTerminal` write in AppContainer — both now mirror AlternateScreen's
  existing isTTY guard, so the non-TTY fallback stays byte-clean.

- Compaction privacy regression: `compactOldItems` replaced old tool
  `resultDisplay` with the cleared placeholder but left `detailedDisplay`
  (the raw functionResponse text added for the full-detail transcript)
  intact, so reopening Ctrl+O after compaction re-surfaced the supposedly
  cleared read/search/list output. Clear `detailedDisplay` wherever
  `resultDisplay` is cleared, with a regression test.

- Docs: keyboard-shortcuts.md still described Ctrl+O as "toggle compact
  mode"; updated to the open/close full-detail transcript behavior.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(tui): report a TTY stdout in ScrollableList mouse-scroll tests

The new `stdout.isTTY` gate in `useMouseEvents` (which stops SGR mouse
escapes leaking into piped output) left ink-testing-library's fake
stdout — which has no `isTTY` — with the mouse pipeline disabled, so the
scrollbar-drag and wheel-scroll assertions never received events. Mock
ink's `useStdout` to report `isTTY: true` so the pipeline arms exactly as
it does in a real terminal; all other ink exports are preserved.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): address Ctrl+O transcript review — q-guard, callback churn, tests, cleanup

Resolves the qwen3.7-max /review findings:

- Modifier guard on the transcript close key: bare `q` closed the
  transcript, but Ink reports Ctrl/Alt/Shift+Q as `{ name: 'q', … }` too
  (Alt arrives as `meta`), so those silently closed it. Guard
  `!key.ctrl && !key.meta && !key.shift` (Shift+Q is a literal `Q`).

- Stable `openTranscript`: it captured `historyManager.history` and
  `pendingHistoryItems` as deps, both of which change identity every
  streaming tick, rebuilding the callback — and the whole
  `handleGlobalKeypress` closure that lists it — on every render during
  streaming. Read both via refs so the callback is referentially stable.

- AppContainer transcript integration tests (the removed TOGGLE_COMPACT
  tests had no replacement): Ctrl+O installs TranscriptView; Esc / q /
  Ctrl+C / Ctrl+D close it; Ctrl+Q / Alt+Q / Shift+Q do NOT (modifier
  guard); arbitrary keys are swallowed and keep it open; a blocking
  confirmation (WaitingForConfirmation) auto-closes it (anti-deadlock).

- Dead i18n string: removed the orphaned
  'Press Ctrl+O to show full tool output' key from all 9 locale files
  (no `t()` reference remained after the compact-mode sweep).

- Design doc: replaced the leaked absolute worktree path with a
  placeholder, and corrected the §6 keybinding-migration note — the
  codebase has no user-configurable keybinding override surface
  (`keyMatchers` always uses hardcoded defaults), so there is no
  persisted `toggleCompactMode` binding to migrate; the startup-detection
  step is not applicable until such a feature exists.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): escape ANSI in transcript detailedDisplay + gate its extraction

Two findings from the qwen3.7-max /review on §4.9:

- [Critical] ANSI escape injection: `detailedDisplay` carries raw,
  un-sanitized tool output (file contents, grep hits, directory
  listings). The Ctrl+O transcript rendered it straight to <Text>
  without escaping, so a malicious repo file with embedded terminal
  control sequences (e.g. `\x1b[?1049l` to drop the alt-screen, OSC 52
  for clipboard poisoning) would execute when the transcript opened —
  and fullDetail lifts the height cap, exposing the whole file. Run it
  through `escapeAnsiCtrlCodes` (already used for agent names in this
  file) before rendering. Added a regression test asserting the raw ESC
  bytes don't survive.

- [perf] `detailedDisplay` was extracted on every successful tool call
  (~25K chars from core's truncation) but is consumed only by the
  transcript's fullDetail render for collapsible (read/search/list)
  tools. Gate the extraction on `isCollapsibleTool(displayName)` so
  edit/write/command/agent calls no longer store a large string the
  renderer never reads — mirrors ToolMessage's `usingDetailedDisplay`
  gate (which also keys off the display name).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): gate resume-path detailedDisplay on isCollapsibleTool (match live path)

The resume path (resumeHistoryUtils.ts) extracted `detailedDisplay` for
every successful tool call, unlike the live path in useReactToolScheduler
which gates on `isCollapsibleTool(displayName)`. Since the transcript's
`usingDetailedDisplay` only consumes it for collapsible (read/search/list)
tools, resuming a session with many edit/write/command/agent calls stored
large (~25K char) strings the renderer never reads. Apply the same gate so
live and resume stay consistent, using `toolCall.name` (the display name,
set from `tool.displayName`) to match the renderer's key.

Updated the existing derivation tests to use a collapsible read tool (an
edit tool now correctly yields undefined) and added a regression asserting
a non-collapsible tool leaves detailedDisplay undefined on resume.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): strip bare C0 control bytes from transcript detailedDisplay + memoize

Follow-up to the ANSI-escape fix. `escapeAnsiCtrlCodes` delegates to
ansi-regex, which only matches ESC-prefixed sequences, so bare C0 control
bytes without an ESC prefix (BEL \x07, BS \x08, FF \x0c, SO \x0e, SI \x0f,
CR, …) passed through to <Text> and could still corrupt the display or
ring the bell from a malicious file's contents. Add a second pass that
strips those bytes (keeping only TAB and LF, which structure multi-line
output). Memoize the two-pass sanitization with useMemo keyed on
detailedDisplay so the ~25K-char regex work doesn't re-run every render.

Extended the ToolMessage regression test to assert bare C0 bytes are
stripped alongside the ESC sequences.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(tui): memoize HistoryItemDisplay, add ErrorBoundary tests + TAB/LF invariant

Addresses three review suggestions:

- Wrap `HistoryItemDisplay` in `React.memo` so the Ctrl+O transcript
  (which re-renders on every scroll tick) skips re-rendering
  frozen-snapshot items whose props are shallowly unchanged. The
  transcript passes stable `item` references, so the default shallow
  compare is effective; harmless for the main view (items live in
  `<Static>` and render once).

- Add ErrorBoundary.test.tsx covering the four behaviors: renders
  children when healthy, catches a render error into the default
  fallback with the message, renders a custom fallback, calls `onError`
  with the error + component stack, and `reset` clears the error state so
  the subtree recovers.

- Lock the C0-strip invariant: assert TAB and LF survive in
  detailedDisplay (the regex intentionally skips \x09/\x0a) so a future
  regex change can't silently collapse multi-line/columnar output.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* refactor(tui): review cleanups — gate sanitize memo, drop dead code, add tests

Addresses the latest /review suggestions:

- ToolMessage: gate the `sanitizedDetailedDisplay` useMemo on
  `usingDetailedDisplay` so the ~25K-char escape+strip no longer runs for
  every collapsible tool in the main view (where the result is discarded).

- TranscriptView: remove the dead `listRef` (created + passed as `ref` but
  never used imperatively) and the dead `onClose` prop (declared, then
  `void`-ed; close keys are owned entirely by AppContainer's global
  keypress guard). Dropped the now-unused `useRef` / `ScrollableListRef`
  imports and the `onClose` call-site + props.

- Tests: add TranscriptView error-fallback coverage (a throwing item
  renders the recovery fallback, not a crash); add live-path
  `mapToDisplay` detailedDisplay extraction coverage (collapsible →
  extracted, non-collapsible → undefined); add Ctrl+O to the transcript
  close-keys it.each (the toggle key was the only close key untested).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(tui): remove orphaned no-op CompactModeProvider stubs

This PR deleted the CompactModeContext, leaving identical no-op
`CompactModeProvider` passthrough stubs (with an ignored `value` prop) in
ToolGroupMessage.test.tsx, ToolMessage.test.tsx and MainContent.test.tsx,
each still wrapping every render. Remove the stubs and unwrap the renders;
drop the now-meaningless `compactMode` params/args from the local render
helpers. Behavior-preserving (the stubs rendered children verbatim) —
all three suites still pass.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): strip bidi overrides, sanitize error fallbacks, share filters

Latest /review round:

- [Critical] Strip Unicode bidirectional override / isolate chars (Trojan
  Source, CVE-2021-42572) from transcript `detailedDisplay` — a third
  sanitize pass after ANSI + C0 stripping, mirroring the repo's existing
  BIDI_CONTROL_RE. Regression test added.

- Sanitize `error.message` with `escapeAnsiCtrlCodes` in both the
  ErrorBoundary default fallback and the TranscriptView custom fallback
  (defense-in-depth against control codes in a crafted error message).

- Ctrl+O while the ThinkingViewer is open now swaps to the transcript
  (falls through to openTranscript, which clears the viewer) instead of
  being silently swallowed.

- Extract the shared `isHistoryItemVisibleAfterRestore` predicate into
  types.ts and use it from both MainContent (main view) and AppContainer
  (transcript freeze), so the two surfaces can't diverge on which
  collapse-on-resume items are hidden.

- Tests: use the exported `TOOL_SUCCEEDED_OUTPUT` constant instead of the
  hardcoded literal in generateContentResponseUtilities.test.ts.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): harden compaction guard to always clear detailedDisplay

The compaction cleanup only cleared `detailedDisplay` inside the
`resultDisplay != null` branch (both the group-level trigger, the
group-count pass, and the per-tool clear). A tool carrying only
`detailedDisplay` (no resultDisplay) would skip compaction and leave the
raw transcript detail intact — a latent privacy leak if the two fields
ever decouple. Widen all three checks to also match `detailedDisplay !=
null` so the memory/privacy safeguard is robust. Added a defensive
regression test.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): sanitize mime/uri in getToolResponseDisplayText media placeholders

The `<media: …>` placeholder interpolated `inlineData.mimeType` /
`fileData.mimeType` / `fileData.fileUri` from tool responses verbatim. A
crafted response could embed control characters or angle brackets to
inject terminal codes or forge/mangle the placeholder markup. Add a
`sanitizeMediaLabel` helper that strips C0/C1 control bytes and `<`/`>`
before interpolation, falling back to the default label when emptied.
Regression test added.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(tui): report a TTY stdout in BaseSelectionList mouse integration test

The `stdout.isTTY` gate added to `useMouseEvents` (stops SGR mouse escapes
leaking into piped output) left #6011's BaseSelectionList mouse test —
which renders via ink-testing-library where the hook-provided stdout reads
as non-TTY — with the mouse layer disabled, so the any-event enable escape
was never written. Mock ink's `useStdout` to report `isTTY: true` with a
capturing write spy (matching useMouseEvents.test.tsx / ScrollableList.test
.tsx), and assert the `?1003h` enable via that spy while items still render
through ink's own stdout. Both cases pass.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(core): fix JSDoc placement + note ErrorBoundary fallback is un-translated

Two small review nits:

- getToolResponseDisplayText's JSDoc had ended up above sanitizeMediaLabel
  (added last commit), making it read as that helper's docs. Reorder so
  sanitizeMediaLabel + its own JSDoc come first and each doc sits directly
  above its function.

- Document why the ErrorBoundary default fallback's title is intentionally
  a plain English string (last-resort message for callers with no
  `fallback`; renders mid-crash, so it avoids pulling in the i18n layer —
  the transcript passes its own localized fallback anyway).

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(tui): share terminal-sanitize pipeline; guard AlternateScreen writes

- Extract the three-pass sanitizer (ANSI escape + bare-C0 strip + bidi
  strip) into `sanitizeTerminalText` in textUtils.ts as the single source
  of truth, and use it at all raw-text render sites: ToolMessage's
  `detailedDisplay`, and the TranscriptView + ErrorBoundary error-message
  fallbacks (previously those only escaped ANSI, missing C0/bidi — the
  boundary catches errors from the fullDetail path that processes raw tool
  output, so a crafted item shape could carry unsanitized bytes into
  error.message). Removes the duplicated regex consts from ToolMessage.

- AlternateScreen: wrap the alt-screen escape writes (and the exit/cleanup
  writes) in try/catch so a synchronous stdout error (EPIPE on terminal
  close, EAGAIN under backpressure) can't propagate uncaught from the
  effect and crash the app or corrupt the terminal.

Generated with AI

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: 秦奇 <gary.gq@alibaba-inc.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-09 23:40:29 +00:00
jinye
f5d36aa5f1
feat(cli): Add workspace-qualified core REST routes (#6567)
* feat(cli): Add workspace-qualified core REST routes

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): Preserve encoded workspace cwd selectors

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: fix CI failure on PR #6567

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: fix CI failure on PR #6567

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#6567)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-09 15:01:55 +00:00