nuwax-codex 0.16.7-beta.1 → 0.16.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/nuwax-codex.js +178 -69
  2. package/package.json +1 -9
@@ -1,95 +1,204 @@
1
1
  #!/usr/bin/env node
2
- // Launcher for the nuwax-codex npm package.
3
- // Resolves the platform-specific optional dependency that ships the native
4
- // `nuwax-codex` binary (and the bundled `bwrap` on Linux) and spawns it with
5
- // the forwarded argv. Both the npm command and the native binary are named
6
- // "nuwax-codex".
2
+ // Launcher for the nuwax-codex-ts npm package.
3
+ // Downloads the native `nuwax-codex` binary from GitHub Releases on first
4
+ // run and caches it locally. No platform-specific npm packages needed.
7
5
 
8
6
  import { spawnSync } from "node:child_process";
9
- import { existsSync } from "node:fs";
10
- import { fileURLToPath } from "node:url";
7
+ import { createWriteStream, existsSync, mkdirSync, chmodSync } from "node:fs";
8
+ import { homedir } from "node:os";
9
+ import { join, dirname } from "node:path";
10
+ import { pipeline } from "node:stream/promises";
11
+ import { createGunzip } from "node:zlib";
11
12
  import { familySync } from "detect-libc";
13
+ import { createRequire } from "node:module";
12
14
 
13
- // Map Node.js platform/arch to the platform-specific npm package name.
14
- function getPlatformPackage() {
15
- const platform = process.platform;
16
- const arch = process.arch;
17
-
18
- const platformMap = {
19
- darwin: {
20
- arm64: "nuwax-codex-darwin-arm64",
21
- x64: "nuwax-codex-darwin-x64",
22
- },
23
- linux: {
24
- // arm64 Linux is not shipped (GitHub arm64 runners are too flaky to build
25
- // it reliably); only x64 Linux is supported for now.
26
- x64: familySync() === "musl"
27
- ? "nuwax-codex-linux-x64-musl"
28
- : "nuwax-codex-linux-x64",
29
- },
30
- win32: {
31
- arm64: "nuwax-codex-win32-arm64",
32
- x64: "nuwax-codex-win32-x64",
33
- },
34
- };
35
-
36
- const packages = platformMap[platform];
37
- if (!packages) {
38
- console.error(`Unsupported platform: ${platform}`);
39
- process.exit(1);
40
- }
15
+ const require = createRequire(import.meta.url);
16
+ const VERSION = require("../package.json").version;
17
+ const OSS_CDN_BASE = "https://nuwa-packages.oss-rg-china-mainland.aliyuncs.com/nuwax-codex";
41
18
 
42
- const packageName = packages[arch];
43
- if (!packageName) {
44
- console.error(`Unsupported architecture: ${arch} on ${platform}`);
45
- process.exit(1);
19
+ // -- platform helpers -------------------------------------------------------
20
+
21
+ function getTargetTriple() {
22
+ const p = process.platform;
23
+ const a = process.arch;
24
+
25
+ if (p === "darwin") {
26
+ return a === "arm64" ? "aarch64-apple-darwin" : "x86_64-apple-darwin";
27
+ }
28
+ if (p === "linux") {
29
+ if (a !== "x64") throw new Error(`Unsupported Linux arch: ${a}`);
30
+ return familySync() === "musl"
31
+ ? "x86_64-unknown-linux-musl"
32
+ : "x86_64-unknown-linux-gnu";
46
33
  }
34
+ if (p === "win32") {
35
+ return a === "arm64" ? "aarch64-pc-windows-msvc" : "x86_64-pc-windows-msvc";
36
+ }
37
+ throw new Error(`Unsupported platform: ${p}`);
38
+ }
39
+
40
+ function getArchiveExt() {
41
+ return process.platform === "win32" ? "zip" : "tar.gz";
42
+ }
47
43
 
48
- return packageName;
44
+ function getBinaryName() {
45
+ return process.platform === "win32" ? "nuwax-codex.exe" : "nuwax-codex";
49
46
  }
50
47
 
51
- // Locate the native `nuwax-codex` binary inside the resolved platform package.
52
- function getBinaryPath() {
53
- const packageName = getPlatformPackage();
54
- const binaryName =
55
- process.platform === "win32" ? "nuwax-codex.exe" : "nuwax-codex";
48
+ // -- download & cache -------------------------------------------------------
56
49
 
57
- try {
58
- const binaryPath = fileURLToPath(
59
- import.meta.resolve(`${packageName}/bin/${binaryName}`),
50
+ function cacheDir() {
51
+ return join(homedir(), ".nuwax-codex-cache", VERSION);
52
+ }
53
+
54
+ function cachedBinaryPath() {
55
+ return join(cacheDir(), getBinaryName());
56
+ }
57
+
58
+ async function downloadBinary(url, outPath) {
59
+ mkdirSync(dirname(outPath), { recursive: true });
60
+
61
+ const res = await fetch(url, { redirect: "follow" });
62
+ if (!res.ok) {
63
+ throw new Error(
64
+ `Failed to download binary: HTTP ${res.status} ${res.statusText}\nURL: ${url}`,
60
65
  );
66
+ }
61
67
 
62
- if (existsSync(binaryPath)) {
63
- return binaryPath;
68
+ const total = parseInt(res.headers.get("content-length") || "0", 10);
69
+ let downloaded = 0;
70
+ const reader = res.body.getReader();
71
+ const ws = createWriteStream(outPath);
72
+ const logInterval = setInterval(() => {
73
+ if (total > 0) {
74
+ process.stderr.write(
75
+ `\r Downloading nuwax-codex ${VERSION} … ${((downloaded / total) * 100).toFixed(0)}%`,
76
+ );
64
77
  }
65
- } catch (e) {
66
- console.error(`Error resolving package: ${e}`);
67
- // Package not found — fall through to the helpful error below.
78
+ }, 500);
79
+
80
+ try {
81
+ while (true) {
82
+ const { done, value } = await reader.read();
83
+ if (done) break;
84
+ ws.write(value);
85
+ downloaded += value.length;
86
+ }
87
+ } finally {
88
+ clearInterval(logInterval);
89
+ ws.end();
68
90
  }
91
+ process.stderr.write("\n");
92
+
93
+ if (process.platform !== "win32") {
94
+ chmodSync(outPath, 0o755);
95
+ }
96
+ }
69
97
 
70
- console.error(
71
- `Failed to locate ${packageName} binary. This usually means the optional dependency was not installed.`,
98
+ async function extractTarGz(archivePath, destDir) {
99
+ // Simple tar.gz extraction: members are listed sequentially as
100
+ // [header(512B)][content(padded to 512B)]...
101
+ const { createReadStream } = await import("node:fs");
102
+ const { createGunzip } = await import("node:zlib");
103
+ const { pipeline } = await import("node:stream/promises");
104
+ const { Transform } = await import("node:stream");
105
+ const { writeFileSync } = await import("node:fs");
106
+
107
+ const gunzip = createGunzip();
108
+ const rs = createReadStream(archivePath);
109
+ let buffer = Buffer.alloc(0);
110
+
111
+ await pipeline(
112
+ rs,
113
+ gunzip,
114
+ new Transform({
115
+ transform(chunk, _enc, cb) {
116
+ buffer = Buffer.concat([buffer, chunk]);
117
+ while (buffer.length >= 512) {
118
+ // Parse tar header
119
+ const name = buffer.toString("utf8", 0, 100).replace(/\0.*$/, "");
120
+ const sizeStr = buffer.toString("utf8", 124, 136).replace(/\0.*$/, "");
121
+ const size = parseInt(sizeStr, 8);
122
+ if (isNaN(size) || size < 0) break;
123
+
124
+ const totalSize = Math.ceil((512 + size) / 512) * 512;
125
+ if (buffer.length < totalSize) break;
126
+
127
+ if (name && !name.endsWith("/") && size > 0) {
128
+ const fileData = buffer.subarray(512, 512 + size);
129
+ const outPath = join(destDir, name);
130
+ mkdirSync(dirname(outPath), { recursive: true });
131
+ writeFileSync(outPath, fileData);
132
+ if (process.platform !== "win32") {
133
+ chmodSync(outPath, 0o755);
134
+ }
135
+ }
136
+
137
+ buffer = buffer.subarray(totalSize);
138
+ }
139
+ cb();
140
+ },
141
+ }),
72
142
  );
73
- console.error(`Platform: ${process.platform}, Architecture: ${process.arch}`);
74
- process.exit(1);
75
143
  }
76
144
 
77
- // Execute the binary, forwarding stdin/stdout/stderr and the exit code.
78
- function run() {
79
- const binaryPath = getBinaryPath();
80
- const result = spawnSync(binaryPath, process.argv.slice(2), {
81
- stdio: "inherit",
82
- windowsHide: true,
83
- });
145
+ async function extractZip(archivePath, destDir) {
146
+ // Use unzip command; Node.js has no built-in zip support.
147
+ const { execSync } = await import("node:child_process");
148
+ execSync(`unzip -q -o "${archivePath}" -d "${destDir}"`, { stdio: "inherit" });
149
+ }
150
+
151
+ // -- main -------------------------------------------------------------------
152
+
153
+ async function ensureBinary() {
154
+ const cached = cachedBinaryPath();
155
+ if (existsSync(cached)) {
156
+ return cached;
157
+ }
158
+
159
+ const target = getTargetTriple();
160
+ const ext = getArchiveExt();
161
+ const url = `${OSS_CDN_BASE}/v${VERSION}/nuwax-codex-${VERSION}-${target}.${ext}`;
84
162
 
85
- if (result.error) {
86
- console.error(`Failed to execute ${binaryPath}:`, result.error);
163
+ console.error(`Downloading nuwax-codex ${VERSION} for ${target} …`);
164
+ console.error(` ${url}`);
165
+
166
+ const dir = cacheDir();
167
+ mkdirSync(dir, { recursive: true });
168
+ const archivePath = join(dir, `nuwax-codex.${ext}`);
169
+
170
+ await downloadBinary(url, archivePath);
171
+
172
+ console.error(" Extracting …");
173
+ if (ext === "tar.gz") {
174
+ await extractTarGz(archivePath, dir);
175
+ } else {
176
+ await extractZip(archivePath, dir);
177
+ }
178
+
179
+ if (!existsSync(cached)) {
180
+ console.error(" Error: binary not found after extraction at", cached);
87
181
  process.exit(1);
88
182
  }
89
183
 
90
- // result.status is null when the child was killed by a signal; treat that as
91
- // a failure (exit 1) rather than success.
92
- process.exit(result.status ?? 1);
184
+ return cached;
185
+ }
186
+
187
+ function run() {
188
+ ensureBinary().then((binaryPath) => {
189
+ const result = spawnSync(binaryPath, process.argv.slice(2), {
190
+ stdio: "inherit",
191
+ windowsHide: true,
192
+ });
193
+ if (result.error) {
194
+ console.error(`Failed to execute ${binaryPath}:`, result.error);
195
+ process.exit(1);
196
+ }
197
+ process.exit(result.status ?? 1);
198
+ }).catch((err) => {
199
+ console.error(err.message);
200
+ process.exit(1);
201
+ });
93
202
  }
94
203
 
95
204
  run();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuwax-codex",
3
- "version": "0.16.7-beta.1",
3
+ "version": "0.16.13",
4
4
  "type": "module",
5
5
  "description": "Fork of OpenAI Codex CLI with domestic (Chinese) LLM support via genai",
6
6
  "license": "Apache-2.0",
@@ -33,13 +33,5 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "detect-libc": "^2.0.0"
36
- },
37
- "optionalDependencies": {
38
- "nuwax-codex-darwin-arm64": "0.16.7-beta.1",
39
- "nuwax-codex-darwin-x64": "0.16.7-beta.1",
40
- "nuwax-codex-linux-x64": "0.16.7-beta.1",
41
- "nuwax-codex-linux-x64-musl": "0.16.7-beta.1",
42
- "nuwax-codex-win32-arm64": "0.16.7-beta.1",
43
- "nuwax-codex-win32-x64": "0.16.7-beta.1"
44
36
  }
45
37
  }