@cloneisyou/cli 0.1.1 → 0.1.2-darwin-arm64
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 +1 -0
- package/package.json +8 -35
- package/vendor/darwin-arm64/clone/clone +0 -0
- package/bin/clone.js +0 -26
- package/scripts/install-native.js +0 -13
- package/scripts/native.js +0 -244
- package/scripts/sync-platform-deps.js +0 -18
package/README.md
CHANGED
|
@@ -78,6 +78,7 @@ Useful environment variables:
|
|
|
78
78
|
- `CLONE_HOME`: override Clone's data directory. Defaults to `~/.clone`.
|
|
79
79
|
- `CLONE_DISABLE_TRAY=1`: disable the desktop tray/menu-bar recording indicator.
|
|
80
80
|
- `CLONE_DISABLE_CONTEXT_WORKER=1`: disable background context screenshots.
|
|
81
|
+
- `CLONE_SKIP_UPDATE_CHECK=1`: skip the npm `latest` version check before launching.
|
|
81
82
|
- `CLONE_SKIP_NATIVE_INSTALL=1`: skip download attempts during install.
|
|
82
83
|
|
|
83
84
|
Development smoke test:
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloneisyou/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Native
|
|
3
|
+
"version": "0.1.2-darwin-arm64",
|
|
4
|
+
"description": "Native Clone CLI binary for darwin-arm64",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
|
-
"private": false,
|
|
7
6
|
"author": "Clone Labs, Inc.",
|
|
8
7
|
"homepage": "https://clone.is",
|
|
9
8
|
"repository": {
|
|
@@ -11,43 +10,17 @@
|
|
|
11
10
|
"url": "git+https://github.com/cloneisyou/clone.git",
|
|
12
11
|
"directory": "apps/cli/npm"
|
|
13
12
|
},
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
},
|
|
17
|
-
"keywords": [
|
|
18
|
-
"clone",
|
|
19
|
-
"cli",
|
|
20
|
-
"agent",
|
|
21
|
-
"automation",
|
|
22
|
-
"capture",
|
|
23
|
-
"memory",
|
|
24
|
-
"terminal"
|
|
25
|
-
],
|
|
26
|
-
"publishConfig": {
|
|
27
|
-
"access": "public"
|
|
28
|
-
},
|
|
13
|
+
"os": ["darwin"],
|
|
14
|
+
"cpu": ["arm64"],
|
|
29
15
|
"bin": {
|
|
30
|
-
"clone": "
|
|
31
|
-
},
|
|
32
|
-
"optionalDependencies": {
|
|
33
|
-
"@cloneisyou/cli-darwin-arm64": "npm:@cloneisyou/cli@0.1.1-darwin-arm64",
|
|
34
|
-
"@cloneisyou/cli-darwin-x64": "npm:@cloneisyou/cli@0.1.1-darwin-x64",
|
|
35
|
-
"@cloneisyou/cli-linux-x64": "npm:@cloneisyou/cli@0.1.1-linux-x64",
|
|
36
|
-
"@cloneisyou/cli-win32-x64": "npm:@cloneisyou/cli@0.1.1-win32-x64"
|
|
16
|
+
"clone": "vendor/darwin-arm64/clone/clone"
|
|
37
17
|
},
|
|
38
18
|
"files": [
|
|
39
|
-
"
|
|
40
|
-
"scripts",
|
|
19
|
+
"vendor",
|
|
41
20
|
"README.md",
|
|
42
21
|
"LICENSE.md"
|
|
43
22
|
],
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"postinstall": "node scripts/install-native.js",
|
|
47
|
-
"sync-platform-deps": "node scripts/sync-platform-deps.js",
|
|
48
|
-
"smoke": "node -e \"const native=require('./scripts/native'); console.log(native.resolvePlatformKey())\" && npm pack --dry-run"
|
|
49
|
-
},
|
|
50
|
-
"engines": {
|
|
51
|
-
"node": ">=18"
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
52
25
|
}
|
|
53
26
|
}
|
|
Binary file
|
package/bin/clone.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
const { spawnSync } = require("node:child_process");
|
|
5
|
-
const { ensureNative } = require("../scripts/native");
|
|
6
|
-
|
|
7
|
-
main().catch((error) => {
|
|
8
|
-
process.stderr.write(`\nClone npm wrapper error:\n${error.message}\n`);
|
|
9
|
-
process.exit(1);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
async function main() {
|
|
13
|
-
const executable = await ensureNative({ allowDownload: true });
|
|
14
|
-
const result = spawnSync(executable, process.argv.slice(2), {
|
|
15
|
-
stdio: "inherit",
|
|
16
|
-
env: process.env,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
if (result.error) {
|
|
20
|
-
throw new Error(`failed to run Clone CLI: ${result.error.message}`);
|
|
21
|
-
}
|
|
22
|
-
if (result.signal) {
|
|
23
|
-
process.kill(process.pid, result.signal);
|
|
24
|
-
}
|
|
25
|
-
process.exit(result.status ?? 1);
|
|
26
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const { ensureNative } = require("./native");
|
|
4
|
-
|
|
5
|
-
ensureNative({ allowDownload: true, optional: true })
|
|
6
|
-
.then((executable) => {
|
|
7
|
-
if (executable) {
|
|
8
|
-
process.stderr.write(`▮ CLONE native binary ready: ${executable}\n`);
|
|
9
|
-
}
|
|
10
|
-
})
|
|
11
|
-
.catch((error) => {
|
|
12
|
-
process.stderr.write(`▮ CLONE native install skipped: ${error.message}\n`);
|
|
13
|
-
});
|
package/scripts/native.js
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const crypto = require("node:crypto");
|
|
4
|
-
const fs = require("node:fs");
|
|
5
|
-
const https = require("node:https");
|
|
6
|
-
const os = require("node:os");
|
|
7
|
-
const path = require("node:path");
|
|
8
|
-
const { pipeline } = require("node:stream/promises");
|
|
9
|
-
|
|
10
|
-
const packageRoot = path.resolve(__dirname, "..");
|
|
11
|
-
const packageJson = require(path.join(packageRoot, "package.json"));
|
|
12
|
-
const runtimeRoot = path.resolve(
|
|
13
|
-
process.env.CLONE_NPM_RUNTIME ||
|
|
14
|
-
path.join(os.homedir(), ".clone", "npm-runtime", packageJson.version),
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
async function ensureNative({ allowDownload = true, optional = false } = {}) {
|
|
18
|
-
const existing = findNative();
|
|
19
|
-
if (existing) {
|
|
20
|
-
return existing;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (process.env.CLONE_SKIP_NATIVE_INSTALL === "1" || !allowDownload) {
|
|
24
|
-
return failOrNull(missingNativeMessage(), optional);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!releaseBaseUrl()) {
|
|
28
|
-
return failOrNull(missingNativeMessage(), optional);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
return await downloadNative();
|
|
33
|
-
} catch (error) {
|
|
34
|
-
return failOrNull(`${missingNativeMessage()}\n\nDownload failed: ${error.message}`, optional);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function findNative() {
|
|
39
|
-
const explicit = process.env.CLONE_NATIVE_BINARY;
|
|
40
|
-
if (explicit && isExecutableFile(explicit)) {
|
|
41
|
-
return path.resolve(explicit);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const optionalPackageBinary = findOptionalPackageBinary();
|
|
45
|
-
if (optionalPackageBinary) {
|
|
46
|
-
return optionalPackageBinary;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const cached = cachedBinaryPath();
|
|
50
|
-
if (isExecutableFile(cached)) {
|
|
51
|
-
return cached;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function findOptionalPackageBinary() {
|
|
58
|
-
const packageName = `@cloneisyou/cli-${resolvePlatformKey()}`;
|
|
59
|
-
try {
|
|
60
|
-
const manifestPath = require.resolve(`${packageName}/package.json`, {
|
|
61
|
-
paths: [packageRoot],
|
|
62
|
-
});
|
|
63
|
-
const manifest = require(manifestPath);
|
|
64
|
-
const binField = typeof manifest.bin === "string" ? manifest.bin : manifest.bin?.clone;
|
|
65
|
-
if (!binField) {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
const candidate = path.resolve(path.dirname(manifestPath), binField);
|
|
69
|
-
return isExecutableFile(candidate) ? candidate : null;
|
|
70
|
-
} catch {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function downloadNative() {
|
|
76
|
-
const platform = resolvePlatformKey();
|
|
77
|
-
const manifest = await fetchManifest().catch(() => null);
|
|
78
|
-
const entry = manifest?.platforms?.[platform];
|
|
79
|
-
const downloadUrl = entry?.url || buildDefaultBinaryUrl(platform);
|
|
80
|
-
const expectedSha256 = entry?.sha256 || entry?.checksum || null;
|
|
81
|
-
const destination = cachedBinaryPath();
|
|
82
|
-
const temp = `${destination}.tmp-${process.pid}`;
|
|
83
|
-
|
|
84
|
-
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
85
|
-
log(`installing native Clone CLI for ${platform}`);
|
|
86
|
-
await downloadFile(downloadUrl, temp);
|
|
87
|
-
|
|
88
|
-
if (expectedSha256) {
|
|
89
|
-
const actual = sha256File(temp);
|
|
90
|
-
if (actual.toLowerCase() !== expectedSha256.toLowerCase()) {
|
|
91
|
-
safeUnlink(temp);
|
|
92
|
-
throw new Error(`checksum mismatch for ${downloadUrl}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
fs.renameSync(temp, destination);
|
|
97
|
-
if (process.platform !== "win32") {
|
|
98
|
-
fs.chmodSync(destination, 0o755);
|
|
99
|
-
}
|
|
100
|
-
return destination;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async function fetchManifest() {
|
|
104
|
-
const baseUrl = releaseBaseUrl();
|
|
105
|
-
const manifestUrl = `${baseUrl.replace(/\/$/, "")}/manifest.json`;
|
|
106
|
-
const text = await readUrl(manifestUrl);
|
|
107
|
-
return JSON.parse(text);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function buildDefaultBinaryUrl(platform) {
|
|
111
|
-
const baseUrl = releaseBaseUrl().replace(/\/$/, "");
|
|
112
|
-
const extension = process.platform === "win32" ? ".exe" : "";
|
|
113
|
-
return `${baseUrl}/clone-${platform}${extension}`;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function releaseBaseUrl() {
|
|
117
|
-
return process.env.CLONE_DOWNLOAD_BASE_URL || null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function cachedBinaryPath() {
|
|
121
|
-
return path.join(runtimeRoot, "native", resolvePlatformKey(), binaryName());
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function binaryName() {
|
|
125
|
-
return process.platform === "win32" ? "clone.exe" : "clone";
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function resolvePlatformKey() {
|
|
129
|
-
const platform = process.platform;
|
|
130
|
-
const arch = process.arch;
|
|
131
|
-
const supported = new Set([
|
|
132
|
-
"darwin-arm64",
|
|
133
|
-
"darwin-x64",
|
|
134
|
-
"linux-x64",
|
|
135
|
-
"win32-x64",
|
|
136
|
-
]);
|
|
137
|
-
const key = `${platform}-${arch}`;
|
|
138
|
-
if (!supported.has(key)) {
|
|
139
|
-
throw new Error(`unsupported platform: ${key}`);
|
|
140
|
-
}
|
|
141
|
-
return key;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function isExecutableFile(filePath) {
|
|
145
|
-
try {
|
|
146
|
-
return fs.statSync(filePath).isFile();
|
|
147
|
-
} catch {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async function readUrl(url) {
|
|
153
|
-
return new Promise((resolve, reject) => {
|
|
154
|
-
https
|
|
155
|
-
.get(url, (response) => {
|
|
156
|
-
if (isRedirect(response.statusCode)) {
|
|
157
|
-
readUrl(response.headers.location).then(resolve, reject);
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
if (response.statusCode !== 200) {
|
|
161
|
-
reject(new Error(`${url} returned HTTP ${response.statusCode}`));
|
|
162
|
-
response.resume();
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
response.setEncoding("utf8");
|
|
166
|
-
let body = "";
|
|
167
|
-
response.on("data", (chunk) => {
|
|
168
|
-
body += chunk;
|
|
169
|
-
});
|
|
170
|
-
response.on("end", () => resolve(body));
|
|
171
|
-
})
|
|
172
|
-
.on("error", reject);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async function downloadFile(url, destination) {
|
|
177
|
-
await new Promise((resolve, reject) => {
|
|
178
|
-
https
|
|
179
|
-
.get(url, (response) => {
|
|
180
|
-
if (isRedirect(response.statusCode)) {
|
|
181
|
-
downloadFile(response.headers.location, destination).then(resolve, reject);
|
|
182
|
-
response.resume();
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
if (response.statusCode !== 200) {
|
|
186
|
-
reject(new Error(`${url} returned HTTP ${response.statusCode}`));
|
|
187
|
-
response.resume();
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
pipeline(response, fs.createWriteStream(destination)).then(resolve, reject);
|
|
191
|
-
})
|
|
192
|
-
.on("error", reject);
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function isRedirect(statusCode) {
|
|
197
|
-
return [301, 302, 303, 307, 308].includes(statusCode);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function sha256File(filePath) {
|
|
201
|
-
const hash = crypto.createHash("sha256");
|
|
202
|
-
hash.update(fs.readFileSync(filePath));
|
|
203
|
-
return hash.digest("hex");
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function safeUnlink(filePath) {
|
|
207
|
-
try {
|
|
208
|
-
fs.unlinkSync(filePath);
|
|
209
|
-
} catch {
|
|
210
|
-
// Best-effort cleanup only.
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function failOrNull(message, optional) {
|
|
215
|
-
if (optional) {
|
|
216
|
-
log(message);
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
throw new Error(message);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function missingNativeMessage() {
|
|
223
|
-
return [
|
|
224
|
-
"Clone native binary is not installed.",
|
|
225
|
-
"",
|
|
226
|
-
"This npm package intentionally does not include Clone's proprietary Python source.",
|
|
227
|
-
"Install options:",
|
|
228
|
-
" 1. Reinstall @cloneisyou/cli without --omit=optional so npm can install the matching platform package.",
|
|
229
|
-
" 2. For internal development, set CLONE_NATIVE_BINARY to an existing clone executable.",
|
|
230
|
-
" 3. For private artifact testing, set CLONE_DOWNLOAD_BASE_URL explicitly.",
|
|
231
|
-
].join("\n");
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
function log(message) {
|
|
235
|
-
process.stderr.write(`▮ CLONE ${message}\n`);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
module.exports = {
|
|
239
|
-
ensureNative,
|
|
240
|
-
findNative,
|
|
241
|
-
resolvePlatformKey,
|
|
242
|
-
cachedBinaryPath,
|
|
243
|
-
releaseBaseUrl,
|
|
244
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const fs = require("node:fs");
|
|
4
|
-
const path = require("node:path");
|
|
5
|
-
|
|
6
|
-
const packagePath = path.resolve(__dirname, "..", "package.json");
|
|
7
|
-
const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
|
|
8
|
-
const platforms = ["darwin-arm64", "darwin-x64", "linux-x64", "win32-x64"];
|
|
9
|
-
|
|
10
|
-
packageJson.optionalDependencies = Object.fromEntries(
|
|
11
|
-
platforms.map((platform) => [
|
|
12
|
-
`@cloneisyou/cli-${platform}`,
|
|
13
|
-
`npm:@cloneisyou/cli@${packageJson.version}-${platform}`,
|
|
14
|
-
]),
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
fs.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
18
|
-
console.error(`synced optional platform dependencies for ${packageJson.version}`);
|