Files
codewhale/npm/deepseek-tui/scripts/artifacts.js
T
Claude 0e5afe0b01 feat(v0.8.8): linux ARM64 prebuilts + install docs overhaul
Triggered by a Telegram report from a Chinese user trying to deploy
DeepSeek TUI on a HarmonyOS ARM64 thin-and-light: `npm i -g deepseek-tui`
exited with `Unsupported architecture: arm64 on platform linux` because
v0.8.7 only published x64 Linux artifacts. They worked around it with
`cargo install`, but the README never documented that path for ARM users.

This PR closes that gap on three layers:

- **Release workflow** — add `aarch64-unknown-linux-gnu` to the build
  matrix using GitHub's `ubuntu-24.04-arm` runner. v0.8.8 will publish
  `deepseek-linux-arm64` and `deepseek-tui-linux-arm64` alongside the
  existing x64/macOS/Windows assets, plus add the row to the Release
  body's manual-download table.

- **npm wrapper** — uncomment the linux/arm64 row in `ASSET_MATRIX`,
  rewrite the `Unsupported architecture/platform` error to print the
  full `cargo install deepseek-tui-cli deepseek-tui --locked` recipe
  and link to docs/INSTALL.md, and add `DEEPSEEK_TUI_OPTIONAL_INSTALL=1`
  so CI matrices that include unsupported platforms can keep running
  without a binary.

- **Docs** — new docs/INSTALL.md covering every supported platform,
  prebuilt vs. cargo install vs. manual download, cross-compiling x64
  -> ARM64 with `cross` or `gcc-aarch64-linux-gnu`, China mirror setup,
  and a troubleshooting section for the common arm64, MISSING_COMPANION_BINARY,
  and self-update arch-mapping (#503) errors. README and README.zh-CN
  now have an explicit Linux ARM64 quickstart pointing at `cargo install`
  for v0.8.7 today and `npm i -g` for v0.8.8+; the v0.8.7 known-issue
  block is updated to mention both #503 and the missing arm64 prebuilt.

https://claude.ai/code/session_01Fg1FKMtDxVnC4pp6bNBRCS
2026-05-03 04:42:53 +00:00

120 lines
3.4 KiB
JavaScript

const path = require("path");
const os = require("os");
const CHECKSUM_MANIFEST = "deepseek-artifacts-sha256.txt";
const ASSET_MATRIX = {
linux: {
x64: ["deepseek-linux-x64", "deepseek-tui-linux-x64"],
arm64: ["deepseek-linux-arm64", "deepseek-tui-linux-arm64"],
},
darwin: {
x64: ["deepseek-macos-x64", "deepseek-tui-macos-x64"],
arm64: ["deepseek-macos-arm64", "deepseek-tui-macos-arm64"],
},
win32: {
x64: ["deepseek-windows-x64.exe", "deepseek-tui-windows-x64.exe"],
},
};
function detectBinaryNames() {
const platform = os.platform();
const arch = os.arch();
const defaults = ASSET_MATRIX[platform];
if (!defaults) {
const supported = Object.keys(ASSET_MATRIX).map(p => `'${p}'`).join(', ');
throw new Error(
`Unsupported platform: ${platform}. Supported platforms: ${supported}.\n\n` +
unsupportedBuildHint(),
);
}
const pair = defaults[arch];
if (!pair) {
const supported = Object.keys(defaults).map(a => `'${a}'`).join(', ');
throw new Error(
`Unsupported architecture: ${arch} on platform ${platform}. ` +
`Supported architectures: ${supported}.\n\n` +
unsupportedBuildHint(),
);
}
return {
platform,
arch,
deepseek: pair[0],
tui: pair[1],
};
}
function unsupportedBuildHint() {
return [
"No prebuilt binary is available for this platform/architecture combo.",
"You can still run DeepSeek TUI by building from source with Cargo:",
"",
" # Requires Rust 1.85+ (https://rustup.rs)",
" cargo install deepseek-tui-cli --locked # provides `deepseek`",
" cargo install deepseek-tui --locked # provides `deepseek-tui`",
"",
"Or build from a checkout:",
"",
" git clone https://github.com/Hmbown/DeepSeek-TUI.git",
" cd DeepSeek-TUI",
" cargo install --path crates/cli --locked",
" cargo install --path crates/tui --locked",
"",
"See https://github.com/Hmbown/DeepSeek-TUI/blob/main/docs/INSTALL.md",
"for cross-compilation, mirror, and Linux ARM64 specifics.",
].join("\n");
}
function executableName(base, platform) {
return platform === "win32" ? `${base}.exe` : base;
}
function releaseBaseUrl(version, repo = "Hmbown/DeepSeek-TUI") {
const override =
process.env.DEEPSEEK_TUI_RELEASE_BASE_URL || process.env.DEEPSEEK_RELEASE_BASE_URL;
if (override) {
const trimmed = String(override).trim();
return trimmed.endsWith("/") ? trimmed : `${trimmed}/`;
}
return `https://github.com/${repo}/releases/download/v${version}/`;
}
function releaseAssetUrl(baseName, version, repo = "Hmbown/DeepSeek-TUI") {
return new URL(baseName, releaseBaseUrl(version, repo)).toString();
}
function checksumManifestUrl(version, repo = "Hmbown/DeepSeek-TUI") {
return releaseAssetUrl(CHECKSUM_MANIFEST, version, repo);
}
function releaseBinaryDirectory() {
return path.join(__dirname, "..", "bin", "downloads");
}
function allAssetNames() {
const names = [];
for (const platformAssets of Object.values(ASSET_MATRIX)) {
for (const pair of Object.values(platformAssets)) {
names.push(pair[0], pair[1]);
}
}
return Array.from(new Set(names));
}
function allReleaseAssetNames() {
return [...allAssetNames(), CHECKSUM_MANIFEST];
}
module.exports = {
allAssetNames,
allReleaseAssetNames,
CHECKSUM_MANIFEST,
checksumManifestUrl,
detectBinaryNames,
executableName,
releaseAssetUrl,
releaseBaseUrl,
releaseBinaryDirectory,
};