Files
deepseek-harness/apps/desktop/scripts/build-harness.mjs
T
Pine 79ae82fa48 feat(desktop): Chinese menu, branded icon, and a self-contained harness bundle
Localizes the Electron application menu (文件/编辑/视图/窗口/帮助 plus the
macOS app menu), adds a branded 1024px app icon (window + per-target icns/ico),
and makes the packaged app fully self-contained. Because the harness's pnpm
workspace does not cleanly materialize via pnpm deploy or electron-builder's
dependency resolution (per-package symlinks to vendored sources, native addons,
a separate frontend dist), scripts/build-harness.mjs assembles the repository's
working runtime — node_modules, vendor, packages, native, apps/cli, apps/web,
and a bundled Node binary — into build/harness. electron-builder ships it as an
extraResource at Resources/harness, and the main process spawns that bundled
node + dsh entry when packaged (keeping the system-Node child during dev). Adds
a comprehensive README and ignores the multi-GB harness/dist from git.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 17:39:26 +08:00

47 lines
2.0 KiB
JavaScript

#!/usr/bin/env node
/**
* Assemble the self-contained harness runtime for the packaged app.
*
* The harness's pnpm workspace does not cleanly materialize via `pnpm deploy` or
* electron-builder's dependency resolution (per-package symlinks to vendored
* packages, native addons, a separate frontend dist). The only known-good
* runtime is the repository's own working tree, so this copies the parts the
* harness needs at the same relative layout — node_modules, vendor, packages,
* native, apps/cli, apps/web — plus the platform Node binary, into
* `build/harness`, which electron-builder ships as `extraResources`.
*
* Run from the repository root before `desktop:pack`.
*/
import { cpSync, chmodSync, existsSync, mkdirSync, rmSync } from 'node:fs'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { execFileSync } from 'node:child_process'
const root = resolve(dirname(fileURLToPath(import.meta.url)), '../../..')
const out = join(root, 'apps/desktop/build/harness')
// Dirs whose relative layout must be preserved so node_modules symlinks resolve.
const harnessDirs = ['node_modules', 'vendor', 'packages', 'native']
const extraDirs = [['apps/cli', 'apps/cli'], ['apps/web', 'apps/web']]
rmSync(out, { recursive: true, force: true })
mkdirSync(join(out, 'apps'), { recursive: true })
mkdirSync(join(out, 'bin'), { recursive: true })
for (const d of harnessDirs) {
const src = join(root, d)
if (existsSync(src)) cpSync(src, join(out, d), { recursive: true })
}
for (const [src, dst] of extraDirs) {
cpSync(join(root, src), join(out, dst), { recursive: true })
}
// Bundle the platform Node binary for the harness child.
const nodeBin = execFileSync('node', ['-e', 'process.stdout.write(process.execPath)']).toString()
if (!existsSync(nodeBin)) throw new Error(`node executable not found: ${nodeBin}`)
cpSync(nodeBin, join(out, 'bin/node'))
chmodSync(join(out, 'bin/node'), 0o755)
console.log(`assembled self-contained harness at ${out}`)