cawide 0.4.5 → 0.4.6
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.
- package/README.md +16 -3
- package/bin/cawide.js +51 -156
- package/package.json +23 -5
package/README.md
CHANGED
|
@@ -36,9 +36,22 @@ Use `cawide <command> --help` for the options supported by a particular command.
|
|
|
36
36
|
|
|
37
37
|
## Supported platforms
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
The right prebuilt binary is installed automatically as an optional dependency
|
|
40
|
+
of this package (the same approach used by esbuild and `@biomejs/biome`) — no
|
|
41
|
+
extra download step at runtime.
|
|
42
|
+
|
|
43
|
+
| Platform | Package |
|
|
44
|
+
|----------|---------|
|
|
45
|
+
| macOS (Apple Silicon) | [`cawide-darwin-arm64`](https://www.npmjs.com/package/cawide-darwin-arm64) |
|
|
46
|
+
| macOS (Intel) | [`cawide-darwin-x64`](https://www.npmjs.com/package/cawide-darwin-x64) |
|
|
47
|
+
| Linux (x86_64) | [`cawide-linux-x64`](https://www.npmjs.com/package/cawide-linux-x64) |
|
|
48
|
+
| Linux (ARM64) | [`cawide-linux-arm64`](https://www.npmjs.com/package/cawide-linux-arm64) |
|
|
49
|
+
| Windows (x86_64) | [`cawide-win32-x64`](https://www.npmjs.com/package/cawide-win32-x64) |
|
|
50
|
+
| Windows (ARM64) | [`cawide-win32-arm64`](https://www.npmjs.com/package/cawide-win32-arm64) |
|
|
51
|
+
|
|
52
|
+
If `npm install` was run with `--no-optional`/`--omit=optional`, or the
|
|
53
|
+
platform is unsupported, `cawide` prints a clear error explaining how to
|
|
54
|
+
reinstall.
|
|
42
55
|
|
|
43
56
|
## Support
|
|
44
57
|
|
package/bin/cawide.js
CHANGED
|
@@ -2,20 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require("node:fs");
|
|
4
4
|
const path = require("node:path");
|
|
5
|
-
const os = require("node:os");
|
|
6
|
-
const https = require("node:https");
|
|
7
5
|
const childProcess = require("node:child_process");
|
|
8
|
-
const zlib = require("node:zlib");
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
7
|
+
// Maps `${process.platform}-${process.arch}` to the platform-specific npm
|
|
8
|
+
// package that ships the prebuilt binary for it (see
|
|
9
|
+
// scripts/build-platforms.js and the six `cawide-<platform>`
|
|
10
|
+
// optionalDependencies in package.json).
|
|
11
|
+
const PLATFORM_PACKAGES = {
|
|
12
|
+
"darwin-arm64": "cawide-darwin-arm64",
|
|
13
|
+
"darwin-x64": "cawide-darwin-x64",
|
|
14
|
+
"linux-x64": "cawide-linux-x64",
|
|
15
|
+
"linux-arm64": "cawide-linux-arm64",
|
|
16
|
+
"win32-x64": "cawide-win32-x64",
|
|
17
|
+
"win32-arm64": "cawide-win32-arm64",
|
|
19
18
|
};
|
|
20
19
|
const SIGNAL_EXIT_CODES = { SIGINT: 130, SIGTERM: 143 };
|
|
21
20
|
|
|
@@ -23,6 +22,10 @@ function executableName() {
|
|
|
23
22
|
return process.platform === "win32" ? "cawide.exe" : "cawide";
|
|
24
23
|
}
|
|
25
24
|
|
|
25
|
+
function platformKey() {
|
|
26
|
+
return `${process.platform}-${process.arch}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
26
29
|
function localBinary() {
|
|
27
30
|
const repositoryRoot = path.resolve(__dirname, "../../..");
|
|
28
31
|
if (!fs.existsSync(path.join(repositoryRoot, "Cargo.toml"))) return null;
|
|
@@ -34,168 +37,60 @@ function localBinary() {
|
|
|
34
37
|
return null;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
function
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
? process.env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local")
|
|
41
|
-
: path.join(os.homedir(), ".cache");
|
|
42
|
-
return path.join(cacheRoot, "cawide", "bin", `v${VERSION}`, executableName());
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function platformTargets() {
|
|
46
|
-
const targets = TARGETS[`${process.platform}-${process.arch}`];
|
|
47
|
-
if (!targets) {
|
|
40
|
+
function platformPackageName() {
|
|
41
|
+
const packageName = PLATFORM_PACKAGES[platformKey()];
|
|
42
|
+
if (!packageName) {
|
|
48
43
|
throw new Error(
|
|
49
|
-
`Cawide does not provide a binary for ${process.platform}/${process.arch}. Supported platforms:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return targets;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function download(url, redirectsLeft = 5) {
|
|
56
|
-
return new Promise((resolve, reject) => {
|
|
57
|
-
const request = https.get(
|
|
58
|
-
url,
|
|
59
|
-
{ headers: { "User-Agent": `cawide-npm/${VERSION}` } },
|
|
60
|
-
(response) => {
|
|
61
|
-
const status = response.statusCode || 0;
|
|
62
|
-
if (status >= 300 && status < 400 && response.headers.location) {
|
|
63
|
-
response.resume();
|
|
64
|
-
if (redirectsLeft === 0) {
|
|
65
|
-
reject(new Error(`Too many redirects while downloading ${url}`));
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
resolve(download(new URL(response.headers.location, url).toString(), redirectsLeft - 1));
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (status !== 200) {
|
|
72
|
-
response.resume();
|
|
73
|
-
const error = new Error(`Download failed with HTTP ${status}: ${url}`);
|
|
74
|
-
error.statusCode = status;
|
|
75
|
-
reject(error);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const chunks = [];
|
|
80
|
-
response.on("data", (chunk) => chunks.push(chunk));
|
|
81
|
-
response.on("end", () => resolve(Buffer.concat(chunks)));
|
|
82
|
-
response.on("error", reject);
|
|
83
|
-
}
|
|
44
|
+
`Cawide does not provide a binary for ${process.platform}/${process.arch}. Supported platforms: ${Object.keys(
|
|
45
|
+
PLATFORM_PACKAGES
|
|
46
|
+
).join(", ")}.`
|
|
84
47
|
);
|
|
85
|
-
request.on("error", reject);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function tarBinary(archive) {
|
|
90
|
-
const tar = zlib.gunzipSync(archive);
|
|
91
|
-
let offset = 0;
|
|
92
|
-
while (offset + 512 <= tar.length) {
|
|
93
|
-
const header = tar.subarray(offset, offset + 512);
|
|
94
|
-
if (header.every((byte) => byte === 0)) break;
|
|
95
|
-
const name = header.subarray(0, 100).toString("utf8").replace(/\0.*$/, "");
|
|
96
|
-
const sizeText = header.subarray(124, 136).toString("ascii").replace(/\0.*$/, "").trim();
|
|
97
|
-
const size = Number.parseInt(sizeText || "0", 8);
|
|
98
|
-
const dataStart = offset + 512;
|
|
99
|
-
if (!Number.isFinite(size) || dataStart + size > tar.length) {
|
|
100
|
-
throw new Error("Downloaded tar archive is corrupt");
|
|
101
|
-
}
|
|
102
|
-
if (path.posix.basename(name) === "cawide") return tar.subarray(dataStart, dataStart + size);
|
|
103
|
-
offset = dataStart + Math.ceil(size / 512) * 512;
|
|
104
48
|
}
|
|
105
|
-
|
|
49
|
+
return packageName;
|
|
106
50
|
}
|
|
107
51
|
|
|
108
|
-
function
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
52
|
+
function resolvePlatformBinary() {
|
|
53
|
+
const packageName = platformPackageName();
|
|
54
|
+
|
|
55
|
+
let packageJsonPath;
|
|
56
|
+
try {
|
|
57
|
+
packageJsonPath = require.resolve(`${packageName}/package.json`);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (error.code === "MODULE_NOT_FOUND") {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Cawide could not find the "${packageName}" platform package for ${platformKey()}.\n` +
|
|
62
|
+
"This usually happens when the package was installed with --no-optional/--omit=optional, " +
|
|
63
|
+
"npm skipped optional dependencies, or the platform is unsupported.\n" +
|
|
64
|
+
"Try reinstalling without skipping optional dependencies: npm install -g cawide"
|
|
65
|
+
);
|
|
118
66
|
}
|
|
67
|
+
throw error;
|
|
119
68
|
}
|
|
120
|
-
if (endOffset < 0) throw new Error("Downloaded zip archive is corrupt");
|
|
121
69
|
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const method = archive.readUInt16LE(offset + 10);
|
|
129
|
-
const compressedSize = archive.readUInt32LE(offset + 20);
|
|
130
|
-
const fileNameLength = archive.readUInt16LE(offset + 28);
|
|
131
|
-
const extraLength = archive.readUInt16LE(offset + 30);
|
|
132
|
-
const commentLength = archive.readUInt16LE(offset + 32);
|
|
133
|
-
const localOffset = archive.readUInt32LE(offset + 42);
|
|
134
|
-
const name = archive.subarray(offset + 46, offset + 46 + fileNameLength).toString("utf8");
|
|
135
|
-
|
|
136
|
-
if (path.posix.basename(name.replace(/\\/g, "/")) === "cawide.exe") {
|
|
137
|
-
if (archive.readUInt32LE(localOffset) !== localSignature) {
|
|
138
|
-
throw new Error("Downloaded zip archive has an invalid entry");
|
|
139
|
-
}
|
|
140
|
-
const localNameLength = archive.readUInt16LE(localOffset + 26);
|
|
141
|
-
const localExtraLength = archive.readUInt16LE(localOffset + 28);
|
|
142
|
-
const dataStart = localOffset + 30 + localNameLength + localExtraLength;
|
|
143
|
-
const compressed = archive.subarray(dataStart, dataStart + compressedSize);
|
|
144
|
-
if (method === 0) return compressed;
|
|
145
|
-
if (method === 8) return zlib.inflateRawSync(compressed);
|
|
146
|
-
throw new Error(`Downloaded zip uses unsupported compression method ${method}`);
|
|
147
|
-
}
|
|
148
|
-
offset += 46 + fileNameLength + extraLength + commentLength;
|
|
149
|
-
}
|
|
150
|
-
throw new Error("Downloaded archive does not contain cawide.exe");
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async function installBinary(destination) {
|
|
154
|
-
const extension = process.platform === "win32" ? "zip" : "tar.gz";
|
|
155
|
-
let lastError;
|
|
156
|
-
for (const target of platformTargets()) {
|
|
157
|
-
const asset = `cawide-${target}.${extension}`;
|
|
158
|
-
const url = `${RELEASE_BASE}/${asset}`;
|
|
159
|
-
try {
|
|
160
|
-
process.stderr.write(`Downloading Cawide v${VERSION} for ${target}...\n`);
|
|
161
|
-
const archive = await download(url);
|
|
162
|
-
const binary = extension === "zip" ? zipBinary(archive) : tarBinary(archive);
|
|
163
|
-
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
164
|
-
const temporary = `${destination}.${process.pid}.tmp`;
|
|
165
|
-
try {
|
|
166
|
-
fs.writeFileSync(temporary, binary, { mode: 0o755 });
|
|
167
|
-
fs.chmodSync(temporary, 0o755);
|
|
168
|
-
fs.renameSync(temporary, destination);
|
|
169
|
-
} finally {
|
|
170
|
-
if (fs.existsSync(temporary)) fs.unlinkSync(temporary);
|
|
171
|
-
}
|
|
172
|
-
return;
|
|
173
|
-
} catch (error) {
|
|
174
|
-
lastError = error;
|
|
175
|
-
if (error.statusCode !== 404) break;
|
|
176
|
-
}
|
|
70
|
+
const binaryPath = path.join(path.dirname(packageJsonPath), "bin", executableName());
|
|
71
|
+
if (!fs.existsSync(binaryPath)) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`The "${packageName}" platform package is installed but is missing its binary at ${binaryPath}. ` +
|
|
74
|
+
"Try reinstalling: npm install -g cawide"
|
|
75
|
+
);
|
|
177
76
|
}
|
|
178
|
-
|
|
77
|
+
return binaryPath;
|
|
179
78
|
}
|
|
180
79
|
|
|
181
80
|
function run(binaryPath) {
|
|
182
81
|
const result = childProcess.spawnSync(binaryPath, process.argv.slice(2), { stdio: "inherit" });
|
|
183
82
|
if (result.error) throw result.error;
|
|
184
|
-
if (result.signal && SIGNAL_EXIT_CODES[result.signal])
|
|
185
|
-
process.exit(SIGNAL_EXIT_CODES[result.signal]);
|
|
83
|
+
if (result.signal && SIGNAL_EXIT_CODES[result.signal]) process.exit(SIGNAL_EXIT_CODES[result.signal]);
|
|
186
84
|
process.exit(result.status ?? 0);
|
|
187
85
|
}
|
|
188
86
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (local) run(local);
|
|
192
|
-
|
|
193
|
-
const cached = cacheBinary();
|
|
194
|
-
if (!fs.existsSync(cached)) await installBinary(cached);
|
|
195
|
-
run(cached);
|
|
87
|
+
function main() {
|
|
88
|
+
run(localBinary() || resolvePlatformBinary());
|
|
196
89
|
}
|
|
197
90
|
|
|
198
|
-
|
|
91
|
+
try {
|
|
92
|
+
main();
|
|
93
|
+
} catch (error) {
|
|
199
94
|
process.stderr.write(`cawide: ${error.message}\n`);
|
|
200
95
|
process.exit(1);
|
|
201
|
-
}
|
|
96
|
+
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cawide",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "Mobile remote code editor & AI agent terminal companion",
|
|
5
5
|
"homepage": "https://cawide.dev",
|
|
6
6
|
"bugs": "https://cawide.dev/support",
|
|
7
7
|
"bin": {
|
|
8
|
-
"cawide": "
|
|
8
|
+
"cawide": "bin/cawide.js"
|
|
9
9
|
},
|
|
10
|
-
"files": [
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
11
14
|
"engines": {
|
|
12
15
|
"node": ">=16.0.0"
|
|
13
16
|
},
|
|
14
|
-
"keywords": [
|
|
17
|
+
"keywords": [
|
|
18
|
+
"cawide",
|
|
19
|
+
"terminal",
|
|
20
|
+
"ai-agent",
|
|
21
|
+
"remote-editor",
|
|
22
|
+
"mobile",
|
|
23
|
+
"editor"
|
|
24
|
+
],
|
|
15
25
|
"author": "Cawide Team",
|
|
16
|
-
"license": "MIT"
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"optionalDependencies": {
|
|
28
|
+
"cawide-darwin-arm64": "0.4.6",
|
|
29
|
+
"cawide-darwin-x64": "0.4.6",
|
|
30
|
+
"cawide-linux-x64": "0.4.6",
|
|
31
|
+
"cawide-linux-arm64": "0.4.6",
|
|
32
|
+
"cawide-win32-x64": "0.4.6",
|
|
33
|
+
"cawide-win32-arm64": "0.4.6"
|
|
34
|
+
}
|
|
17
35
|
}
|