Skip to content

Commit c59b0df

Browse files
authored
Merge branch 'main' into chat-model-thinking-selector
2 parents 416e0ea + f7ec103 commit c59b0df

265 files changed

Lines changed: 10673 additions & 1154 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/code-qa.yml‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,33 @@ jobs:
9191
- name: Check types
9292
run: pnpm check-types
9393

94+
build-vsix:
95+
name: Build test VSIX
96+
if: github.event_name == 'pull_request'
97+
runs-on: ubuntu-latest
98+
steps:
99+
- name: Checkout code
100+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
101+
with:
102+
persist-credentials: false
103+
- name: Setup Node.js and pnpm
104+
uses: ./.github/actions/setup-node-pnpm
105+
with:
106+
install-args: "--frozen-lockfile"
107+
- name: Build workspace packages
108+
run: |
109+
pnpm --filter @roo-code/build build
110+
pnpm --filter @roo-code/vscode-webview build
111+
- name: Package extension
112+
run: pnpm --filter ./src vsix
113+
- name: Upload test VSIX
114+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
115+
with:
116+
name: zoo-code-vsix-pr-${{ github.event.pull_request.number }}
117+
path: bin/*.vsix
118+
if-no-files-found: error
119+
retention-days: 7
120+
94121
unit-test:
95122
name: platform-unit-test (${{ matrix.name }})
96123
runs-on: ${{ matrix.os }}

‎.github/workflows/visual-regression.yml‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ on:
55
pull_request:
66
types: [opened, reopened, ready_for_review, synchronize]
77
paths:
8+
- "apps/vscode-e2e/package.json"
9+
- "apps/vscode-e2e/src/theme-fixtures/**"
10+
- "packages/types/src/api.ts"
11+
- "packages/types/src/vscode-extension-host.ts"
12+
- "src/core/webview/ClineProvider.ts"
13+
- "src/core/webview/webviewMessageHandler.ts"
14+
- "src/extension/api.ts"
815
- "webview-ui/**"
916
- "src/shared/**"
1017
- "package.json"
@@ -55,3 +62,32 @@ jobs:
5562
webview-ui/playwright-report
5663
webview-ui/test-results
5764
if-no-files-found: ignore
65+
66+
theme-fixtures:
67+
runs-on: ubuntu-latest
68+
timeout-minutes: 15
69+
steps:
70+
- name: Checkout code
71+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
72+
with:
73+
persist-credentials: false
74+
- name: Setup Node.js and pnpm
75+
uses: ./.github/actions/setup-node-pnpm
76+
with:
77+
install-args: "--frozen-lockfile"
78+
- name: Install xvfb
79+
run: sudo apt-get install -y xvfb
80+
- name: Get pinned VS Code version
81+
id: vscode-version
82+
run: |
83+
VERSION=$(node -p 'require("./apps/vscode-e2e/package.json").devDependencies["@types/vscode"]')
84+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
85+
- name: Cache pinned VS Code
86+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
87+
with:
88+
path: apps/vscode-e2e/.vscode-test/
89+
key: vscode-theme-fixtures-${{ runner.os }}-${{ steps.vscode-version.outputs.version }}-v1
90+
- name: Test theme fixture serialization
91+
run: pnpm --filter @roo-code/vscode-e2e themes:test
92+
- name: Check generated VS Code theme fixtures
93+
run: xvfb-run -a pnpm --filter @roo-code/vscode-e2e themes:check

‎CHANGELOG.md‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
# Zoo Code Changelog
22

3+
## [3.80.0]
4+
5+
### Minor Changes
6+
7+
- Add separate Read and Write allowlists so users can restrict file operations to approved paths (#1273 by @nh2, PR #1274 by @nh2)
8+
- Add official GLM 5.3 support to the Z.ai API (PR #1284 by @app/zoomote)
9+
- Add Gemini 3.5 Flash Lite and Gemini 3.1 Flash Lite to the Gemini API provider (#1251 by @MrMody0, PR #1334 by @easonLiangWorldedtech)
10+
- Prevent webview gray screens and out-of-memory failures by throttling extension-state pushes (#629 by @edelauna, PR #1078 by @JunyongParkDev)
11+
- Recover stale delegated child tasks after an extension restart (#1100 by @aniruddhabag3, PR #1210 by @edelauna)
12+
- Replace the shared task-history index with atomic per-task merges to prevent lost or corrupted history (#1231 by @martin-rueegg, PR #1261 by @edelauna)
13+
- Mark interrupted tool calls as errors in persisted task history so resumed conversations remain consistent (#1283 by @martin-rueegg, PR #1323 by @easonLiangWorldedtech)
14+
- Complete OpenAI Codex prompts over the streaming transport instead of waiting indefinitely (#1242 by @Rafael-Silva-Oliveira, PR #1243 by @Rafael-Silva-Oliveira)
15+
- Stream LM Studio `reasoning_content` so model reasoning is preserved in responses (#1075 by @marunguy, PR #1175 by @daewoongoh)
16+
- Fix NanoGPT Muse Spark tool-use requests (PR #1310 by @app/zoomote)
17+
- Make settings import await provider-state persistence before reporting success (PR #1340 by @app/zoomote)
18+
- Default telemetry to opt-out and require explicit consent through the telemetry UI (PR #1069 by @edelauna)
19+
- Introduce an SDK-agnostic request configuration builder for consistent abort-signal support (#1007 by @easonLiangWorldedtech, PR #1008 by @easonLiangWorldedtech)
20+
- Delegate VS Code shell-profile reads to Terminal methods for more reliable profile detection (#634 by @marty-a11y, PR #1033 by @edelauna)
21+
- Increase the Semble archive download limit for larger codebase-intelligence binaries (#1305 by @navedmerchant, PR #1306 by @navedmerchant)
22+
- Stop estimating Zoo Gateway UI costs from unrelated default-model prices when authoritative cost data is unavailable (PR #1339 by @JamesRobert20)
23+
- Improve Mermaid label contrast in light IDE themes (PR #1285 by @app/zoomote)
24+
- Keep chat controls legible in light IDE themes (PR #1298 by @app/zoomote)
25+
- Fix the remaining chat controls that faded into light IDE themes (PR #1312 by @app/zoomote)
26+
- Improve shared-control contrast across IDE themes (PR #1333 by @app/zoomote)
27+
- Canonicalize provider and model identifiers in webview messages (PR #1143 by @WebMad)
28+
- Canonicalize model-router calls across providers (PR #1165 by @WebMad)
29+
- Enforce canonical provider identifiers through provider lint rules (#1294 by @WebMad, PR #1297 by @WebMad)
30+
- Enforce safe asynchronous handling in core tools (PR #1255 by @app/zoomote)
31+
- Build downloadable VSIX artifacts for pull requests (PR #1314 by @app/zoomote)
32+
333
## [3.78.0]
434

535
### Minor Changes

‎PRIVACY.md‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Zoo Code Privacy Policy
22

3-
**Last Updated: May 13th, 2026**
3+
**Last Updated: August 15th, 2026**
44

55
Zoo Code respects your privacy and is committed to transparency about how we
66
handle your data. Below is a simple breakdown of where key pieces of data
@@ -32,14 +32,18 @@ go—and, importantly, where they don't.
3232
- **API Keys & Credentials**: If you enter an API key (e.g., to connect an AI
3333
model), it is stored locally on your device and never sent to us or any third
3434
party, except the provider you have chosen.
35-
- **Telemetry (Usage Data)**: We collect feature usage and error data to help
36-
us improve Zoo Code. This telemetry is powered by PostHog and includes your
37-
VS Code machine ID, feature usage patterns, and exception reports. The VS Code
35+
- **Telemetry (Usage Data)**: We collect feature usage and error data to help us
36+
improve Zoo Code. This telemetry is powered by PostHog and includes your VS
37+
Code machine ID, feature usage patterns, and exception reports. The VS Code
3838
machine ID is a persistent identifier and may be considered personal data in
3939
some jurisdictions; we use it only for product analytics and error grouping.
40-
We retain telemetry only as long as needed for product analytics and debugging.
41-
Telemetry does **not** collect your code or AI prompts, and you can opt out at
42-
any time through the settings.
40+
PostHog event data is retained for 12 months under our current project
41+
configuration. This PostHog-based telemetry does **not** collect your code or AI
42+
prompts. Telemetry is on by default. To turn it off, choose "Disabled" in
43+
the settings or in the notice shown on first use. The notice remains until
44+
you explicitly Accept or Decline. Telemetry also follows VS Code's own
45+
global telemetry setting: if you turn that off, Zoo Code stops sending
46+
telemetry right away, even if the Zoo Code setting says "Enabled."
4347
- **Marketplace Requests**: When you browse or search the Marketplace for Model
4448
Configuration Profiles (MCPs) or Custom Modes, Zoo Code makes a secure API
4549
call to Zoo Code's backend servers to retrieve listing information. These

‎README.md‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,11 @@ Zoo Code builds on the foundation created by Roo Code and continues to expand it
4646
- **More dependable terminal and editing workflows** — fixes for premature terminal completion, task-state races, context management, diff editing, and provider-specific tool use.
4747
- **More control over your workspace** — rules management, per-mode MCP restrictions, multi-root path controls, model reasoning options, and completion change review actions.
4848

49-
## What's New in v3.78.0
49+
## What's New in v3.80.0
5050

51-
- **Three major new models have arrived** — use the brand-new Gemini 3.7 Flash, GLM 5.3, and Qwen3.8 Max models, plus updated DeepSeek V4 reasoning, pricing, and provider coverage.
52-
- **Connect to NanoGPT** — use dynamic model discovery, streaming and prompt completions, and routing preferences for speed, price, latency, throughput, tool support, and caching.
53-
- **More reliable providers and tasks** — fixes improve Azure OpenAI endpoint setup, Kimi Code output limits, task-history title preservation, and Zoo settings import/export.
54-
- Destructive Command Guard now supports Intel-based Macs.
55-
- Security updates address vulnerabilities in `undici` and Mermaid.
51+
- **Safer file access** — use separate Read and Write allowlists to control which paths Zoo Code can access.
52+
- **More model choice** — GLM 5.3 is now available through Z.ai, with Gemini 3.5 Flash Lite and Gemini 3.1 Flash Lite added to the Gemini provider.
53+
- **More reliable everyday workflows** — improvements strengthen task recovery and history, provider streaming and tool use, settings imports, and readability across IDE themes.
5654

5755
<details>
5856
<summary>🌐 Available languages</summary>

‎apps/vscode-e2e/package.json‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
"test:ci:mock": "pnpm -w bundle && pnpm --filter @roo-code/vscode-webview build && USE_MOCK=true pnpm test:run",
1010
"test:record": "AIMOCK_RECORD=true pnpm test:ci",
1111
"test:run": "rimraf out && tsc -p tsconfig.json && dotenv -e .env.local -- node ./out/runTest.js",
12+
"themes:build": "pnpm -w bundle && pnpm --filter @roo-code/vscode-webview build && rimraf out && tsc -p tsconfig.json",
13+
"themes:update": "pnpm themes:build && node ./out/theme-fixtures/generate.js update",
14+
"themes:check": "pnpm themes:build && node ./out/theme-fixtures/generate.js check",
15+
"themes:test": "pnpm --filter @roo-code/types build && rimraf out && tsc -p tsconfig.json && node --test ./out/theme-fixtures/fixtures.test.js",
1216
"clean": "rimraf out .turbo"
1317
},
1418
"devDependencies": {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
export const themeFixtureDefinitions = [
2+
{
3+
name: "dark",
4+
themeId: "Default Dark Modern",
5+
bodyClass: "vscode-dark",
6+
colorScheme: "dark",
7+
kind: "dark",
8+
},
9+
{
10+
name: "light",
11+
themeId: "Default Light Modern",
12+
bodyClass: "vscode-light",
13+
colorScheme: "light",
14+
kind: "light",
15+
},
16+
{
17+
name: "high-contrast",
18+
themeId: "Default High Contrast",
19+
bodyClass: "vscode-high-contrast",
20+
colorScheme: "dark",
21+
kind: "high-contrast",
22+
},
23+
{
24+
name: "high-contrast-light",
25+
themeId: "Default High Contrast Light",
26+
bodyClass: "vscode-high-contrast-light",
27+
colorScheme: "light",
28+
kind: "high-contrast-light",
29+
},
30+
] as const
31+
32+
export type ThemeFixtureDefinition = (typeof themeFixtureDefinitions)[number]
33+
34+
export function getThemeFixtureFileName(theme: ThemeFixtureDefinition): string {
35+
return `vscode-theme-${theme.name}.css`
36+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import fs from "fs/promises"
2+
3+
import * as vscode from "vscode"
4+
5+
import type { RooCodeTestAPI, WebviewThemeFixture } from "@roo-code/types"
6+
7+
import { themeFixtureDefinitions, type ThemeFixtureDefinition } from "./definitions"
8+
9+
const POLL_INTERVAL_MS = 100
10+
const THEME_TIMEOUT_MS = 20_000
11+
12+
const colorThemeKinds: Record<ThemeFixtureDefinition["kind"], vscode.ColorThemeKind> = {
13+
dark: vscode.ColorThemeKind.Dark,
14+
light: vscode.ColorThemeKind.Light,
15+
"high-contrast": vscode.ColorThemeKind.HighContrast,
16+
"high-contrast-light": vscode.ColorThemeKind.HighContrastLight,
17+
}
18+
19+
async function poll<T>(capture: () => Promise<T>, matches: (value: T) => boolean, description: string): Promise<T> {
20+
const deadline = Date.now() + THEME_TIMEOUT_MS
21+
let latest: T | undefined
22+
23+
while (Date.now() < deadline) {
24+
latest = await capture()
25+
if (matches(latest)) {
26+
return latest
27+
}
28+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS))
29+
}
30+
31+
throw new Error(`Timed out waiting for ${description}; latest value: ${JSON.stringify(latest)}`)
32+
}
33+
34+
function matchesTheme(fixture: WebviewThemeFixture, theme: ThemeFixtureDefinition): boolean {
35+
return fixture.themeId === theme.themeId && fixture.bodyClass.split(/\s+/).includes(theme.bodyClass)
36+
}
37+
38+
export async function run(): Promise<void> {
39+
if (process.env.ROO_CODE_THEME_FIXTURE_PROBE !== "1") {
40+
throw new Error("ROO_CODE_THEME_FIXTURE_PROBE must be set to 1")
41+
}
42+
43+
const outputPath = process.env.ROO_CODE_THEME_FIXTURE_CAPTURE_PATH
44+
const expectedVersion = process.env.ROO_CODE_THEME_FIXTURE_VSCODE_VERSION
45+
if (!outputPath || !expectedVersion) {
46+
throw new Error("Theme fixture output path and VS Code version are required")
47+
}
48+
if (vscode.version !== expectedVersion) {
49+
throw new Error(`Expected VS Code ${expectedVersion}, launched ${vscode.version}`)
50+
}
51+
52+
const extension = vscode.extensions.getExtension<RooCodeTestAPI>("ZooCodeOrganization.zoo-code")
53+
if (!extension) {
54+
throw new Error("Zoo Code extension not found")
55+
}
56+
const api = extension.isActive ? extension.exports : await extension.activate()
57+
58+
await vscode.commands.executeCommand("zoo-code.SidebarProvider.focus")
59+
await poll(async () => api.isReady(), Boolean, "Zoo Code webview activation")
60+
61+
const captures: Record<string, WebviewThemeFixture> = {}
62+
for (const theme of themeFixtureDefinitions) {
63+
await vscode.workspace
64+
.getConfiguration("workbench")
65+
.update("colorTheme", theme.themeId, vscode.ConfigurationTarget.Global)
66+
await poll(
67+
async () => vscode.window.activeColorTheme.kind,
68+
(kind) => kind === colorThemeKinds[theme.kind],
69+
`${theme.themeId} color theme kind`,
70+
)
71+
captures[theme.name] = await poll(
72+
() => api.captureWebviewThemeFixture(),
73+
(fixture) => matchesTheme(fixture, theme),
74+
`${theme.themeId} webview identity`,
75+
)
76+
}
77+
78+
await fs.writeFile(outputPath, `${JSON.stringify(captures, null, 2)}\n`, "utf8")
79+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import assert from "node:assert/strict"
2+
import test from "node:test"
3+
4+
import type { WebviewThemeFixture } from "@roo-code/types"
5+
6+
import { themeFixtureDefinitions } from "./definitions"
7+
import { createSerializedFixtures, findDriftedFixtures, serializeThemeFixture } from "./fixtures"
8+
9+
const validVariables = Object.fromEntries(
10+
Array.from({ length: 100 }, (_, index) => [`--vscode-test-${index}`, "#000000"]),
11+
)
12+
const validFixture: WebviewThemeFixture = {
13+
themeId: "Default Dark Modern",
14+
bodyClass: "vscode-dark",
15+
variables: {
16+
...validVariables,
17+
"--vscode-foreground": "#cccccc",
18+
"--vscode-editor-background": "#1f1f1f",
19+
"--vscode-button-foreground": "#ffffff",
20+
},
21+
}
22+
23+
test("serializeThemeFixture sorts variables and emits stable metadata", () => {
24+
const fixture: WebviewThemeFixture = {
25+
themeId: "Default Dark Modern",
26+
bodyClass: "vscode-dark",
27+
variables: {
28+
"--vscode-z-last": "rgb(2, 2, 2)",
29+
"--vscode-a-first": "#010101",
30+
"--vscode-font-family": "platform-dependent",
31+
},
32+
}
33+
34+
assert.equal(
35+
serializeThemeFixture(themeFixtureDefinitions[0], fixture, "1.100.0"),
36+
[
37+
"/* Generated from Default Dark Modern by VS Code 1.100.0. Do not edit manually. */",
38+
".vscode-dark {",
39+
"\tcolor-scheme: dark;",
40+
"\t--vscode-a-first: #010101;",
41+
"\t--vscode-z-last: rgb(2, 2, 2);",
42+
"}",
43+
"",
44+
].join("\n"),
45+
)
46+
})
47+
48+
test("findDriftedFixtures reports missing and changed files in sorted order", () => {
49+
const expected = new Map([
50+
["vscode-theme-light.css", "light"],
51+
["vscode-theme-dark.css", "dark"],
52+
])
53+
const actual = new Map<string, string | undefined>([["vscode-theme-light.css", "stale"]])
54+
55+
assert.deepEqual(findDriftedFixtures(expected, actual), ["vscode-theme-dark.css", "vscode-theme-light.css"])
56+
})
57+
58+
test("createSerializedFixtures rejects incomplete captures", () => {
59+
const fixture: WebviewThemeFixture = {
60+
...validFixture,
61+
variables: {
62+
...validVariables,
63+
"--vscode-foreground": "#cccccc",
64+
"--vscode-editor-background": "#1f1f1f",
65+
},
66+
}
67+
68+
assert.throws(
69+
() => createSerializedFixtures(new Map([["dark", fixture]]), "1.100.0", [themeFixtureDefinitions[0]]),
70+
/--vscode-button-foreground/,
71+
)
72+
})
73+
74+
test("createSerializedFixtures rejects an empty capture", () => {
75+
assert.throws(
76+
() =>
77+
createSerializedFixtures(new Map([["dark", { ...validFixture, variables: {} }]]), "1.100.0", [
78+
themeFixtureDefinitions[0],
79+
]),
80+
/fewer than 100/,
81+
)
82+
})
83+
84+
test("createSerializedFixtures rejects the wrong theme identity", () => {
85+
assert.throws(
86+
() =>
87+
createSerializedFixtures(
88+
new Map([["dark", { ...validFixture, themeId: "Default Light Modern" }]]),
89+
"1.100.0",
90+
[themeFixtureDefinitions[0]],
91+
),
92+
/Expected Default Dark Modern/,
93+
)
94+
})

0 commit comments

Comments
 (0)