# Mirrors the workspaces list in package.json exactly; a new channel must be # added to both files, the same as under npm. A glob here would let a # channel join the pnpm layout silently while npm still ignores it. packages: - 'packages/*' - 'packages/cua-driver/typescript' - 'packages/channels/base' - 'packages/channels/dingtalk' - 'packages/channels/dws' - 'packages/channels/email' - 'packages/channels/feishu' - 'packages/channels/github' - 'packages/channels/gitlab' - 'packages/channels/plugin-example' - 'packages/channels/qqbot' - 'packages/channels/telegram' - 'packages/channels/wecom' - 'packages/channels/weixin' - 'integrations/external-context' - 'integrations/external-context-mem0' - 'integrations/test-failure-explorer' - 'integrations/generated-ui' - '!packages/desktop' - '!packages/live-host' - '!packages/mobile-shell' # npm links every workspace package into the root node_modules; pnpm links # one only where it is a declared dependency. The root package therefore # declares, as file: devDependencies, the workspace packages that root-level # code (integration-tests/, scripts/) imports, and .pnpmfile.mjs rewrites them # to workspace:* like every other internal dependency. nodeLinker: 'hoisted' # The root postinstall runs patch-package, which rewrites files inside # node_modules in place. Under the default import method those files are # hard links into the content-addressable store, so the patch also rewrites # the store entry -- its contents stop matching the sha512 it is filed # under. Every later worktree then fails its --offline stage with # ERR_PNPM_NO_OFFLINE_TARBALL, falls back to the registry, and re-patches # the store, so the offline path never hits again. Cloning (copy-on-write # where the filesystem supports it, a plain copy elsewhere) keeps the store # entry untouched while patch-package edits only the worktree's own copy. packageImportMethod: 'clone-or-copy' linkWorkspacePackages: true # packages/cli's `tsc --build` exhausts V8's default heap when a build runs # through pnpm: the heap cap the root build script sets lives in NODE_OPTIONS # for the root process, but each package script starts its own `node`, so the # compile gets whatever pnpm hands it. `npm run build` observed the same # growth past 4 GB (#14823), so package scripts get headroom here rather than # on the one entry point that happened to fail first. nodeOptions: '--max-old-space-size=6144' verifyDepsBeforeRun: false fetchRetries: 5 fetchRetryMintimeout: 20000 fetchRetryMaxtimeout: 120000 fetchTimeout: 300000 overrides: 'brace-expansion@1': '1.1.21' 'brace-expansion@2': '2.1.7' typescript: '5.8.3' '@microsoft/api-extractor>typescript': '5.9.3' '@qwen-code/mobile-mcp>typescript': '5.8.2' ansi-regex: '6.2.2' 'cliui>wrap-ansi': '7.0.0' baseline-browser-mapping: '^2.9.19' normalize-package-data: '^7.0.1' react: '^19.2.4' react-dom: '^19.2.4' '@types/react': '^19.2.0' '@types/react-dom': '^19.2.0' axios: '^1.19.0' # @node-rs/jieba-wasm32-wasi brings in @napi-rs/wasm-runtime, which accepts # ^0.10.3. Unpinned it resolves to 0.10.4, published 2026-09-13, which the # minimumReleaseAge gate rejects until it ages out. The gate is enforced by # pnpm itself, and scripts/tests/package-scripts.test.js keeps # minimumReleaseAgeExclude internal-only, so the age-compliant version is # pinned here rather than exempted there. '@tybys/wasm-util': '0.10.3' react-markdown: '^9.0.0' # The root package declares zod 3.25.76 as a devDependency on purpose. With # resolve-peers-from-workspace-root (on by default), every zod peer that a # workspace package does not declare itself resolves to it — the copy npm # hoists. Without it pnpm fills such a peer with the highest locked zod # (4.4.3): web-shell bundles @modelcontextprotocol/ext-apps, whose zod is a # peer, and zod 4 pushed the export renderer past its size budget. It also # covers the override below, which predates it. # packages/acp-bridge declares no zod, so pnpm is free to satisfy the SDK's # `^3.25.0 || ^4.0.0` peer with the highest locked zod, where npm served it # 3.25.76. The split is not cosmetic: the SDK imports `zod` and `zod/v4` from # different modules, so under zod 4 its own `instanceof z.ZodError` test # stops matching and a malformed request answers -32602 instead of -32603. # Pin it so every ACP consumer keeps the behaviour the tests verify. '@agentclientprotocol/sdk>zod': '3.25.76' # web-shell generates its Managed Agent API types with openapi-typescript, # which asks for supports-color 10. A second, higher supports-color in the # graph makes pnpm resolve every `debug` instance's optional supports-color # peer to it, rewriting hundreds of lockfile entries that the hoisted tree # never uses. openapi-typescript only reads `stdout` and `stdout.hasBasic` # to decide whether to colour its logs, and 7.2.0, the version the # repository already installs, exports the same `stdout` (false without a # TTY, which turns colours off). 'openapi-typescript>supports-color': '7.2.0' allowBuilds: '@google/genai': true '@qwen-code/qwen-code-core@file:packages/core': true '@vscode/vsce-sign': true esbuild: true # Darwin-only optional dependency whose install script is only # `node-gyp rebuild`; the macOS smoke install reports no ignored build for # it, so false records the behaviour pnpm already has. The consequence is # that a macOS pnpm worktree runs the prebuilt binding shipped in the # tarball, and where that is missing, vite, tsx, rollup, playwright and # tailwindcss's nested chokidar fall back to fs.watch. All of them are # build and test tooling, never shipped runtime. fsevents: false keytar: true msw: true protobufjs: true minimumReleaseAgeExclude: - '@qwen-code/channel-base'