diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 3eaf57f56a..fd84cbaa62 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -9,7 +9,7 @@ "scripts": { "test:installer": "node scripts/test-windows-installer.mjs", "build": "tsc -b && pnpm run bundle", - "bundle": "tsdown", + "bundle": "tsdown --config-loader native", "dev": "tsx scripts/dev.ts", "start": "tsx scripts/dev.ts --skip-build", "test:updates:local": "pnpm run build && node scripts/test-local-updater.mjs", diff --git a/docs/development.i18n.yaml b/docs/development.i18n.yaml index 0a4130454d..904fdd17cb 100644 --- a/docs/development.i18n.yaml +++ b/docs/development.i18n.yaml @@ -9,8 +9,8 @@ en: 5207d17725c07a27 zh: 258884c4300ac63a /development-guide/setup-tutorial/prerequisites: - en: 6078798f0fda1347 - zh: ea73704c4ec4f2a9 + en: a8543c278338a02d + zh: b5790c5fea7c0bc6 /development-guide/setup-tutorial/windows-and-wsl-2: en: e86be579be6f1813 zh: 14f6a220337d0861 diff --git a/docs/development.md b/docs/development.md index 847f4235a9..d2f3ff337f 100644 --- a/docs/development.md +++ b/docs/development.md @@ -9,6 +9,7 @@ The setup tutorial takes a new contributor from prerequisites to a checked check ### Prerequisites - Node.js supports 22.19+ and 24+. CI covers 22.19, 24, and 26; see the [Node engine floor Agent Note](../.agents/notes/implemented/process/2026-07-06-node-engine-floor.md). +- Node.js TypeScript type stripping enabled. The repository build scripts load `tsdown.config.ts` with tsdown's native config loader, so they fail when `--no-experimental-strip-types` is in `NODE_OPTIONS` or the Node.js build lacks TypeScript support; `pnpm run build` checks this first and names the cause. - Corepack-enabled pnpm. The repo pins `pnpm@11.7.0` in `package.json`; run `corepack enable` if `pnpm --version` does not resolve through Corepack. - Git 2.26 or newer; hook setup enables Git's worktree-specific configuration extension. - Optional: a DeepSeek API key for the Web, headless, and ACP automation demos and real-API e2e tests. diff --git a/docs/development.zh.md b/docs/development.zh.md index eb56870e25..0ad92e883d 100644 --- a/docs/development.zh.md +++ b/docs/development.zh.md @@ -11,6 +11,7 @@ ### 前置条件 - Node.js 支持 22.19+ 与 24+。CI 覆盖 22.19、24 和 26;见 [Node 引擎下限 Agent Note](../.agents/notes/implemented/process/2026-07-06-node-engine-floor.zh.md)。 +- 启用 Node.js TypeScript 类型剥离。仓库构建脚本用 tsdown 的 native 配置加载器加载 `tsdown.config.ts`,因此当 `NODE_OPTIONS` 含 `--no-experimental-strip-types` 或 Node.js 构建缺少 TypeScript 支持时会失败;`pnpm run build` 会先检查这一条件并指出原因。 - 启用了 Corepack 的 pnpm。仓库在 `package.json` 中固定使用 `pnpm@11.7.0`;如果 `pnpm --version` 无法通过 Corepack 解析,请先运行 `corepack enable`。 - Git 2.26 或更高版本;钩子设置会启用 Git 的 worktree 专属配置扩展。 - 可选:一个 DeepSeek API key,用于 Web、headless 和 ACP(Agent Client Protocol)自动化 agent(智能体)演示以及真实 API 的 e2e 测试。 diff --git a/package.json b/package.json index 75d586f00f..bd57f507ef 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,11 @@ "scripts": { "prepare:primary-runtime": "tsx scripts/primary-runtime/prepare.ts", "build": "tsx scripts/build.ts", - "build:bench": "npm run build:native-system && npm run build:lib && tsdown --config benchmarks/tsdown.config.ts", + "build:bench": "npm run build:native-system && npm run build:lib && tsdown --config-loader native --config benchmarks/tsdown.config.ts", "build:official": "tsx scripts/build.ts --profile official", "build:lib": "pnpm run build:lib:host && pnpm run build:lib:client", - "build:lib:host": "node --max-old-space-size=4096 ./node_modules/typescript/bin/tsc -b tsconfig.host.json && tsdown --env.DSH_BUILD_FACE host && pnpm --filter @deepseek-ai/dsh-desktop run bundle", - "build:lib:client": "tsc -b tsconfig.client.json && tsdown --env.DSH_BUILD_FACE client", + "build:lib:host": "node --max-old-space-size=4096 ./node_modules/typescript/bin/tsc -b tsconfig.host.json && tsdown --config-loader native --env.DSH_BUILD_FACE host && pnpm --filter @deepseek-ai/dsh-desktop run bundle", + "build:lib:client": "tsc -b tsconfig.client.json && tsdown --config-loader native --env.DSH_BUILD_FACE client", "build:web": "pnpm --filter @deepseek-ai/dsh-web-frontend run build", "build:desktop": "pnpm --filter @deepseek-ai/dsh-desktop run build", "dev:desktop": "pnpm --filter @deepseek-ai/dsh-desktop run dev", diff --git a/scripts/build.spec.ts b/scripts/build.spec.ts new file mode 100644 index 0000000000..07f5f8b98f --- /dev/null +++ b/scripts/build.spec.ts @@ -0,0 +1,18 @@ +import { spawnSync } from 'node:child_process' +import { resolve } from 'node:path' +import { describe, expect, it } from 'vitest' + +const root = resolve(import.meta.dirname, '..') + +describe('repository build CLI', () => { + // The sentinel makes parseArgs fail fast if the check ever stops running first. + it('rejects a Node process without TypeScript type stripping before any build step', () => { + const result = spawnSync( + process.execPath, + ['--no-experimental-strip-types', '--import', 'tsx/esm', resolve(root, 'scripts/build.ts'), '--spec-sentinel'], + { cwd: root, encoding: 'utf8' }, + ) + expect(result.status).not.toBe(0) + expect(result.stderr).toContain('build: Node.js TypeScript type stripping is unavailable') + }) +}) diff --git a/scripts/build.ts b/scripts/build.ts index e64fd1486e..a7b06bda65 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -30,6 +30,10 @@ function runScript(script: string, environment: NodeJS.ProcessEnv): void { /** Run the full build selected by `--profile` or `DSH_BUILD_CLIENT_PROFILE`. */ function main(): void { + // tsdown.config.ts loads only through Node type stripping (`--config-loader native`); this names the cause before tsdown fails. + if (!process.features.typescript) { + throw new Error('build: Node.js TypeScript type stripping is unavailable in this Node.js process; remove --no-experimental-strip-types from NODE_OPTIONS or use a Node.js build with TypeScript support') + } const { values } = parseArgs({ options: { profile: { type: 'string' } }, allowPositionals: false, diff --git a/scripts/dev-web.ts b/scripts/dev-web.ts index bc64d8c0de..d0c87bfb7b 100644 --- a/scripts/dev-web.ts +++ b/scripts/dev-web.ts @@ -187,6 +187,7 @@ export async function watchClientPlugins( const bundles = await build({ cwd: root, workspace: [...pluginDirs], + configLoader: 'native', watch: true, // Workspace hooks override inline hooks; onSuccess runs after each package's build:done work. onSuccess: (options) => { diff --git a/scripts/run-gates.spec.ts b/scripts/run-gates.spec.ts index 740c3a760c..76bcafb3ed 100644 --- a/scripts/run-gates.spec.ts +++ b/scripts/run-gates.spec.ts @@ -258,7 +258,7 @@ describe('gate graph validation', () => { }) expect(scripts['test:bench']).toBe('npm run build:bench && npm run build:web && npm run test:bench:built') expect(scripts['build:bench']).toBe( - 'npm run build:native-system && npm run build:lib && tsdown --config benchmarks/tsdown.config.ts', + 'npm run build:native-system && npm run build:lib && tsdown --config-loader native --config benchmarks/tsdown.config.ts', ) expect(scripts['build:native-system']).toBe('tsx native/system/scripts/build.ts --host-addon-only') expect(scripts['test:bench:built']).toBe('vitest run --config vitest.bench.config.ts')