feat(npm): publish as codewhale; keep deepseek-tui as deprecation shim
Rename the npm wrapper directory and package from `deepseek-tui` to
`codewhale`. Move under `npm/codewhale/`:
- `package.json` renamed (name, bin, internal field) — keeps a
`deepseekBinaryVersion` fallback so old metadata still works.
- Bin entry points renamed to `bin/codewhale.js` and
`bin/codewhale-tui.js`; they spawn the corresponding canonical
binaries via the wrapper.
- `scripts/artifacts.js` switches to the canonical asset-name matrix
(`codewhale-*`, `codewhale-tui-*`) and `codewhale-artifacts-sha256.txt`.
- `scripts/run.js` exports `runCodewhale` and `runCodewhaleTui`; the
legacy `runDeepseek` exports are gone since nothing else inside the
package depended on them.
- `scripts/install.js`, `verify-release-assets.js`, `preflight-glibc.js`
update brand-mention strings + User-Agent headers. Env vars
(`DEEPSEEK_TUI_*`, `DEEPSEEK_*`) are explicitly anti-scope and are
left in place.
- Tests retargeted at the canonical asset names; all 19 still pass.
- README rewritten with the new install command and a deprecation
note about the old package.
Create a one-release deprecation shim at `npm/deepseek-tui/`:
- `package.json` with no `bin`, just a postinstall script that
prints a clear message telling the user to install `codewhale`
instead.
- `README.md` with the same migration note.
- Will be removed in v0.9.0 (or whenever Hunter retires the shims).
Release-side scripts in `scripts/release/` follow the rename:
- `prepare-local-release-assets.js` now requires `npm/codewhale/...`
and copies the canonical `codewhale*` binaries.
- `npm-wrapper-smoke.js` smokes the renamed package.
- `check-versions.sh` reads `npm/codewhale/package.json` for the
primary check and additionally pins the legacy shim package to
the same version.
- `check-published.sh` queries `codewhale@<version>` (with
`codewhaleBinaryVersion` lookup that falls back to the legacy
`deepseekBinaryVersion` field).
- `.github/workflows/auto-tag.yml` watches both `npm/codewhale/` and
`npm/deepseek-tui/` package.json for auto-tag triggers.
Verified:
- `npm test` inside `npm/codewhale/` passes 19/19.
- `npm install --dry-run --ignore-scripts` succeeds for both
`npm/codewhale/` and `npm/deepseek-tui/`.
- `scripts/release/check-versions.sh` reports OK.
- Rust gates re-run: `cargo check`, `cargo fmt --check`,
`cargo clippy -- -D warnings`, all clean.
No `npm publish` is run from this change — Hunter publishes manually
when the rebrand is ready to ship.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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