Merge remote-tracking branch 'origin/rebrand/r3-npm-wrapper' into work/v0.8.41-codewhale-ready
This commit is contained in:
@@ -18,6 +18,7 @@ on:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'Cargo.toml'
|
||||
- 'npm/codewhale/package.json'
|
||||
- 'npm/deepseek-tui/package.json'
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# codewhale
|
||||
|
||||
Install and run the `codewhale` and `codewhale-tui` binaries from GitHub release artifacts.
|
||||
|
||||
> Previously published as `deepseek-tui`. See `docs/REBRAND.md` in the upstream
|
||||
> repository for the migration notes; the legacy `deepseek-tui` npm package
|
||||
> still exists as a deprecation shim for one release cycle.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install -g codewhale
|
||||
# or
|
||||
pnpm add -g codewhale
|
||||
```
|
||||
|
||||
For project-local usage:
|
||||
|
||||
```bash
|
||||
npm install codewhale
|
||||
npx codewhale --help
|
||||
```
|
||||
|
||||
`postinstall` tries to download platform binaries into `bin/downloads/` and
|
||||
exposes `codewhale` and `codewhale-tui` commands. If GitHub release assets are
|
||||
temporarily unreachable, install continues and the wrapper retries the download
|
||||
on first run.
|
||||
|
||||
## First run
|
||||
|
||||
```bash
|
||||
codewhale login --api-key "YOUR_DEEPSEEK_API_KEY"
|
||||
codewhale doctor
|
||||
codewhale
|
||||
```
|
||||
|
||||
The `codewhale` facade and `codewhale-tui` binary share `~/.deepseek/config.toml`
|
||||
for DeepSeek auth and default model settings. Common TUI commands are available
|
||||
directly through the facade, including `codewhale doctor`, `codewhale models`,
|
||||
`codewhale sessions`, and `codewhale resume --last`.
|
||||
|
||||
The app talks to DeepSeek's documented OpenAI-compatible Chat Completions API.
|
||||
Set `DEEPSEEK_BASE_URL` only if you need the China endpoint or DeepSeek beta
|
||||
features such as strict tool mode, chat prefix completion, or FIM completion.
|
||||
|
||||
NVIDIA NIM-hosted DeepSeek V4 Pro is also supported:
|
||||
|
||||
```bash
|
||||
codewhale auth set --provider nvidia-nim --api-key "YOUR_NVIDIA_API_KEY"
|
||||
codewhale --provider nvidia-nim
|
||||
```
|
||||
|
||||
For a single process, set `DEEPSEEK_PROVIDER=nvidia-nim` and `NVIDIA_API_KEY`
|
||||
or `NVIDIA_NIM_API_KEY` (with `DEEPSEEK_API_KEY` as a compatibility fallback).
|
||||
The NIM default model is `deepseek-ai/deepseek-v4-pro` and the default base URL
|
||||
is `https://integrate.api.nvidia.com/v1`. With `--provider nvidia-nim`,
|
||||
`--model deepseek-v4-flash` maps to `deepseek-ai/deepseek-v4-flash`.
|
||||
|
||||
## Supported platforms
|
||||
|
||||
Prebuilt binaries for the GitHub release are downloaded automatically:
|
||||
|
||||
- Linux x64
|
||||
- Linux arm64 (v0.8.8+)
|
||||
- macOS x64 / arm64
|
||||
- Windows x64
|
||||
|
||||
Other platform/architecture combinations (musl, riscv64, FreeBSD, …) aren't
|
||||
shipped as prebuilts. Unsupported platforms, checksum failures, and glibc
|
||||
compatibility problems still fail with a clear error pointing you at
|
||||
`cargo install codewhale-cli codewhale-tui --locked` and the full
|
||||
[docs/INSTALL.md](https://github.com/Hmbown/DeepSeek-TUI/blob/main/docs/INSTALL.md)
|
||||
build-from-source guide.
|
||||
|
||||
## Configuration
|
||||
|
||||
- Default binary version comes from `codewhaleBinaryVersion` in `package.json`
|
||||
(with `deepseekBinaryVersion` as a backward-compat fallback).
|
||||
- Set `DEEPSEEK_TUI_VERSION` or `DEEPSEEK_VERSION` to override the release version.
|
||||
- Set `DEEPSEEK_TUI_GITHUB_REPO` or `DEEPSEEK_GITHUB_REPO` to override the source repo (defaults to `Hmbown/DeepSeek-TUI`).
|
||||
- Set `DEEPSEEK_TUI_RELEASE_BASE_URL` to use an internal or mirrored
|
||||
release-asset directory when GitHub Releases is unavailable. The directory
|
||||
must contain `codewhale-artifacts-sha256.txt` and the platform binaries.
|
||||
- Set `DEEPSEEK_TUI_FORCE_DOWNLOAD=1` to force download even when the cached binary is already present.
|
||||
- Set `DEEPSEEK_TUI_DISABLE_INSTALL=1` to skip install-time download.
|
||||
- Set `DEEPSEEK_TUI_OPTIONAL_INSTALL=1` to make install-time retryable download
|
||||
failures warn and exit `0` instead of failing `npm install`.
|
||||
|
||||
## Release integrity
|
||||
|
||||
- `npm publish` runs a release-asset check to ensure all required binary assets
|
||||
exist for the target GitHub release before publishing.
|
||||
- Install-time downloads are verified against the release checksum manifest before
|
||||
the wrapper marks them executable.
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { runCodewhaleTui } = require("../scripts/run");
|
||||
|
||||
runCodewhaleTui().catch((error) => {
|
||||
console.error("Failed to start codewhale-tui:", error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { runCodewhale } = require("../scripts/run");
|
||||
|
||||
runCodewhale().catch((error) => {
|
||||
console.error("Failed to start codewhale:", error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "codewhale",
|
||||
"version": "0.8.40",
|
||||
"codewhaleBinaryVersion": "0.8.40",
|
||||
"description": "Install and run the codewhale CLI dispatcher and codewhale-tui terminal UI from GitHub release artifacts.",
|
||||
"author": "Hmbown",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/Hmbown/DeepSeek-TUI",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Hmbown/DeepSeek-TUI.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Hmbown/DeepSeek-TUI/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"codewhale",
|
||||
"deepseek",
|
||||
"cli",
|
||||
"tui",
|
||||
"rust",
|
||||
"binary",
|
||||
"terminal"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"bin": {
|
||||
"codewhale": "bin/codewhale.js",
|
||||
"codewhale-tui": "bin/codewhale-tui.js"
|
||||
},
|
||||
"scripts": {
|
||||
"release:check": "node scripts/verify-release-assets.js",
|
||||
"postinstall": "node scripts/install.js --optional",
|
||||
"prepublishOnly": "node scripts/verify-release-assets.js",
|
||||
"prepack": "node scripts/install.js",
|
||||
"test": "node --test test/*.test.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"files": [
|
||||
"bin/*.js",
|
||||
"scripts/*.js",
|
||||
"test/*.js",
|
||||
"README.md",
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
const path = require("path");
|
||||
const os = require("os");
|
||||
|
||||
const CHECKSUM_MANIFEST = "deepseek-artifacts-sha256.txt";
|
||||
const CHECKSUM_MANIFEST = "codewhale-artifacts-sha256.txt";
|
||||
|
||||
const ASSET_MATRIX = {
|
||||
linux: {
|
||||
x64: ["deepseek-linux-x64", "deepseek-tui-linux-x64"],
|
||||
arm64: ["deepseek-linux-arm64", "deepseek-tui-linux-arm64"],
|
||||
x64: ["codewhale-linux-x64", "codewhale-tui-linux-x64"],
|
||||
arm64: ["codewhale-linux-arm64", "codewhale-tui-linux-arm64"],
|
||||
},
|
||||
darwin: {
|
||||
x64: ["deepseek-macos-x64", "deepseek-tui-macos-x64"],
|
||||
arm64: ["deepseek-macos-arm64", "deepseek-tui-macos-arm64"],
|
||||
x64: ["codewhale-macos-x64", "codewhale-tui-macos-x64"],
|
||||
arm64: ["codewhale-macos-arm64", "codewhale-tui-macos-arm64"],
|
||||
},
|
||||
win32: {
|
||||
x64: ["deepseek-windows-x64.exe", "deepseek-tui-windows-x64.exe"],
|
||||
x64: ["codewhale-windows-x64.exe", "codewhale-tui-windows-x64.exe"],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ function detectBinaryNames() {
|
||||
return {
|
||||
platform,
|
||||
arch,
|
||||
deepseek: pair[0],
|
||||
codewhale: pair[0],
|
||||
tui: pair[1],
|
||||
};
|
||||
}
|
||||
@@ -55,11 +55,11 @@ function detectBinaryNames() {
|
||||
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:",
|
||||
"You can still run codewhale by building from source with Cargo:",
|
||||
"",
|
||||
" # Requires Rust 1.88+ (https://rustup.rs)",
|
||||
" cargo install deepseek-tui-cli --locked # provides `deepseek`",
|
||||
" cargo install deepseek-tui --locked # provides `deepseek-tui`",
|
||||
" cargo install codewhale-cli --locked # provides `codewhale`",
|
||||
" cargo install codewhale-tui --locked # provides `codewhale-tui`",
|
||||
"",
|
||||
"Or build from a checkout:",
|
||||
"",
|
||||
@@ -3,9 +3,9 @@ function assertSupportedNode() {
|
||||
const major = Number.parseInt(String(version).split(".")[0], 10);
|
||||
if (Number.isNaN(major) || major < 18) {
|
||||
process.stderr.write(
|
||||
"deepseek-tui: Node.js 18 or newer is required for npm installation. " +
|
||||
"codewhale: Node.js 18 or newer is required for npm installation. " +
|
||||
`Current Node.js version is ${version}. ` +
|
||||
"Please upgrade Node.js and rerun `npm install -g deepseek-tui`.\n",
|
||||
"Please upgrade Node.js and rerun `npm install -g codewhale`.\n",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -136,16 +136,16 @@ function maxAttempts(context = "runtime", env = process.env) {
|
||||
}
|
||||
|
||||
function binaryPaths() {
|
||||
const { deepseek, tui } = detectBinaryNames();
|
||||
const { codewhale, tui } = detectBinaryNames();
|
||||
const releaseDir = releaseBinaryDirectory();
|
||||
return {
|
||||
deepseek: {
|
||||
asset: deepseek,
|
||||
target: path.join(releaseDir, process.platform === "win32" ? "deepseek.exe" : "deepseek"),
|
||||
codewhale: {
|
||||
asset: codewhale,
|
||||
target: path.join(releaseDir, process.platform === "win32" ? "codewhale.exe" : "codewhale"),
|
||||
},
|
||||
tui: {
|
||||
asset: tui,
|
||||
target: path.join(releaseDir, process.platform === "win32" ? "deepseek-tui.exe" : "deepseek-tui"),
|
||||
target: path.join(releaseDir, process.platform === "win32" ? "codewhale-tui.exe" : "codewhale-tui"),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -166,7 +166,7 @@ function logInfo(message) {
|
||||
if (isQuietInstall()) {
|
||||
return;
|
||||
}
|
||||
process.stderr.write(`deepseek-tui: ${message}\n`);
|
||||
process.stderr.write(`codewhale: ${message}\n`);
|
||||
}
|
||||
|
||||
function installFailureHint(error) {
|
||||
@@ -194,19 +194,19 @@ function installFailureHint(error) {
|
||||
|
||||
if (releaseBase) {
|
||||
return [
|
||||
"deepseek-tui install hint:",
|
||||
"codewhale install hint:",
|
||||
` DEEPSEEK_TUI_RELEASE_BASE_URL is set to ${releaseBase}`,
|
||||
" Verify that this directory contains deepseek-artifacts-sha256.txt",
|
||||
" plus the deepseek/deepseek-tui binary assets for your platform.",
|
||||
" Verify that this directory contains codewhale-artifacts-sha256.txt",
|
||||
" plus the codewhale/codewhale-tui binary assets for your platform.",
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
return [
|
||||
"deepseek-tui install hint:",
|
||||
"codewhale install hint:",
|
||||
" The npm package downloads prebuilt binaries from GitHub Releases.",
|
||||
" If GitHub is unavailable on this network, mirror the release assets and set:",
|
||||
" DEEPSEEK_TUI_RELEASE_BASE_URL=https://<mirror>/<release-asset-directory>/",
|
||||
" The directory must contain deepseek-artifacts-sha256.txt and the platform binaries.",
|
||||
" The directory must contain codewhale-artifacts-sha256.txt and the platform binaries.",
|
||||
" See docs/INSTALL.md#npm-binary-download-times-out.",
|
||||
].join("\n");
|
||||
}
|
||||
@@ -258,14 +258,14 @@ function createProgressReporter(assetName, totalBytes) {
|
||||
const render = (final) => {
|
||||
if (totalBytes && totalBytes > 0) {
|
||||
const pct = Math.min(100, Math.round((received / totalBytes) * 100));
|
||||
const line = `deepseek-tui: downloading ${assetName}: ${formatMb(received)} / ${formatMb(totalBytes)} MB (${pct}%)`;
|
||||
const line = `codewhale: downloading ${assetName}: ${formatMb(received)} / ${formatMb(totalBytes)} MB (${pct}%)`;
|
||||
if (interactive) {
|
||||
process.stderr.write(`${line}\r`);
|
||||
} else {
|
||||
process.stderr.write(`${line}\n`);
|
||||
}
|
||||
} else {
|
||||
const line = `deepseek-tui: downloading ${assetName}: ${formatMb(received)} MB downloaded`;
|
||||
const line = `codewhale: downloading ${assetName}: ${formatMb(received)} MB downloaded`;
|
||||
if (interactive) {
|
||||
process.stderr.write(`${line}\r`);
|
||||
} else {
|
||||
@@ -295,7 +295,7 @@ function createProgressReporter(assetName, totalBytes) {
|
||||
// Move past the carriage-return line and emit a "done" footer.
|
||||
process.stderr.write("\n");
|
||||
}
|
||||
process.stderr.write(`deepseek-tui: ${assetName} ... done.\n`);
|
||||
process.stderr.write(`codewhale: ${assetName} ... done.\n`);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -406,7 +406,7 @@ function connectThroughProxy(proxy, targetHost, targetPort, timeoutMs) {
|
||||
const lines = [
|
||||
`CONNECT ${targetHost}:${targetPort} HTTP/1.1`,
|
||||
`Host: ${targetHost}:${targetPort}`,
|
||||
"User-Agent: deepseek-tui-installer",
|
||||
"User-Agent: codewhale-installer",
|
||||
"Proxy-Connection: keep-alive",
|
||||
];
|
||||
if (proxy.auth) {
|
||||
@@ -555,7 +555,7 @@ function httpRequest(rawUrl, opts = {}) {
|
||||
path: `${url.pathname}${url.search || ""}`,
|
||||
headers: {
|
||||
Host: url.host,
|
||||
"User-Agent": "deepseek-tui-installer",
|
||||
"User-Agent": "codewhale-installer",
|
||||
Accept: "*/*",
|
||||
Connection: "close",
|
||||
},
|
||||
@@ -641,7 +641,7 @@ function httpRequest(rawUrl, opts = {}) {
|
||||
path: rawUrl,
|
||||
headers: {
|
||||
Host: url.host,
|
||||
"User-Agent": "deepseek-tui-installer",
|
||||
"User-Agent": "codewhale-installer",
|
||||
Accept: "*/*",
|
||||
Connection: "close",
|
||||
...(proxy.auth ? { "Proxy-Authorization": `Basic ${proxy.auth}` } : {}),
|
||||
@@ -704,7 +704,7 @@ function httpRequest(rawUrl, opts = {}) {
|
||||
path: `${url.pathname}${url.search || ""}`,
|
||||
headers: {
|
||||
Host: url.host,
|
||||
"User-Agent": "deepseek-tui-installer",
|
||||
"User-Agent": "codewhale-installer",
|
||||
Accept: "*/*",
|
||||
Connection: "close",
|
||||
},
|
||||
@@ -1122,7 +1122,7 @@ async function run(options = {}) {
|
||||
};
|
||||
|
||||
await Promise.all([
|
||||
ensureBinary(paths.deepseek.target, paths.deepseek.asset, version, repo, getChecksums, { context }),
|
||||
ensureBinary(paths.codewhale.target, paths.codewhale.asset, version, repo, getChecksums, { context }),
|
||||
ensureBinary(paths.tui.target, paths.tui.asset, version, repo, getChecksums, { context }),
|
||||
]);
|
||||
}
|
||||
@@ -1130,10 +1130,10 @@ async function run(options = {}) {
|
||||
async function getBinaryPath(name) {
|
||||
await run({ context: "runtime" });
|
||||
const paths = binaryPaths();
|
||||
if (name === "deepseek") {
|
||||
return paths.deepseek.target;
|
||||
if (name === "codewhale") {
|
||||
return paths.codewhale.target;
|
||||
}
|
||||
if (name === "deepseek-tui") {
|
||||
if (name === "codewhale-tui") {
|
||||
return paths.tui.target;
|
||||
}
|
||||
throw new Error(`Unknown binary: ${name}`);
|
||||
@@ -1158,7 +1158,7 @@ module.exports = {
|
||||
|
||||
if (require.main === module) {
|
||||
run({ context: "install" }).catch((error) => {
|
||||
console.error("deepseek-tui install failed:", error.message);
|
||||
console.error("codewhale install failed:", error.message);
|
||||
const hint = installFailureHint(error);
|
||||
if (hint) {
|
||||
console.error(hint);
|
||||
+3
-3
@@ -66,11 +66,11 @@ function detectBinaryRequiredGlibc(filePath) {
|
||||
|
||||
function buildFromSourceHint() {
|
||||
return [
|
||||
"You can still run DeepSeek TUI by building from source with Cargo:",
|
||||
"You can still run codewhale by building from source with Cargo:",
|
||||
"",
|
||||
" # Requires Rust 1.88+ (https://rustup.rs)",
|
||||
" cargo install deepseek-tui-cli --locked # provides `deepseek`",
|
||||
" cargo install deepseek-tui --locked # provides `deepseek-tui`",
|
||||
" cargo install codewhale-cli --locked # provides `codewhale`",
|
||||
" cargo install codewhale-tui --locked # provides `codewhale-tui`",
|
||||
"",
|
||||
"Or build from a checkout:",
|
||||
"",
|
||||
@@ -9,7 +9,8 @@ function isVersionFlag(args = process.argv.slice(2)) {
|
||||
|
||||
function handleVersionFallback(binaryName) {
|
||||
if (isVersionFlag()) {
|
||||
const binVersion = pkg.deepseekBinaryVersion || pkg.version;
|
||||
const binVersion =
|
||||
pkg.codewhaleBinaryVersion || pkg.deepseekBinaryVersion || pkg.version;
|
||||
console.log(`${binaryName} (npm wrapper) v${pkg.version}`);
|
||||
console.log(`binary version: v${binVersion}`);
|
||||
console.log(`repo: ${pkg.repository?.url || "N/A"}`);
|
||||
@@ -33,26 +34,26 @@ async function run(binaryName) {
|
||||
process.exit(result.status ?? 1);
|
||||
}
|
||||
|
||||
async function runDeepseek() {
|
||||
await run("deepseek");
|
||||
async function runCodewhale() {
|
||||
await run("codewhale");
|
||||
}
|
||||
|
||||
async function runDeepseekTui() {
|
||||
await run("deepseek-tui");
|
||||
async function runCodewhaleTui() {
|
||||
await run("codewhale-tui");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
run,
|
||||
runDeepseek,
|
||||
runDeepseekTui,
|
||||
runCodewhale,
|
||||
runCodewhaleTui,
|
||||
_internal: { isVersionFlag },
|
||||
};
|
||||
|
||||
if (require.main === module) {
|
||||
const command = process.argv[1] || "";
|
||||
if (command.includes("tui")) {
|
||||
runDeepseekTui();
|
||||
runCodewhaleTui();
|
||||
} else {
|
||||
runDeepseek();
|
||||
runCodewhale();
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -13,7 +13,7 @@ function resolveBinaryVersion() {
|
||||
const configuredVersion =
|
||||
process.env.DEEPSEEK_TUI_VERSION ||
|
||||
process.env.DEEPSEEK_VERSION ||
|
||||
pkg.deepseekBinaryVersion ||
|
||||
pkg.codewhaleBinaryVersion || pkg.deepseekBinaryVersion ||
|
||||
pkg.version;
|
||||
return String(configuredVersion).trim();
|
||||
}
|
||||
@@ -33,7 +33,7 @@ function requestStatus(url, method = "HEAD", redirects = 0) {
|
||||
{
|
||||
method,
|
||||
headers: {
|
||||
"User-Agent": "deepseek-tui-npm-release-check",
|
||||
"User-Agent": "codewhale-npm-release-check",
|
||||
},
|
||||
},
|
||||
(res) => {
|
||||
@@ -71,7 +71,7 @@ async function downloadText(url) {
|
||||
url,
|
||||
{
|
||||
headers: {
|
||||
"User-Agent": "deepseek-tui-npm-release-check",
|
||||
"User-Agent": "codewhale-npm-release-check",
|
||||
},
|
||||
},
|
||||
(res) => {
|
||||
@@ -24,8 +24,8 @@ test("openharmony x64 resolves to linux x64 binaries", () => {
|
||||
withMockedOs("openharmony", "x64", () => {
|
||||
const { detectBinaryNames } = require(ARTIFACTS_PATH);
|
||||
const result = detectBinaryNames();
|
||||
assert.equal(result.deepseek, "deepseek-linux-x64");
|
||||
assert.equal(result.tui, "deepseek-tui-linux-x64");
|
||||
assert.equal(result.codewhale, "codewhale-linux-x64");
|
||||
assert.equal(result.tui, "codewhale-tui-linux-x64");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -33,8 +33,8 @@ test("openharmony arm64 resolves to linux arm64 binaries", () => {
|
||||
withMockedOs("openharmony", "arm64", () => {
|
||||
const { detectBinaryNames } = require(ARTIFACTS_PATH);
|
||||
const result = detectBinaryNames();
|
||||
assert.equal(result.deepseek, "deepseek-linux-arm64");
|
||||
assert.equal(result.tui, "deepseek-tui-linux-arm64");
|
||||
assert.equal(result.codewhale, "codewhale-linux-arm64");
|
||||
assert.equal(result.tui, "codewhale-tui-linux-arm64");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,15 +52,15 @@ test("genuinely unsupported platform throws with raw platform name", () => {
|
||||
});
|
||||
|
||||
test("known platforms are unaffected by alias map", () => {
|
||||
for (const [platform, arch, expectedDeepseek] of [
|
||||
["linux", "x64", "deepseek-linux-x64"],
|
||||
["darwin", "arm64", "deepseek-macos-arm64"],
|
||||
["win32", "x64", "deepseek-windows-x64.exe"],
|
||||
for (const [platform, arch, expectedCodewhale] of [
|
||||
["linux", "x64", "codewhale-linux-x64"],
|
||||
["darwin", "arm64", "codewhale-macos-arm64"],
|
||||
["win32", "x64", "codewhale-windows-x64.exe"],
|
||||
]) {
|
||||
withMockedOs(platform, arch, () => {
|
||||
const { detectBinaryNames } = require(ARTIFACTS_PATH);
|
||||
const result = detectBinaryNames();
|
||||
assert.equal(result.deepseek, expectedDeepseek);
|
||||
assert.equal(result.codewhale, expectedCodewhale);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -16,7 +16,7 @@ function sha256(content) {
|
||||
}
|
||||
|
||||
async function makeTempDir(t) {
|
||||
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "deepseek-install-test-"));
|
||||
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "codewhale-install-test-"));
|
||||
t.after(() => fs.promises.rm(dir, { force: true, recursive: true }));
|
||||
return dir;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ test("install failure hint explains release base override for blocked GitHub dow
|
||||
try {
|
||||
const error = Object.assign(
|
||||
new Error(
|
||||
"fetch https://github.com/Hmbown/DeepSeek-TUI/releases/download/v0.8.19/deepseek-artifacts-sha256.txt failed after 5 attempts:\ngetaddrinfo ENOTFOUND github.com",
|
||||
"fetch https://github.com/Hmbown/DeepSeek-TUI/releases/download/v0.8.19/codewhale-artifacts-sha256.txt failed after 5 attempts:\ngetaddrinfo ENOTFOUND github.com",
|
||||
),
|
||||
{ code: "ENOTFOUND" },
|
||||
);
|
||||
@@ -77,7 +77,7 @@ test("install failure hint explains release base override for blocked GitHub dow
|
||||
const hint = installFailureHint(error);
|
||||
|
||||
assert.match(hint, /DEEPSEEK_TUI_RELEASE_BASE_URL/);
|
||||
assert.match(hint, /deepseek-artifacts-sha256\.txt/);
|
||||
assert.match(hint, /codewhale-artifacts-sha256\.txt/);
|
||||
assert.match(hint, /platform binaries/);
|
||||
assert.match(hint, /#npm-binary-download-times-out/);
|
||||
} finally {
|
||||
@@ -100,7 +100,7 @@ test("install failure hint checks configured release base when override is alrea
|
||||
const hint = installFailureHint(error);
|
||||
|
||||
assert.match(hint, /is set to https:\/\/mirror\.example\/deepseek\//);
|
||||
assert.match(hint, /deepseek-artifacts-sha256\.txt/);
|
||||
assert.match(hint, /codewhale-artifacts-sha256\.txt/);
|
||||
assert.doesNotMatch(hint, /If GitHub is unavailable/);
|
||||
} finally {
|
||||
if (previous === undefined) {
|
||||
@@ -113,10 +113,10 @@ test("install failure hint checks configured release base when override is alrea
|
||||
|
||||
test("ensureBinary adopts a manually placed target binary after checksum validation", async (t) => {
|
||||
const dir = await makeTempDir(t);
|
||||
const target = path.join(dir, process.platform === "win32" ? "deepseek.exe" : "deepseek");
|
||||
const assetName = process.platform === "win32" ? "deepseek-windows-x64.exe" : "deepseek-linux-x64";
|
||||
const target = path.join(dir, process.platform === "win32" ? "codewhale.exe" : "codewhale");
|
||||
const assetName = process.platform === "win32" ? "codewhale-windows-x64.exe" : "codewhale-linux-x64";
|
||||
const version = "0.8.25";
|
||||
const content = Buffer.from("manual deepseek binary");
|
||||
const content = Buffer.from("manual codewhale binary");
|
||||
let checksumLoads = 0;
|
||||
|
||||
await fs.promises.writeFile(target, content, { mode: 0o600 });
|
||||
@@ -139,8 +139,8 @@ test("ensureBinary adopts a manually placed target binary after checksum validat
|
||||
|
||||
test("ensureBinary adopts an official release-named binary placed in downloads", async (t) => {
|
||||
const dir = await makeTempDir(t);
|
||||
const target = path.join(dir, process.platform === "win32" ? "deepseek.exe" : "deepseek");
|
||||
const assetName = process.platform === "win32" ? "deepseek-windows-x64.exe" : "deepseek-linux-x64";
|
||||
const target = path.join(dir, process.platform === "win32" ? "codewhale.exe" : "codewhale");
|
||||
const assetName = process.platform === "win32" ? "codewhale-windows-x64.exe" : "codewhale-linux-x64";
|
||||
const assetPath = path.join(dir, assetName);
|
||||
const version = "0.8.25";
|
||||
const content = Buffer.from("official release binary");
|
||||
@@ -161,8 +161,8 @@ test("ensureBinary adopts an official release-named binary placed in downloads",
|
||||
|
||||
test("manual binaries with mismatched checksums are not adopted", async (t) => {
|
||||
const dir = await makeTempDir(t);
|
||||
const target = path.join(dir, process.platform === "win32" ? "deepseek.exe" : "deepseek");
|
||||
const assetName = process.platform === "win32" ? "deepseek-windows-x64.exe" : "deepseek-linux-x64";
|
||||
const target = path.join(dir, process.platform === "win32" ? "codewhale.exe" : "codewhale");
|
||||
const assetName = process.platform === "win32" ? "codewhale-windows-x64.exe" : "codewhale-linux-x64";
|
||||
const content = Buffer.from("wrong binary bytes");
|
||||
|
||||
await fs.promises.writeFile(target, content);
|
||||
@@ -71,7 +71,7 @@ test("optional install only swallows retryable download failures", () => {
|
||||
false,
|
||||
);
|
||||
|
||||
const badChecksum = new Error("Checksum mismatch for deepseek-linux-x64");
|
||||
const badChecksum = new Error("Checksum mismatch for codewhale-linux-x64");
|
||||
badChecksum.nonRetryable = true;
|
||||
assert.equal(
|
||||
_internal.shouldIgnoreInstallFailure("install", badChecksum, ["--optional"], {}),
|
||||
@@ -148,7 +148,7 @@ test("withRetry prints install hint on first retryable failure", async () => {
|
||||
|
||||
assert.equal(result, "ok");
|
||||
assert.equal(attempts, 2);
|
||||
assert.match(stderr, /deepseek-tui install hint:/);
|
||||
assert.match(stderr, /codewhale install hint:/);
|
||||
assert.match(stderr, /#npm-binary-download-times-out/);
|
||||
} finally {
|
||||
process.stderr.write = previousWrite;
|
||||
@@ -1,89 +1,15 @@
|
||||
# deepseek-tui
|
||||
# deepseek-tui (deprecated)
|
||||
|
||||
Install and run the `deepseek` and `deepseek-tui` binaries from GitHub release artifacts.
|
||||
|
||||
## Install
|
||||
This package has been renamed to **codewhale**. Install that instead:
|
||||
|
||||
```bash
|
||||
npm install -g deepseek-tui
|
||||
# or
|
||||
pnpm add -g deepseek-tui
|
||||
npm uninstall -g deepseek-tui
|
||||
npm install -g codewhale
|
||||
```
|
||||
|
||||
For project-local usage:
|
||||
`codewhale` ships the same `codewhale` and `codewhale-tui` binaries plus
|
||||
deprecation shims under the old `deepseek` / `deepseek-tui` names so existing
|
||||
scripts keep working through one transition release.
|
||||
|
||||
```bash
|
||||
npm install deepseek-tui
|
||||
npx deepseek-tui --help
|
||||
```
|
||||
|
||||
`postinstall` tries to download platform binaries into `bin/downloads/` and
|
||||
exposes `deepseek` and `deepseek-tui` commands. If GitHub release assets are
|
||||
temporarily unreachable, install continues and the wrapper retries the download
|
||||
on first run.
|
||||
|
||||
## First run
|
||||
|
||||
```bash
|
||||
deepseek login --api-key "YOUR_DEEPSEEK_API_KEY"
|
||||
deepseek doctor
|
||||
deepseek
|
||||
```
|
||||
|
||||
The `deepseek` facade and `deepseek-tui` binary share `~/.deepseek/config.toml`
|
||||
for DeepSeek auth and default model settings. Common TUI commands are available
|
||||
directly through the facade, including `deepseek doctor`, `deepseek models`,
|
||||
`deepseek sessions`, and `deepseek resume --last`.
|
||||
|
||||
The app talks to DeepSeek's documented OpenAI-compatible Chat Completions API.
|
||||
Set `DEEPSEEK_BASE_URL` only if you need the China endpoint or DeepSeek beta
|
||||
features such as strict tool mode, chat prefix completion, or FIM completion.
|
||||
|
||||
NVIDIA NIM-hosted DeepSeek V4 Pro is also supported:
|
||||
|
||||
```bash
|
||||
deepseek auth set --provider nvidia-nim --api-key "YOUR_NVIDIA_API_KEY"
|
||||
deepseek --provider nvidia-nim
|
||||
```
|
||||
|
||||
For a single process, set `DEEPSEEK_PROVIDER=nvidia-nim` and `NVIDIA_API_KEY`
|
||||
or `NVIDIA_NIM_API_KEY` (with `DEEPSEEK_API_KEY` as a compatibility fallback).
|
||||
The NIM default model is `deepseek-ai/deepseek-v4-pro` and the default base URL
|
||||
is `https://integrate.api.nvidia.com/v1`. With `--provider nvidia-nim`,
|
||||
`--model deepseek-v4-flash` maps to `deepseek-ai/deepseek-v4-flash`.
|
||||
|
||||
## Supported platforms
|
||||
|
||||
Prebuilt binaries for the GitHub release are downloaded automatically:
|
||||
|
||||
- Linux x64
|
||||
- Linux arm64 (v0.8.8+)
|
||||
- macOS x64 / arm64
|
||||
- Windows x64
|
||||
|
||||
Other platform/architecture combinations (musl, riscv64, FreeBSD, …) aren't
|
||||
shipped as prebuilts. Unsupported platforms, checksum failures, and glibc
|
||||
compatibility problems still fail with a clear error pointing you at
|
||||
`cargo install deepseek-tui-cli deepseek-tui --locked` and the full
|
||||
[docs/INSTALL.md](https://github.com/Hmbown/DeepSeek-TUI/blob/main/docs/INSTALL.md)
|
||||
build-from-source guide.
|
||||
|
||||
## Configuration
|
||||
|
||||
- Default binary version comes from `deepseekBinaryVersion` in `package.json`.
|
||||
- Set `DEEPSEEK_TUI_VERSION` or `DEEPSEEK_VERSION` to override the release version.
|
||||
- Set `DEEPSEEK_TUI_GITHUB_REPO` or `DEEPSEEK_GITHUB_REPO` to override the source repo (defaults to `Hmbown/DeepSeek-TUI`).
|
||||
- Set `DEEPSEEK_TUI_RELEASE_BASE_URL` to use an internal or mirrored
|
||||
release-asset directory when GitHub Releases is unavailable. The directory
|
||||
must contain `deepseek-artifacts-sha256.txt` and the platform binaries.
|
||||
- Set `DEEPSEEK_TUI_FORCE_DOWNLOAD=1` to force download even when the cached binary is already present.
|
||||
- Set `DEEPSEEK_TUI_DISABLE_INSTALL=1` to skip install-time download.
|
||||
- Set `DEEPSEEK_TUI_OPTIONAL_INSTALL=1` to make install-time retryable download
|
||||
failures warn and exit `0` instead of failing `npm install`.
|
||||
|
||||
## Release integrity
|
||||
|
||||
- `npm publish` runs a release-asset check to ensure all required binary assets
|
||||
exist for the target GitHub release before publishing.
|
||||
- Install-time downloads are verified against the release checksum manifest before
|
||||
the wrapper marks them executable.
|
||||
See [docs/REBRAND.md](https://github.com/Hmbown/DeepSeek-TUI/blob/main/docs/REBRAND.md)
|
||||
for the full migration story.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { runDeepseekTui } = require("../scripts/run");
|
||||
|
||||
runDeepseekTui().catch((error) => {
|
||||
console.error("Failed to start deepseek-tui:", error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { runDeepseek } = require("../scripts/run");
|
||||
|
||||
runDeepseek().catch((error) => {
|
||||
console.error("Failed to start deepseek:", error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,11 +1,10 @@
|
||||
{
|
||||
"name": "deepseek-tui",
|
||||
"version": "0.8.40",
|
||||
"deepseekBinaryVersion": "0.8.40",
|
||||
"description": "Install and run deepseek and deepseek-tui binaries from GitHub release artifacts.",
|
||||
"description": "Deprecated. Renamed to `codewhale`. Run `npm install -g codewhale` instead.",
|
||||
"author": "Hmbown",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/Hmbown/DeepSeek-TUI",
|
||||
"homepage": "https://github.com/Hmbown/DeepSeek-TUI/blob/main/docs/REBRAND.md",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Hmbown/DeepSeek-TUI.git"
|
||||
@@ -14,24 +13,13 @@
|
||||
"url": "https://github.com/Hmbown/DeepSeek-TUI/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"deprecated",
|
||||
"deepseek",
|
||||
"cli",
|
||||
"tui",
|
||||
"rust",
|
||||
"binary",
|
||||
"terminal"
|
||||
"codewhale"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"bin": {
|
||||
"deepseek": "bin/deepseek.js",
|
||||
"deepseek-tui": "bin/deepseek-tui.js"
|
||||
},
|
||||
"scripts": {
|
||||
"release:check": "node scripts/verify-release-assets.js",
|
||||
"postinstall": "node scripts/install.js --optional",
|
||||
"prepublishOnly": "node scripts/verify-release-assets.js",
|
||||
"prepack": "node scripts/install.js",
|
||||
"test": "node --test test/*.test.js"
|
||||
"postinstall": "node scripts/deprecation-notice.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -39,11 +27,8 @@
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"files": [
|
||||
"bin/*.js",
|
||||
"scripts/*.js",
|
||||
"test/*.js",
|
||||
"README.md",
|
||||
"package.json"
|
||||
]
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const notice = [
|
||||
"",
|
||||
" ╭───────────────────────────────────────────────────────────────────╮",
|
||||
" │ │",
|
||||
" │ deepseek-tui has been renamed to `codewhale`. │",
|
||||
" │ │",
|
||||
" │ Please uninstall this package and install codewhale instead: │",
|
||||
" │ │",
|
||||
" │ npm uninstall -g deepseek-tui │",
|
||||
" │ npm install -g codewhale │",
|
||||
" │ │",
|
||||
" │ codewhale ships the same `codewhale` and `codewhale-tui` │",
|
||||
" │ binaries plus deprecation shims under the old names. See: │",
|
||||
" │ https://github.com/Hmbown/DeepSeek-TUI/blob/main/docs/REBRAND.md │",
|
||||
" │ │",
|
||||
" ╰───────────────────────────────────────────────────────────────────╯",
|
||||
"",
|
||||
].join("\n");
|
||||
|
||||
process.stderr.write(notice);
|
||||
@@ -56,29 +56,48 @@ fail=0
|
||||
|
||||
echo "Checking published release ${version}..."
|
||||
|
||||
if npm_version="$(npm view "deepseek-tui@${version}" version 2>/dev/null)"; then
|
||||
echo "npm deepseek-tui@${npm_version} is published."
|
||||
# Canonical post-rebrand npm package.
|
||||
if npm_version="$(npm view "codewhale@${version}" version 2>/dev/null)"; then
|
||||
echo "npm codewhale@${npm_version} is published."
|
||||
else
|
||||
echo "npm deepseek-tui@${version} is not published." >&2
|
||||
echo "npm codewhale@${version} is not published." >&2
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if npm_binary_version="$(npm view "deepseek-tui@${version}" deepseekBinaryVersion 2>/dev/null)"; then
|
||||
# `codewhaleBinaryVersion` is the new internal version-pin field. Fall back
|
||||
# to the legacy `deepseekBinaryVersion` field for old/transition packages.
|
||||
binary_field=""
|
||||
npm_binary_version=""
|
||||
if value="$(npm view "codewhale@${version}" codewhaleBinaryVersion 2>/dev/null)" && [[ -n "${value}" ]]; then
|
||||
binary_field="codewhaleBinaryVersion"
|
||||
npm_binary_version="${value}"
|
||||
elif value="$(npm view "codewhale@${version}" deepseekBinaryVersion 2>/dev/null)" && [[ -n "${value}" ]]; then
|
||||
binary_field="deepseekBinaryVersion"
|
||||
npm_binary_version="${value}"
|
||||
fi
|
||||
|
||||
if [[ -n "${binary_field}" ]]; then
|
||||
if [[ "${npm_binary_version}" == "${version}" ]]; then
|
||||
echo "npm deepseekBinaryVersion=${npm_binary_version}."
|
||||
echo "npm ${binary_field}=${npm_binary_version}."
|
||||
elif [[ "${allow_npm_binary_mismatch}" == "1" ]]; then
|
||||
echo "npm deepseekBinaryVersion=${npm_binary_version} (allowed packaging-only mismatch)."
|
||||
echo "npm ${binary_field}=${npm_binary_version} (allowed packaging-only mismatch)."
|
||||
else
|
||||
echo "npm deepseekBinaryVersion=${npm_binary_version}, expected ${version}." >&2
|
||||
echo "npm ${binary_field}=${npm_binary_version}, expected ${version}." >&2
|
||||
fail=1
|
||||
fi
|
||||
elif [[ "${allow_npm_binary_mismatch}" == "1" ]]; then
|
||||
echo "npm deepseekBinaryVersion is absent (allowed packaging-only mismatch)."
|
||||
echo "npm codewhaleBinaryVersion is absent (allowed packaging-only mismatch)."
|
||||
else
|
||||
echo "npm deepseekBinaryVersion is absent for deepseek-tui@${version}." >&2
|
||||
echo "npm codewhaleBinaryVersion is absent for codewhale@${version}." >&2
|
||||
fail=1
|
||||
fi
|
||||
|
||||
# Legacy `deepseek-tui` deprecation shim package. Best-effort check —
|
||||
# absence after the transition release is expected and not fatal.
|
||||
if legacy_version="$(npm view "deepseek-tui@${version}" version 2>/dev/null)"; then
|
||||
echo "npm deepseek-tui@${legacy_version} (deprecation shim) is published."
|
||||
fi
|
||||
|
||||
for crate in "${release_crates[@]}"; do
|
||||
if curl -fsSL "https://crates.io/api/v1/crates/${crate}/${version}" >/dev/null 2>&1; then
|
||||
echo "crates.io ${crate}@${version} is published."
|
||||
@@ -89,7 +108,7 @@ for crate in "${release_crates[@]}"; do
|
||||
done
|
||||
|
||||
if [[ "${fail}" == "0" ]]; then
|
||||
echo "Published release OK: npm deepseek-tui@${version} and ${#release_crates[@]} crates are visible."
|
||||
echo "Published release OK: npm codewhale@${version} and ${#release_crates[@]} crates are visible."
|
||||
fi
|
||||
|
||||
exit "${fail}"
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
# Checks performed:
|
||||
# 1. No `crates/*/Cargo.toml` carries a literal `version = "x.y.z"`; every
|
||||
# crate must inherit `version.workspace = true`.
|
||||
# 2. `npm/deepseek-tui/package.json` `version` matches the workspace
|
||||
# `version` in the root `Cargo.toml`. (The npm wrapper directory is
|
||||
# renamed to `npm/codewhale/` in a follow-up phase; this script will
|
||||
# be updated then.)
|
||||
# 2. `npm/codewhale/package.json` `version` matches the workspace
|
||||
# `version` in the root `Cargo.toml`. (`npm/deepseek-tui/` still
|
||||
# exists during the transition as a deprecation shim package; its
|
||||
# version is also checked.)
|
||||
# 3. Internal `codewhale-*` path dependency pins match the workspace version.
|
||||
# 4. The TUI crate's packaged changelog copy matches root `CHANGELOG.md`.
|
||||
# 5. The current release has a dated Keep a Changelog entry and compare link.
|
||||
@@ -32,11 +32,20 @@ fi
|
||||
|
||||
# 2) Workspace ↔ npm package.json.
|
||||
workspace_version="$(grep -E '^version = "' Cargo.toml | head -n1 | sed -E 's/^version = "([^"]+)".*/\1/')"
|
||||
npm_version="$(node -p "require('./npm/deepseek-tui/package.json').version")"
|
||||
npm_version="$(node -p "require('./npm/codewhale/package.json').version")"
|
||||
if [[ "${workspace_version}" != "${npm_version}" ]]; then
|
||||
echo "::error::npm/deepseek-tui/package.json version (${npm_version}) does not match workspace Cargo.toml (${workspace_version})." >&2
|
||||
echo "::error::npm/codewhale/package.json version (${npm_version}) does not match workspace Cargo.toml (${workspace_version})." >&2
|
||||
fail=1
|
||||
fi
|
||||
# Also pin the legacy deprecation shim package to the same workspace version
|
||||
# so a stale `deepseek-tui` doesn't ship pointing at a different release.
|
||||
if [[ -f npm/deepseek-tui/package.json ]]; then
|
||||
legacy_npm_version="$(node -p "require('./npm/deepseek-tui/package.json').version")"
|
||||
if [[ "${workspace_version}" != "${legacy_npm_version}" ]]; then
|
||||
echo "::error::npm/deepseek-tui/package.json version (${legacy_npm_version}) does not match workspace Cargo.toml (${workspace_version})." >&2
|
||||
fail=1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 3) Internal path dependency pins.
|
||||
internal_dep_drift="$(
|
||||
|
||||
@@ -8,7 +8,7 @@ const path = require("path");
|
||||
const { spawn } = require("child_process");
|
||||
|
||||
const repoRoot = path.resolve(__dirname, "..", "..");
|
||||
const packageDir = path.join(repoRoot, "npm", "deepseek-tui");
|
||||
const packageDir = path.join(repoRoot, "npm", "codewhale");
|
||||
const prepareAssetsScript = path.join(
|
||||
repoRoot,
|
||||
"scripts",
|
||||
@@ -133,7 +133,7 @@ function parsePackJson(stdout) {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "deepseek-npm-smoke-"));
|
||||
const tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "codewhale-npm-smoke-"));
|
||||
const releaseAssetsDir = path.join(tempRoot, "release-assets");
|
||||
const packDir = path.join(tempRoot, "pack");
|
||||
const installDir = path.join(tempRoot, "install");
|
||||
@@ -165,11 +165,11 @@ async function main() {
|
||||
|
||||
await runCommand("npm", ["init", "-y"], { cwd: installDir });
|
||||
await runCommand("npm", ["install", tarball], { cwd: installDir, env });
|
||||
await runCommand("npx", ["--no-install", "deepseek", "doctor", "--help"], {
|
||||
await runCommand("npx", ["--no-install", "codewhale", "doctor", "--help"], {
|
||||
cwd: installDir,
|
||||
env,
|
||||
});
|
||||
await runCommand("npx", ["--no-install", "deepseek-tui", "--help"], {
|
||||
await runCommand("npx", ["--no-install", "codewhale-tui", "--help"], {
|
||||
cwd: installDir,
|
||||
env,
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ const {
|
||||
allAssetNames,
|
||||
CHECKSUM_MANIFEST,
|
||||
detectBinaryNames,
|
||||
} = require("../../npm/deepseek-tui/scripts/artifacts");
|
||||
} = require("../../npm/codewhale/scripts/artifacts");
|
||||
|
||||
async function sha256(filePath) {
|
||||
const content = await fs.readFile(filePath);
|
||||
@@ -25,16 +25,16 @@ async function main() {
|
||||
const buildDir = path.resolve(
|
||||
process.argv[3] || path.join("target", "release"),
|
||||
);
|
||||
const { deepseek, tui } = detectBinaryNames();
|
||||
const { codewhale, tui } = detectBinaryNames();
|
||||
const isWindows = process.platform === "win32";
|
||||
|
||||
const assets = [
|
||||
{
|
||||
source: path.join(buildDir, isWindows ? "deepseek.exe" : "deepseek"),
|
||||
target: deepseek,
|
||||
source: path.join(buildDir, isWindows ? "codewhale.exe" : "codewhale"),
|
||||
target: codewhale,
|
||||
},
|
||||
{
|
||||
source: path.join(buildDir, isWindows ? "deepseek-tui.exe" : "deepseek-tui"),
|
||||
source: path.join(buildDir, isWindows ? "codewhale-tui.exe" : "codewhale-tui"),
|
||||
target: tui,
|
||||
},
|
||||
];
|
||||
@@ -45,9 +45,9 @@ async function main() {
|
||||
continue;
|
||||
}
|
||||
assets.push({
|
||||
source: assetName.startsWith("deepseek-tui")
|
||||
? path.join(buildDir, isWindows ? "deepseek-tui.exe" : "deepseek-tui")
|
||||
: path.join(buildDir, isWindows ? "deepseek.exe" : "deepseek"),
|
||||
source: assetName.startsWith("codewhale-tui")
|
||||
? path.join(buildDir, isWindows ? "codewhale-tui.exe" : "codewhale-tui")
|
||||
: path.join(buildDir, isWindows ? "codewhale.exe" : "codewhale"),
|
||||
target: assetName,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user