diff --git a/CODEWHALE.md b/CODEWHALE.md index 9bef495..d2cfbee 100644 --- a/CODEWHALE.md +++ b/CODEWHALE.md @@ -1,6 +1,6 @@ # Codewhale 一键安装和 LMM 配置 -需要 Node.js 22+ 和 npm。Bash 入口单独下载时还需要 curl。脚本不代装 Node,不改 npm registry,不使用 sudo 或 `--force`。安装使用官方的 `npm install --global codewhale@latest`;二进制选择和校验仍由官方 npm 安装器负责。LMM 适配器安装固定 Git 提交 `adad64b7ac77ec997b5be4662c6b6ccf36998357`,禁用其 npm 生命周期脚本;不依赖尚未发布的 npm 包。 +需要 Node.js 22+ 和 npm。Bash 入口单独下载时还需要 curl。脚本不代装 Node,不改 npm registry,不使用 sudo 或 `--force`。安装使用官方的 `npm install --global codewhale@latest`;二进制选择和校验仍由官方 npm 安装器负责。LMM 适配器安装固定 Git 提交 `62eb05b40f1dda7b844b5430ad2b735e66508aa0`,禁用其 npm 生命周期脚本;不依赖尚未发布的 npm 包。 ## 安装并配置 diff --git a/codewhale.mjs b/codewhale.mjs index a581a46..6e677c9 100755 --- a/codewhale.mjs +++ b/codewhale.mjs @@ -7,7 +7,7 @@ import { createRequire } from 'node:module'; import { createInterface } from 'node:readline/promises'; import { pathToFileURL } from 'node:url'; -export const PROVIDER_REV = 'adad64b7ac77ec997b5be4662c6b6ccf36998357'; +export const PROVIDER_REV = '62eb05b40f1dda7b844b5430ad2b735e66508aa0'; export const PROVIDER_URL = `https://github.com/TokenNotIncluded/codewhale-lmm-provider/archive/${PROVIDER_REV}.tar.gz`; const require = createRequire(import.meta.url); const actions = ['setup', 'install', 'login', 'run', 'models', 'status', 'balance', 'usage', 'logout', 'doctor', 'menu', 'help']; diff --git a/codewhale.ps1 b/codewhale.ps1 index df13dc1..244a478 100644 --- a/codewhale.ps1 +++ b/codewhale.ps1 @@ -19,8 +19,8 @@ try { $work = Join-Path ([IO.Path]::GetTempPath()) ('lmm-codewhale-' + [guid]::NewGuid()) New-Item -ItemType Directory -Path $work | Out-Null $helper = Join-Path $work 'codewhale.mjs' - Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/TokenNotIncluded/lmm-scripts/319d9790ba026583ea226fb92b13b366b738c3ef/codewhale.mjs' -OutFile $helper - if ((Get-FileHash -LiteralPath $helper -Algorithm SHA256).Hash -ne '91dcff456f04abb0ef0ff7f95742ff3d332bfb2c93b4b067f4d778008556f69c') { + Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/TokenNotIncluded/lmm-scripts/cdf32d6d0e612cb2e22ae93f2f25f744d6145617/codewhale.mjs' -OutFile $helper + if ((Get-FileHash -LiteralPath $helper -Algorithm SHA256).Hash -ne '4138c5d74f1dee3cf089a90bdeef649d42304de7f5f9cd83e28f7d3302f994fb') { throw 'Codewhale setup script checksum mismatch; nothing was executed.' } } diff --git a/codewhale.sh b/codewhale.sh index e518b1d..d69f505 100755 --- a/codewhale.sh +++ b/codewhale.sh @@ -10,6 +10,6 @@ temp_root=${TMPDIR:-/tmp} if [[ -n ${TERMUX_VERSION:-} || ${PREFIX:-} == */com.termux/files/usr ]]; then temp_root=${TMPDIR:-${PREFIX:-/data/data/com.termux/files/usr}/tmp}; fi work=$(mktemp -d "$temp_root/lmm-codewhale.XXXXXX") trap 'rm -rf -- "$work"' EXIT -curl --proto '=https' --proto-redir '=https' -fsSL 'https://raw.githubusercontent.com/TokenNotIncluded/lmm-scripts/319d9790ba026583ea226fb92b13b366b738c3ef/codewhale.mjs' -o "$work/codewhale.mjs" -node -e 'const fs=require("node:fs"),crypto=require("node:crypto");if(crypto.createHash("sha256").update(fs.readFileSync(process.argv[1])).digest("hex")!==process.argv[2]){console.error("Codewhale setup script checksum mismatch; nothing was executed.");process.exit(1)}' "$work/codewhale.mjs" '91dcff456f04abb0ef0ff7f95742ff3d332bfb2c93b4b067f4d778008556f69c' +curl --proto '=https' --proto-redir '=https' -fsSL 'https://raw.githubusercontent.com/TokenNotIncluded/lmm-scripts/cdf32d6d0e612cb2e22ae93f2f25f744d6145617/codewhale.mjs' -o "$work/codewhale.mjs" +node -e 'const fs=require("node:fs"),crypto=require("node:crypto");if(crypto.createHash("sha256").update(fs.readFileSync(process.argv[1])).digest("hex")!==process.argv[2]){console.error("Codewhale setup script checksum mismatch; nothing was executed.");process.exit(1)}' "$work/codewhale.mjs" '4138c5d74f1dee3cf089a90bdeef649d42304de7f5f9cd83e28f7d3302f994fb' node "$work/codewhale.mjs" "$@" diff --git a/test-codewhale.mjs b/test-codewhale.mjs index b711293..683fdf0 100644 --- a/test-codewhale.mjs +++ b/test-codewhale.mjs @@ -240,7 +240,7 @@ process.exit(Number(process.env.TEST_CURL_EXIT||0));\n`; const result = f.runShell('--help'); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /Codewhale \+ LMM/); - assert.ok(f.calls()[0][1].some(arg => /319d9790ba026583ea226fb92b13b366b738c3ef\/codewhale.mjs/.test(arg))); + assert.ok(f.calls()[0][1].some(arg => /cdf32d6d0e612cb2e22ae93f2f25f744d6145617\/codewhale.mjs/.test(arg))); }); test('truncated downloads fail before execution even when bytes were written', t => { const f = shellFixture(t); f.env.TEST_BAD_DOWNLOAD = '1'; f.env.TEST_CURL_EXIT = '18';