Commit Graph
73 Commits
Author SHA1 Message Date
chencheng (云谦)andShaojin Wen 29fa7bbe06 chore(types): compile cleanly under the TypeScript 7 native compiler (#16463)
* fix(types): compile cleanly under the TypeScript 7 native compiler

tsgo (@typescript/native-preview) reported 48 errors across the
typecheck projects while tsc 5.8 reported none. This removes all of
them without changing what tsc emits, so a tsgo typecheck lane or a
later compiler switch can start from a clean tree.

- Drop `baseUrl` from five tsconfigs. TypeScript 7 removed it, and
  every `paths` target here is already relative to its tsconfig.
- Set `rootDir` where TypeScript 7 no longer infers it (web-shell
  declarations, sdk-typescript), and list node types explicitly for
  cua-driver now that @types are no longer included by default.
- Annotate Buffers built by Node's Buffer factories as
  `Buffer<ArrayBuffer>` (or widen to `Buffer` where a variable later
  receives stream chunks); the ES2024 lib no longer treats
  ArrayBufferLike as an ArrayBuffer, so these failed at fetch, Blob,
  and Response call sites. The two call sites that take caller- or
  interface-supplied bytes assert `BodyInit`, matching the existing
  XMLHttpRequest upload path.
- Remove three redundant `?? []` / `?? undefined` operands that the
  newer checker reports as unreachable.
- Declare `*.css` modules for the two integrations that import
  stylesheets, now that side-effect imports are checked.

* fix(types): include web-shell client declarations in the build config

The config's include listed only client/index.tsx, so client/vite-env.d.ts
and client/local-files/file-system-access.d.ts never entered the program.
Removing baseUrl unmasked 227 tsgo errors (and 222 under tsc 5.8) for the
CSS module and File System Access declarations they provide.

---------

Co-authored-by: Shaojin Wen <[email protected]>
2026-11-07 08:23:16 +00:00
Bob.qwencodeandgithub-actions[bot] 208beb2b3b chore(release): v0.26.9 [skip ci]
* chore(release): v0.26.9

* docs(changelog): sync for v0.26.9

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-06 18:03:10 +00:00
Bob.qwencodeandgithub-actions[bot] 3718b57fa8 chore(release): v0.26.8 (#16409)
* chore(release): v0.26.8

* docs(changelog): sync for v0.26.8

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-06 01:02:08 +08:00
Bob.qwencodeandgithub-actions[bot] 7d5a82443a chore(release): v0.26.7 [skip ci]
* chore(release): v0.26.7

* docs(changelog): sync for v0.26.7

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-04 04:49:30 +00:00
Bob.qwencodeandgithub-actions[bot] 5e267805c3 chore(release): v0.26.6 (#16163)
* chore(release): v0.26.6

* docs(changelog): sync for v0.26.6

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-03 07:00:07 +08:00
e26f377a28 chore(release): v0.26.5 (#16035)
* chore(release): v0.26.5

* docs(changelog): sync for v0.26.5

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Shaojin Wen <[email protected]>
2026-11-01 12:40:25 +08:00
Bob.qwencodeandgithub-actions[bot] ae51b081ce chore(release): v0.26.4 [skip ci]
* chore(release): v0.26.4

* docs(changelog): sync for v0.26.4

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-29 15:14:52 +00:00
qqqys 81ab5b9285 feat(generated-ui): keep chatting with a card's values and turn Generated UI on by default (#15856)
* feat(generated-ui): let users keep chatting with a card's values

Continuing from an interactive view took a separate button and a review
dialog that showed the protocol text and a JSON snapshot. Hosts built
on MCP Apps let a view update the model context and let a view's own
explicit action post to the conversation directly; the card now does
both.

After the user changes values, the App sends the applied values as
model context once they settle (ui/update-model-context). Web Shell
places them above the composer as one removable "Interactive view
values" tag per card, replaced as the values change, so whatever the
user types next carries the card's current state. Values are offered
only after an interaction and never from a hidden or parked card.

The App's continue action now sends the applied values straight to the
session. The built-in card's parameter message skips the review dialog
and appears in the transcript as the same labelled reference instead of
raw text, and sending it clears that card's composer tag. When nothing
was sent, the card says so with the host's reason (for example a busy
session) and offers the action again. Other App messages, including the
built-in card's request to fix a failed view, keep the review dialog.

The writer skill asks for a short reply after the card that does not
repeat what the card shows, and explains how later messages carry the
view's values.

* feat(generated-ui): turn Generated UI on by default

experimental.generatedUi now defaults to true, so clients that render
MCP Apps, such as Web Shell, can show interactive views without a
settings change. An explicit false still turns it off, and an invalid
value still leaves it off.

Only an explicit opt-in warns when the runtime cannot offer the view
(untrusted workspace, sandbox, missing assets and similar); under the
default the session falls back to text as it already does for clients
that do not render MCP Apps. The settings schema, the VS Code schema,
the Web Shell setting copy, the settings reference and the Generated UI
README describe the new default.
2026-10-29 20:16:06 +08:00
qqqys 8739bc042b feat(generated-ui): offer interactive views when users want to adjust values (#15846)
In a code workspace the model usually wrote a standalone HTML file when
asked for a calculator or simulator, and reached generated_ui_show only
when the prompt explicitly said not to write files. The tool was also
deferred, so even then the model first searched for it and called it
through the ToolCall bridge.

The bundled server's tool is now declared up front. The skill
description, skill introduction and tool description say when to use
an interactive view (the user wants to change values and see results,
or compare options under adjustable assumptions) and when not to (a
single fact, an explicitly requested file, page or project code, or
work that needs live data), and to prefer the view to a standalone HTML
file when the user has not asked for one.
2026-10-29 09:55:30 +00:00
qqqys 69cb6d0483 feat(generated-ui): localize and reshape the card frame (#15803)
* feat(generated-ui): localize and reshape the card frame

The card frame was English-only, used unstyled browser buttons, gave the
view a fixed 390 px height inside a 640 px host cap, and showed results
behind nested scroll areas. Cancelling a review produced a long warning
that the request might still be in flight, and Stop pointed users to a
reopen action it did not show.

The frame now follows the host locale (English and Simplified Chinese),
styles its buttons with the host variables, sizes the view to its
content without a border or scroll area of its own, and collapses the
summary to two lines. A hidden or zero-width view is not measured, so the
card never flashes thousands of pixels tall while it mounts. A stopped
view stays visible under an overlay that points to reopening it, which
the host's Reopen and reset action does. After the first interaction
the card notes that changes stay in the page and refreshing the page
restarts from the initial values.

Web Shell sends its language in the MCP App host context, raises the
App height cap to 960 px, and marks message results whose review was
cancelled or expired before dispatch. The card then says nothing was
sent and offers the same action again, keeping the unconfirmed warning
for requests that may have been dispatched.

* fix(generated-ui): keep the card frame stable, localized and accurate

Measure the view at its minimum height and refit on resize only when the
width changed, so viewport-sized content (100vh, height:100%) no longer
grows the frame to its cap through its own resize events. The view body
is a flow root, so collapsed child margins are measured.

Localize the placeholder title, the view's accessible name and the
frame's own failures; errors from the generated document stay as
written. A view stopped before it appeared says how to start again.
Collapsing the summary measures it again.

Web Shell marks refusals that never reached the session as failed and
keeps a review outcome when the card's lease ends first. A retry that
sends nothing keeps the warning of an earlier unconfirmed attempt.
2026-10-29 11:31:25 +08:00
Bob.qwencodeandgithub-actions[bot] 08d97f383a chore(release): sdk-typescript v0.1.25 [skip ci]
* chore(release): v0.26.3

* chore(release): sdk-typescript v0.1.25

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-28 17:02:53 +00:00
qqqys a000b33748 feat(generated-ui): follow the host theme in generated views (#15798)
Generated content followed the operating system's color scheme instead
of the Web Shell theme, and models chose colors for one theme. With Web
Shell in dark mode, cards showed near-white text on light panels and
dark-on-dark headings and table rows.

Web Shell now sends standard MCP App style variables resolved from its
own color, font and radius tokens, including a secondary text color
that stays readable in each theme. The Generated UI App applies them to
its frame and copies the allowed variables onto the view document,
whose color-scheme is pinned to the host theme and updated on theme
changes.

A base stylesheet styles headings, labels, form controls, buttons,
tables and output with those variables and adds --gu-* variables plus
panel, grid, stat, muted, danger and num helpers. The writer skill asks
for these instead of fixed colors or widths, and not to repeat the card
title or wrap the whole view in another bordered box, and the documented
examples are checked against the new pre-display check.

Passing the theme tokens adds 820 bytes to the transcript export renderer,
which main had left 790 bytes below its ceiling; the ceiling rises to
2,053,000 bytes with the measurement recorded next to it.

The base styles make controls larger, so the queue notice that appeared
above the view during a burst of clicks moved the view enough to send
later clicks to neighbouring elements. The notice now sits below the
view.
2026-10-28 14:44:36 +00:00
qqqys 8345f5ceec feat(generated-ui): check a view's initial calculation before display (#15790)
Run the generated JavaScript's initialization once in the same bounded
QuickJS interpreter before returning a snapshot, using the markup's
initial input values and a stand-in ui API. Syntax errors, exceptions
from the initial calculation, initial updates to missing element IDs
and markup the view rejects now return a VIEW_ERROR tool result that
names the problem, with line and column, so the model can correct the
document instead of reporting a broken card as ready.

The App names ordinary script errors instead of a generic runtime-limit
message, reading only native error data properties so guest getters and
toString hooks never run. When a view fails because of its document, the
card offers to send the error to the session for correction through the
existing host message review.

The writer skill documents the check and that Intl is unavailable and
toLocaleString ignores locales and options.
2026-10-28 20:34:36 +08:00
qqqys fe5f093f56 fix(generated-ui): offer Generated UI only to clients that render MCP Apps (#15720)
* fix(generated-ui): offer Generated UI only to clients that render MCP Apps

Generated UI activated in every trusted local session once the setting
was on, including the interactive TUI, qwen -p and other headless runs,
editor ACP clients and channels. None of them can show a card, yet the
model still called generated_ui_show and told the user to adjust the
sliders in a card above.

The daemon's ACP bridge, whose sessions Web Shell and Desktop display,
now declares qwen.mcpAppHost in its client capabilities, and acpAgent
marks those session configs as MCP App hosts before initialization.
Every other session reports the new unsupported-client reason and does
not receive the tool or skill. That reason is an expected state, so it
no longer produces the startup warning the bootstrap config used to log
as unsupported-runtime.

* fix(generated-ui): keep Generated UI off for channel sessions the daemon creates

A daemon-managed channel creates its sessions through the daemon bridge,
which declares an MCP App host, but its users read replies in the IM
client and cannot see a card. Treat channel-sourced sessions as
unsupported clients.
2026-10-28 19:28:46 +08:00
Bob.qwencodeandgithub-actions[bot] 5180685d97 chore(release): sdk-typescript v0.1.24 [skip ci]
* chore(release): v0.26.2

* chore(release): sdk-typescript v0.1.24

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-27 18:01:25 +00:00
qqqysandqqqys c586e00cb7 feat(web-shell): retain Generated UI instances across same-page navigation (#15611)
* feat(web-shell): retain Generated UI instances across same-page navigation

* fix(web-shell): release retained UI after background session deletion

* fix(web-shell): bind Generated UI owners before initial events

* fix(web-shell): release retained UI after failed session restore

* fix(web-shell): retain views in shadow portals and local deletion

* fix(web-shell): keep retained views out of transcript exports

Let transcript builds prune the unused retention branch without raising the document renderer budget. Verify built artifacts and align the retained-history fixture with the current navigation gutter requirement.

* fix(web-shell): preserve retained view lifecycle boundaries

* fix(web-shell): observe Generated UI revocations before render

* fix(web-shell): defer retention until canonical ownership matches

---------

Co-authored-by: qqqys <[email protected]>
2026-10-27 16:54:35 +00:00
qqqysandqqqys 58a4c1b9cc feat(generated-ui): continue analysis with reviewed parameters (#15333)
* feat(generated-ui): continue analysis with reviewed parameters

* test(generated-ui): reveal outer frames before continuation clicks

* fix(generated-ui): keep continuation feedback accurate when nothing was sent

A capture failure no longer reports that a sent request may still be
accepted, and the unconfirmed message now covers cancelled or rejected
reviews, which the host reports the same way as an unknown outcome.

---------

Co-authored-by: qqqys <[email protected]>
2026-10-25 16:12:38 +08:00
aa6b65a52a chore(release): v0.26.1 (#15468)
* chore(release): v0.26.1

* docs(changelog): sync for v0.26.1

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: 易良 <[email protected]>
2026-10-25 01:27:17 +08:00
qqqysand衍星 034e35056b feat(generated-ui): expose interaction outcomes and applied parameter snapshots (#15004)
Co-authored-by: 衍星 <[email protected]>
2026-10-22 17:32:47 +08:00
Bob.qwencodeandgithub-actions[bot] 8f259db527 chore(release): v0.26.0 [skip ci]
* chore(release): v0.26.0

* docs(changelog): sync for v0.26.0

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-22 02:08:04 +00:00
qqqysand衍星 5f638ae436 feat(generated-ui): bundle Generated UI behind an experimental flag (#14888)
* feat(generated-ui): bundle behind an experimental flag

* fix(generated-ui): preserve runtime admission and settings aliases

* fix(generated-ui): invalidate owning cards after MCP refresh

---------

Co-authored-by: 衍星 <[email protected]>
2026-10-21 11:52:03 +08:00
qqqysandqqqys c4f0acdef8 feat(extensions): add bounded generated HTML and JavaScript views (#14338)
Co-authored-by: qqqys <[email protected]>
2026-10-19 13:09:33 +00:00
Bob.qwencodeandgithub-actions[bot] 530a22680d chore(release): v0.25.3 [skip ci]
* chore(release): v0.25.3

* docs(changelog): sync for v0.25.3

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-19 07:38:12 +00:00
Shaojin Wen 6e6a69c71f test: gate the remaining chmod-based root skips on the permission-bit probe (#14403)
Fifty cases across core, cli, browser-use, sdk-typescript,
test-failure-explorer and scripts/tests force a failure with chmod and
skip whenever uid is 0. ci.yml runs unit tests as root on the ECS pool,
but drops CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH first, so permission
bits bind there and these cases could run; the uid check skips them all
on that lane anyway.

Gate them on whether a mode-000 directory refuses this process, as #14162,
#14271 and #14283 do for the rest:
- core (22 cases in 14 files) and cli (1) use their own helper.
- browser-use, sdk-typescript and test-failure-explorer import nothing
  from another package, so each gets a copy of the helper; browser-use,
  with six cases, also gets its tests, as core did in #14283.
- scripts/tests (19 cases in 7 files) imports the cli helper, as other
  scripts tests do.

Three core cases returned early as root instead of skipping, so they
reported a pass without asserting anything; they now skip there. The
workflow-extension case left its unreadable directory empty, so it passed
whether or not the directory was refused; it now holds a workflow that
would show up if it were read.

package-scripts pins every copy of the helper, and the cli, core and
browser-use copies of its tests, byte-identical, so a fix to one cannot
leave the others behind.

Left on the uid check: pathReader's case, whose permissions come from
mock-fs, which lets uid 0 through whatever the mode; the session writer
lease's chown case, which needs root; and the release workflow's wipe
test, which does not depend on permission bits.
2026-10-16 17:34:52 +00:00
Bob.qwencodeandgithub-actions[bot] 25ef506c03 chore(release): sdk-typescript v0.1.20 [skip ci]
* chore(release): v0.25.2

* chore(release): sdk-typescript v0.1.20

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-15 17:01:33 +00:00
qqqysandqqqys 51f26d3d54 feat(extensions): add bounded generated failure explorer views (#14269)
Co-authored-by: qqqys <[email protected]>
2026-10-16 00:04:16 +08:00
qqqysandqqqys 97fb4a547d feat(web-shell): review MCP App messages before submission (PR3a) (#13958)
* feat(web-shell): review MCP App messages before session submission

* fix(web-shell): preserve MCP App state and admission outcomes

---------

Co-authored-by: qqqys <[email protected]>
2026-10-14 06:34:37 +00:00
qqqysandqqqys 30582105fe feat(extensions): add interactive test failure explorer (PR2) (#13916)
* feat(extensions): add interactive test failure explorer app

* fix(extensions): lint test explorer build scripts

* fix(test-failure-explorer): keep expanded report controls reachable

---------

Co-authored-by: qqqys <[email protected]>
2026-10-12 06:07:55 +00:00
qqqysandqqqys 6775f24927 feat(extensions): add test failure report explorer (#13854)
* feat(extensions): add test failure report explorer

* fix(extensions): bound report snapshots before serialization

* fix(extensions): bound test report validation

---------

Co-authored-by: qqqys <[email protected]>
2026-10-11 12:58:55 +00:00
Bob.qwencodeandgithub-actions[bot] 726e8d77f7 chore(release): v0.25.1 (#13904)
* chore(release): v0.25.1

* docs(changelog): sync for v0.25.1

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-11 12:00:47 +00:00
Bob.qwencodeandgithub-actions[bot] 8d864a9f21 chore(release): v0.25.0 (#13448)
* chore(release): v0.25.0

* docs(changelog): sync for v0.25.0

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 10:07:16 +00:00
易良andQwen-Coder abcf23a3d9 feat(memory): bundle Mem0 with the main CLI (#12891)
* feat(memory): bundle Mem0 with the main CLI

Co-authored-by: Qwen-Coder <[email protected]>

* feat(memory): support settings-defined Mem0 credentials

Co-authored-by: Qwen-Coder <[email protected]>

* fix(memory): preserve bundled Mem0 trust and configuration boundaries

Ignore repository-scoped MCP conflicts, require the genuine bundled runtime for confirmation hooks, and use native artifact paths in packaging assertions. Improve field diagnostics and document existing precedence, scope, and verification limits.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(mem0): close three review Criticals on the bundled Mem0 binding

R1-1 (scripts/tests/package-assets.test.js): the two new multi-segment
`missingArtifact` entries are compared against a message built with
`path.join`, so `mem0/main.js` never matches the `\`-joined Windows path.
Normalise the separator in the assertion; single-segment entries and POSIX
behaviour are unchanged.

R1-2 (packages/cli/src/config/config.ts): the mem0/external-context conflict
guard read the merged all-scopes map, so a `external-context` entry that a
trusted repository contributes through its own `.qwen/settings.json`
(`scope: 'workspace'`) aborted `loadCliConfig` for every operator who
configured `memory.mem0` — before `assembleMcpServers` applied the approval
gate that would have held that server pending anyway. Limit the settings leg
to operator scopes via `isGatedMcpScope`; a gated-scope entry is now
overridden by the built-in binding (topTierMcpServers spreads last), exactly
as a `.mcp.json` entry of the same name always has been, matching the design
doc this PR adds.

R1-28 (packages/cli/src/config/mem0-settings.ts): `bundledMem0Hooks`
identified the bundled server by duck-typing an env-var name plus
`includeTools`, so a repository-authored `external-context` entry reaching
the `/hooks` reload path through `getMcpServers()` was filed under
`systemHooks` — the one hook source folder trust does not gate — rendered as
`[System]` configuration and pointed at a different script than the one the
MCP approval dialog showed. Require identity instead: every file-sourced
entry carries a provenance `scope`, the bundled one never does.

Tests: workspace-scoped override + operator-scoped conflict still throws
(config.test.ts), three scoped-entry rejection rows + an unscoped positive
control (mem0-settings.test.ts), and a control/negative pair on the real
reload path (hooksCommand.test.ts). Each fix was mutation-proved red.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmultfgjtdh

* test(mem0): pin the spawn interpreter, timeout slack and both bound copies

R1-23: nothing in the repo observed `server.command` or `server.timeout`, and
the `memory.mem0.timeoutMs` bounds are declared independently in
mem0-settings.ts (zod, the runtime contract) and settingsSchema.ts (the
settings-dialog copy). Replacing `command: process.execPath` with `'node'`, or
dropping the `+ 5000` slack, left every suite green — a packaged or
GUI-launched install routinely has no `node` on PATH, and the same value gates
`bundledMem0Hooks` and is interpolated as the hook interpreter.

Adds, in mem0-settings.test.ts: `command === process.execPath`,
`config.timeoutMs === 5000` / `server.timeout === 10_000` for the default, an
accept row at the documented ceiling asserting `35_000`, and reject rows for
`0` / `30001` / `1.5`. Adds, in settingsSchema.test.ts, the bound test mirroring
the existing `tools.webSearch.timeoutMs` precedent so the JSON-schema copy is
pinned to the same documented numbers (docs/users/features/mem0.md: "defaults to
5000, between 1 and 30000").

Mutation-proved individually: `process.execPath` -> `'node'` red, `+ 5000`
removed red, `maximum: 30000` -> `60000` red; intact tree green (27 + 61).

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmultfgjtdh

* fix(mem0): restore PolarDB direct-import text on retrieval

Co-authored-by: Qwen-Coder <[email protected]>

* test(mem0): use the real bundled binding in hook reload control

Co-authored-by: Qwen-Coder <[email protected]>

* fix(memory): Preserve Mem0 operator and legacy preset semantics

Co-authored-by: Qwen-Coder <[email protected]>

* test(memory): Pin Windows Mem0 package artifact errors

Co-authored-by: Qwen-Coder <[email protected]>

* fix(memory): Retain Mem0 safeguards across reloads

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-09-30 07:57:11 +00:00
Bob.qwencodeandgithub-actions[bot] 34dbaf6741 chore(release): v0.24.7 (#13025)
* chore(release): v0.24.7

* docs(changelog): sync for v0.24.7

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-29 14:36:56 +00:00
Bob.qwencodeandgithub-actions[bot] 16496a71ec chore(release): v0.24.6 (#12722)
* chore(release): v0.24.6

* docs(changelog): sync for v0.24.6

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-26 01:06:56 +00:00
Bob.qwencodeandgithub-actions[bot] af5e90bfb2 chore(release): v0.24.5 (#12661)
* chore(release): v0.24.5

* docs(changelog): sync for v0.24.5

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-24 17:19:31 +00:00
Bob.qwencodeandgithub-actions[bot] 1b26d38b5c chore(release): v0.24.4 (#12476)
* chore(release): v0.24.4

* docs(changelog): sync for v0.24.4

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-22 15:19:32 +00:00
Bob.qwencodeandgithub-actions[bot] 364032a032 chore(release): v0.24.3 (#12418)
* chore(release): v0.24.3

* docs(changelog): sync for v0.24.3

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-21 14:46:57 +00:00
Bob.qwencodeandgithub-actions[bot] eceaede18e chore(release): v0.24.2 (#12359)
* chore(release): v0.24.2

* docs(changelog): sync for v0.24.2

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-20 16:05:04 +00:00
Bob.qwencodeandgithub-actions[bot] 94946f1bf8 chore(release): v0.24.1 (#12239)
* chore(release): v0.24.1

* docs(changelog): sync for v0.24.1

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-19 08:23:48 +00:00
易良andQwen-Coder 9f75842786 feat(external-context): Support configurable Mem0 providers (#9952)
* feat(external-context): Support open-source Mem0 providers

Add a mem0 provider type to the external-context integration that speaks
the open-source Mem0 REST API (POST /v2/memories/search for on-demand
recall, POST /v1/memories with infer:false for exact direct-import
writes), so self-hosted mem0 servers and managed OSS-protocol services
such as Aliyun PolarDB Mem0 can serve as the external context corpus.

The tenant identity (user_id, optional app_id) is fixed in the
administrator-managed configuration and is never supplied by the model.
A new allowInsecureHttp opt-in permits plain-HTTP endpoints such as
PolarDB Mem0 while credentials-in-URL remain rejected.

Refs #9951

* test(external-context): Cover the open-source Mem0 example config

Assert the exact example structure and that it loads through loadConfig
once the endpoint and user placeholders are substituted, so the shipped
sample cannot drift from the provider schema.

* refactor(external-context): Address review on the mem0 provider

Enforce the OSS baseUrl policy only in the adapter constructor, matching
the sibling providers, and have the rejection message point at the
allowInsecureHttp opt-in. Extract the shared write-rejection classifier
used by both Mem0 adapters, pin localhost and IPv6 loopback acceptance,
cover non-HTTP write failures mapping to unknown, clean up the example
test's temp directory, and correct the README rollout guarantees and the
OSS write-enablement guidance.

* fix(external-context): Ship the mem0 example with HTTPS defaults

The example pre-enabled allowInsecureHttp, inverting the README guidance
it is cited by. Default to an HTTPS baseUrl without the flag; the hinted
validation error and the README paragraph lead plain-HTTP whitelist
deployments to the explicit opt-in.

* test(external-context): prove shipped mem0 example constructs a provider

* refactor(external-context): address mem0 review round — merge duplicate arms, gate HTTP hint, fix README wording

* fix(external-context): Scope OSS mem0 by agent_id instead of app_id

The open-source mem0 v1.0.1 REST protocol (implemented by Aliyun PolarDB
Mem0) scopes memories by user_id / agent_id / run_id; app_id is a
hosted-platform-only field these endpoints do not accept. Rename the
optional mem0 provider field to agentId, send it as agent_id, and place it
top-level in the v2 search request (filters carry user_id) to match the
protocol.

Verified live against a PolarDB Mem0 instance: add and search accept
agent_id, infer:false is honored for direct import, and the MCP chain works
end to end.

* fix(external-context): Scope Mem0 provider to PolarDB

* feat(external-context): add versioned Mem0 presets

Replace the protocol-specific draft provider with a generic Mem0 provider backed by reviewed, immutable presets for Mem0 Platform, stock Mem0 REST, and PolarDB.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(external-context): survive an unverified Mem0 deployment build

The endpoint is operator-supplied and its build is not guaranteed - these
services are self-hosted or vendor-packaged, and the stock Mem0 REST server
carries no API version in its paths at all. A preset is therefore a claim
about what is deployed, and it can be wrong. Nothing here probes or falls
back; instead a mismatch is kept from passing silently.

Send session identity at both the request root and under `filters` for the
Mem0 server preset. `_build_filters_and_metadata` seeds the effective filters
from `filters` and then overwrites each identity key with the root value, so
one request resolves to a byte-equal scope on builds that read either
position. A filters-only search is rejected outright by builds predating that
move, which surfaced as a 500 rather than as an unscoped search.

Claim `stored` for a direct import only when the echoed `memory` matches the
submitted text and the event is not a delete. `infer: false` is what makes the
stored memory the exact text approved at the confirmation Hook, but a build
whose request model predates the field drops it silently, runs fact
extraction, and returns a rewritten memory with a valid identifier - reported
until now as `stored`.

Write provider failures to stderr with the HTTP status, which separates a
contract mismatch from an outage. The model-facing error stays opaque, and no
provider response body is ever written.

Rename the preset to `mem0-server-rest-2026-08`: "OSS" names an object storage
service in some of the clouds these deployments run in, and the preset list it
sits in already names one of those clouds.

Report which scope key and which basePath rule a configuration broke, narrow
the preset unions to the members a shipped preset uses, and cover the write
result classes, basePath rules, both scope rules in isolation, the identifier
bound, the direct-import basePath join, the Platform V3 preset write request,
and the mem0 arm of auto-recall credential scrubbing.

* feat(external-context): add a read-only Mem0 preset probe

Every other field of a `mem0` block is a fact the administrator already holds.
`preset` is not: it is a claim about which wire contract the deployment
implements, and these services are self-hosted or vendor-packaged, so the
answer is not visible from the configuration side. The configuration made that
claim mandatory without offering any way to check it.

The probe runs a candidate preset through the real adapter against the real
endpoint, so a preset that reaches the service but whose items the parser
discards is reported as the mismatch it is. It also reads the declared search
schema when one is served, and compares scope placements so a preset can be
moved to `body-and-filters` on evidence rather than on assumption.

An empty corpus is reported as inconclusive rather than as a pass: three
equally empty result sets look like agreement and are not.

Read-only. It issues search requests and one `GET /openapi.json`, never
writes, and never renders the credential.

* refactor(external-context): drop the vendor prefix from the PolarDB preset

PolarDB Mem0 is offered by more than one cloud, so an identifier scoped to one
of them reads as inapplicable to an operator running the same contract
elsewhere - the preset names a wire contract, not a vendor. The mapping's
verification evidence came from an Aliyun deployment, which the design doc now
says explicitly rather than encoding in the identifier.

Record who controls the build behind each preset, and probe placements only
where that is the operator. A vendor-operated service has one published
contract and no version skew to hedge against, so reporting that a different
request shape also works would invite a deviation with a cost and no benefit.

A skipped comparison no longer stands in for a working preset: when the
baseline search fails, the verdict is the mismatch, not "see the baseline".

* fix(external-context): restore bounded Mem0 contracts

Co-authored-by: Qwen-Coder <[email protected]>

* docs(external-context): ship a PolarDB example that loads as it is shipped

The console hands out a plain-HTTP address and port, while the shipped example
carries an `https://` origin with no port - the shape the endpoint should have,
not the shape it arrives in. Pasting the console address into that example
fails the URL policy, and nothing tells the operator which of the legitimate
resolutions their deployment wants.

Add a loopback example instead of loosening the policy. An `ssh -L` relay
carries the credential and the memories, loopback HTTP loads with no opt-in, and
only the user id has to be substituted, so the path from a new instance to a
working search is one relay command and one copied file. The HTTPS example is
unchanged: pre-enabling the opt-in in a shipped file would invert the posture
the surrounding section asks operators to keep.

The loopback example omits `agentId`, which the preset sends at the request
root - a placement no PolarDB document confirms, and an optional field is not
worth staking a first connection on.

* docs(external-context): clarify PolarDB setup

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-09-17 09:22:34 +00:00
Bob.qwencodeandgithub-actions[bot] c53287da5f chore(release): v0.24.0 (#12031)
* chore(release): v0.24.0

* docs(changelog): sync for v0.24.0

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-16 13:31:06 +00:00
Bob.qwencodeandgithub-actions[bot] af4da34719 chore(release): v0.23.4 (#11880)
* chore(release): v0.23.4

* docs(changelog): sync for v0.23.4

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-14 15:59:33 +00:00
易良andQwen-Coder c666ec1a0a fix(ci): restore Windows test baseline (#11787)
* fix(live): restore Windows filesystem compatibility

* fix(ci): restore Windows test baseline

* fix(ci): keep release-age excludes internal and re-arm two witnesses

- pnpm-workspace.yaml: drop '@tybys/[email protected].4' from
  minimumReleaseAgeExclude. scripts/tests/package-scripts.test.js pins
  that list to internal, version-independent entries. The exclusion is
  also inert: minimumReleaseAge is not configured anywhere in the repo,
  and pnpm-lock.yaml records `overrides` but not minimumReleaseAgeExclude
  -- so the '@tybys/wasm-util': '0.10.4' override stays, because dropping
  it would desync the lockfile and fail --frozen-lockfile.
- web-shell-brand.test.ts: build the swapped-file fake as BigIntStats.
  Production compares bigint fields with a bare `!==`, so a number-backed
  fake tripped `dev` first and the perturbed inode was never reached;
  removing the perturbation now turns the test red again.
- run-qwen-serve.test.ts: '0' is unresolvable on Windows (getaddrinfo
  ENOTFOUND 0), so the wildcard case keeps '0.0.0.0' and witnesses the
  socket rather than a spelling: the operator typed port 0, so the report
  must carry the ephemeral port the listener actually got. Spelling
  normalisation stays pinned platform-independently in
  remote-quickstart.test.ts.
- artifact-snapshots.ts: revert the readdir hoist to main. It is
  behaviourally inert (the catch rethrows ENOENT on the operationId path
  either way), has no test and no Windows link.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmu07e78o2w

* fix(ci): restore the load-bearing release-age exclude, keep the witness fixes

The previous commit dropped '@tybys/[email protected].4' from
minimumReleaseAgeExclude to satisfy scripts/tests/package-scripts.test.js:390,
on the reasoning that the entry was inert because minimumReleaseAge is not
configured in this repo. That reasoning was wrong and CI measured it: the gate
is enforced by pnpm itself, not by repo config, so removing the exclude failed
'Install frozen pnpm worktree dependencies' on all three platforms with

  Lockfile failed supply-chain policy check (1975 entries)
  @tybys/[email protected].4 was published at 2026-09-13T08:00:13.464Z,
  within the minimumReleaseAge cutoff (2026-09-12T20:03:50.286Z)

(run 34779568628; Install was green at 6099768ffb, which carries the entry).
Restoring the line makes pnpm-workspace.yaml byte-identical to that head again.

The three other changes from that commit are kept, since they are independent
of the exclude and were green in run 34779568625 (Test 18m58s, Lint & Static
12m36s, Integration no-AK 7m8s): the web-shell-brand.test.ts BigIntStats fake
that re-arms the inode witness, the run-qwen-serve.test.ts socket witness
replacing the tautological '0.0.0.0' assertion, and the artifact-snapshots.ts
revert to main.

This leaves the package-scripts.test.js assertion red exactly as it was before
this round. That is now a measured conflict rather than an open question: the
repo test pins the exclude list to internal, version-independent entries, while
pnpm needs a version-pinned exemption for a package published the same day.
Resolving it means either dropping the '@tybys/wasm-util': '0.10.4' override and
regenerating both lockfiles so an older, age-compliant version resolves, or
relaxing the invariant to admit external version-pinned excludes. Both are
supply-chain policy calls for the author/maintainer, so neither is made here.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmu07e78o2w

* fix(ci): pin @tybys/wasm-util to the age-compliant 0.10.3 instead of exempting it

Test (ubuntu-latest, Node 22.x) failed at scripts/tests/package-scripts.test.js:390
(run 34781999892), which pins minimumReleaseAgeExclude to internal,
version-independent entries, while the previous head carried
'@tybys/[email protected].4' there to satisfy pnpm's minimumReleaseAge gate. The two
looked mutually exclusive, but only because the pin chose the newest release.

@node-rs/jieba-wasm32-wasi pulls in @napi-rs/[email protected], which accepts
^0.10.3, and 0.10.3 was published 2026-06-23 -- well outside the 24h window that
rejected 0.10.4 (published 2026-09-13T08:00:13Z). So the pnpm override now pins
0.10.3, the exclude entry is dropped, and both lockfiles follow: package-lock.json
must lock the same version or scripts/check-lockfile.js's "pnpm lockfile against
package-lock.json" agreement gate fails, which also reddens the two check-lockfile
fixture branches in package-scripts.test.js because they copy the real lockfiles.

The pin lives on the pnpm side only, mirroring how the typescript pins already
diverge; npm has no release-age gate, so no package.json override is added and the
nested @tailwindcss/oxide-wasm32-wasi copy of @tybys/wasm-util is left alone. Once
0.10.4 ages out of the window, a maintainer can drop the override from both sides if
nothing else needs the pin.

Verified locally: pnpm 11.24.0 `install --lockfile-only` reports "Lockfile passes
supply-chain policies (1975 entries)"; scripts/tests/package-scripts.test.js 49
passed / 1 skipped (was 3 failed); scripts/tests/check-lockfile.test.js 14 passed;
prettier --check clean.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-conflict/jmu0ce8qb32

* fix(ci): handle expected Windows socket reset

* fix(ci): make Windows regression tests portable

* fix(ci): make script tests portable on Windows

* test: re-arm four witnesses the review round found vacuous or over-gated

Each of these was measured, not argued; the mutation named in every case is
the one that used to leave the suite green.

- no-follow-open.test.ts: add the >2^53 identity case. Removing
  `{ bigint: true }` from all four production stat call sites left 17/17
  green, so the Windows-precision conversion this PR exists for was
  unwitnessed. The fixture uses 2^60 offsets, where the double spacing is
  256 and both ids collapse to one value; 2^53+1 / 2^53+2 do NOT collapse
  (2^53+2 is exactly representable), so those constants cannot pin it.
  Two-arm measured: intact 18/18 pass, mutated exactly 1 fails.
- web-shell-brand.test.ts: stat the planted regular file with
  `{ bigint: true }`. Production compares BigIntStats with a bare `!==`, so
  the number-backed fake tripped `dev` on a type mismatch alone and would
  have refused the correct file too. Probed both arms: pre-fix
  `typeof expectedStat.dev === 'number'` with the `dev` clause true,
  post-fix both sides bigint with `dev` false and the refusal driven by a
  real inode mismatch.
- conversation-workspace.test.ts: move the `inodeVerifiable` gate below the
  two `toBe(identity)` assertions. They are inode-independent, so gating
  them deleted a witness the Windows lane was green on. Modelled an
  unverifiable-inode host: the test reports skipped, not failed, which is
  only reachable once both assertions have passed.
- worktree.test.ts: split `localFilterCommands` in two. The fail-closed
  branch is platform-free by construction and the base Windows log shows it
  passing there; only the `a\nb` fixture is Windows-impossible, so only that
  half keeps the gate.

Co-authored-by: Qwen-Coder <[email protected]>

* ci: say why the post-redirect autocrlf line is not a duplicate

Both workflows now run `git config --global core.autocrlf false` twice: once
before the checkout and once inside the test step, where HOME/USERPROFILE are
redirected to a freshly created empty directory. The second line therefore
writes a different global config than its twin, and on ci.yml's hosted
windows-2022 fallback the pre-checkout step never runs at all because it is
gated on `runner.environment == 'self-hosted'`.

It was the only one of the three occurrences with no comment, so deduping it
looks free and silently returns CRLF conversion to every git operation the
suites perform. Replaying no-ak-integration-ci.test.js's own assertions with
the second occurrence deleted gives identical indices and still passes, so no
test notices the removal.

Comments only. The ordering assertions search for the FIRST occurrence and
none of the added text matches a needle they look for; the 14 assertions in
no-ak-integration-ci.test.js still pass.

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-09-14 11:17:19 +00:00
qqqysandqwen-code-dev-bot f49dda1b2f fix(core)!: read command hook timeout in seconds (#11615)
* fix(core)!: read command hook timeout in seconds with a 600s default

Command hooks passed `timeout` to the timer as milliseconds, while HTTP
and prompt hooks read it as seconds, the settings schema described
seconds, and the hooks guide documented both. A command hook written
with `"timeout": 10` was killed after 10ms and failed open.

Command hook `timeout` is now read in seconds and defaults to 600s. A
value of 1000 or more is still read as milliseconds so existing settings
keep their meaning, and a debug-log warning names each such hook once.
Timeout errors report seconds. HTTP, prompt and function hooks are
unchanged. The schema description, generated JSON schema and every
command hook example in the guide now use seconds.

BREAKING CHANGE: a command hook `timeout` below 1000 is now seconds
rather than milliseconds.

Part of #11610

* fix(core): keep hook timeouts authoritative and surface legacy values

Review follow-up.

- Hook execution requests on the message bus no longer carry the bus's
  60-second default deadline, so a hook is bounded by its own timeout
  instead of being abandoned while it keeps running. Explicit caller
  timeouts and other request types are unchanged.
- Command hooks on MessageDisplay, StopFailure and SessionDelete, which
  outlive the CLI, default to 60 seconds instead of 600.
- Settings warnings now name each command hook whose timeout is still
  read as milliseconds; the advice never suggests a seconds value that
  would itself be read as milliseconds.
- The hooks guide scopes "seconds" to command, HTTP and prompt hooks and
  notes async slot usage; shipped external-context examples use seconds.
- Tests pin the async registration and supervisor deadlines, and reset
  the warning deduplication between cases.

Part of #11610

* docs(core): explain long command hook timeouts and blocking hold time

A command hook timeout of 1000 or more is still read as legacy
milliseconds, so a value meant as a long timeout in seconds, such as 1800
for 30 minutes, ends up as 1.8 seconds. The startup warning now also says
how to keep the value that was meant as seconds, and the hooks guide
explains that long timeouts stay in milliseconds. The guide also notes that
a synchronous hook on an event that waits for its result holds the turn
until it exits or times out, 600 seconds by default.

* fix(core): bound signal-less hook requests and cancel tool hooks on abort

The message bus now waives its default deadline only for hook execution
requests that carry an abort signal. Requests without one cannot be
cancelled, so they keep the 60-second deadline instead of waiting on the
hook's own timeout.

PreToolUse, PostToolUse and non-interrupt PostToolUseFailure hooks now
receive the tool's abort signal, in the payload and as the request signal,
so an abort stops the hook and releases the wait. Interrupt reports keep no
signal because it is already aborted there. The UserPromptSubmit hook gets
the send signal, and a send aborted during or right after that hook ends as
an abort instead of recording or sending the prompt.

MessageDisplay deliveries pass the turn signal to the request, warn when the
bus reports a failed hook execution, and stay quiet when the turn was
cancelled.

A command hook timeout written as a numeric string is read like the number
it holds instead of falling back to the default.

The startup warning for legacy millisecond timeouts is removed from this
change and tracked in #11675; the hooks guide now explains how to find such
hooks. Async hook timeout messages report seconds, the remaining first-party
millisecond values in integration fixtures and design docs are rewritten in
seconds, and the async hooks bullet names the 60-second default on events
whose hooks outlive the process.

* fix(core): keep the 60 second command hook default and drop hook bus signal threading

Raising the command hook default to 600 seconds forced two rounds of
reconciliation with the 60 second and 15 second bus deadlines: first by
waiving the deadline, then by threading abort signals through the tool
and prompt hook call sites. Each round produced new regressions (payload
vs request signal, already-aborted failure reports, unmigrated arity
assertions, orphaned hook children, cancels recorded as hook errors). The
default change and the cancellation work move to a follow-up issue, and
this change keeps only the unit.

- Command hook timeouts stay in seconds with a 60 second default, the
  same duration as before; values of 1000 or more keep their legacy
  millisecond meaning, and numeric strings are still coerced. The
  separate default for hooks that outlive the process is gone because it
  now equals the default.
- MessageBus, tool hook triggers, the scheduler, the UserPromptSubmit
  request, the MessageDisplay dispatcher and their tests are back to main.
- An unusable timeout such as "30s" is named in the debug log with the
  default it was replaced by, like a legacy millisecond value.
- Timeout warnings are recorded as sent only once debug logging can write
  them, and are deduplicated per session.
- Async hook timeout messages and a real spawned hook with timeout 1 now
  pin the seconds conversion.

---------

Co-authored-by: qwen-code-dev-bot <[email protected]>
2026-09-12 10:44:06 +00:00
cbd2cbadec fix(acp): Preserve submitted prompt provenance for auto recall (#11455)
* fix(acp): Preserve submitted prompt provenance for auto recall

Co-authored-by: Qwen-Coder <[email protected]>

* fix(acp): Omit submitted_prompt on channel-classified turns (#11455)

Channel turns are machine-relayed deliveries (loop jobs, webhook tasks,
adapter-synthesized events), so nothing on them crossed a submission
boundary. Since submitted_prompt presence alone gates Auto Recall's
outbound provider search, emitting it there ran retrieval on unattended
turns and could publish composed wrapper text as user provenance. Gate
emission on a positive user-submission condition instead.

Also reconcile the producer-set contract this PR changed: hooks.md, the
Auto Recall READMEs, the in-product hook description with its locale
mirrors, and the recording payload comment now state the actual rule,
and the new design doc records the channel exclusion plus the
strict-decoder rollout warning.

* fix(acp): Require explicit submission provenance for auto recall

Carry original Web Shell composer text separately through admission and queues; keep background dispatches and undeclared requests ineligible. Reconcile hook and integration contracts and add regression coverage.

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-10 15:17:51 +00:00
Bob.qwencodeandgithub-actions[bot] 38513b591b chore(release): v0.23.3 (#11583)
* chore(release): v0.23.3

* docs(changelog): sync for v0.23.3

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-10 15:03:19 +00:00
Bob.qwencodeandgithub-actions[bot] bae90d7afa chore(release): v0.23.2 (#11469)
* chore(release): v0.23.2

* docs(changelog): sync for v0.23.2

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-09 11:38:23 +00:00
ada633d584 fix(external-context): Align deletion responses with Mem0 SDK (#11397)
* fix(external-context): Align deletion responses with Mem0 SDK

Accept successful HTTP responses and parse JSON without fixed acknowledgement rules, retaining exact post-delete absence verification.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(external-context): Clarify deletion confirmation and cover success statuses

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
Co-authored-by: Shaojin Wen <[email protected]>
2026-09-09 07:09:28 +00:00
Bob.qwencodeandgithub-actions[bot] c26f6d299f chore(release): v0.23.1 (#11400)
* chore(release): v0.23.1

* docs(changelog): sync for v0.23.1

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-08 17:01:17 +00:00
jinyeandQwen-Coder ab33974509 feat(external-context): Add daemon memory deletion (#11337)
Add an opt-in workspace-bound deletion profile with exact target reads,
full-text and scope verification, single-shot deletion, and absence checks.
Preserve full record identifiers and cover approval and failure boundaries.

Co-authored-by: Qwen-Coder <[email protected]>
2026-09-08 09:30:06 +00:00