@abacus-ai/cli 2.5.2-canary.3 → 2.5.3-canary.0

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/package.json CHANGED
@@ -1,21 +1,18 @@
1
1
  {
2
2
  "name": "@abacus-ai/cli",
3
- "version": "2.5.2-canary.3",
4
- "type": "module",
3
+ "version": "2.5.3-canary.0",
5
4
  "bin": {
6
- "abacusai": "dist/index.mjs"
5
+ "abacusai": "scripts/npm-wrapper/shim.cjs"
6
+ },
7
+ "scripts": {
8
+ "postinstall": "node scripts/npm-wrapper/install.cjs"
7
9
  },
8
10
  "files": [
9
- "dist",
11
+ "scripts/npm-wrapper/install.cjs",
12
+ "scripts/npm-wrapper/shim.cjs",
10
13
  "LICENSE.txt"
11
14
  ],
12
15
  "engines": {
13
16
  "node": ">=18"
14
- },
15
- "dependencies": {
16
- "koffi": "^2.15.1",
17
- "@vscode/ripgrep": "1.17.1",
18
- "trash": "^10.1.1",
19
- "node-notifier": "^10.0.1"
20
17
  }
21
18
  }
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const fs = require("node:fs");
5
+ const path = require("node:path");
6
+ const os = require("node:os");
7
+ const https = require("node:https");
8
+ const { execFileSync } = require("node:child_process");
9
+ const { pipeline } = require("node:stream/promises");
10
+
11
+ const BASE_URL = "https://static.abacus.ai/cli/releases";
12
+ const PKG_ROOT = path.resolve(__dirname, "..", "..");
13
+ const PKG_JSON = require(path.join(PKG_ROOT, "package.json"));
14
+ const VERSION = PKG_JSON.version;
15
+
16
+ function detectInstallPm() {
17
+ const ua = process.env.npm_config_user_agent ?? "";
18
+ const name = ua.split("/")[0];
19
+ if (name === "yarn" || name === "pnpm" || name === "bun" || name === "npm") return name;
20
+ return "npm";
21
+ }
22
+
23
+ function detectPlatform() {
24
+ const arch = process.arch;
25
+ if (arch !== "x64" && arch !== "arm64") {
26
+ throw new Error(`Unsupported architecture: ${arch}`);
27
+ }
28
+ switch (process.platform) {
29
+ case "darwin":
30
+ return { target: `darwin-${arch}`, ext: "tar.gz", binaryName: "abacusai" };
31
+ case "linux":
32
+ return { target: `linux-${arch}`, ext: "tar.gz", binaryName: "abacusai" };
33
+ case "win32":
34
+ return { target: `win32-${arch}`, ext: "zip", binaryName: "abacusai.exe" };
35
+ default:
36
+ throw new Error(`Unsupported operating system: ${process.platform}`);
37
+ }
38
+ }
39
+
40
+ function download(url, dest) {
41
+ return new Promise((resolve, reject) => {
42
+ const file = fs.createWriteStream(dest);
43
+ https
44
+ .get(url, { headers: { "user-agent": "abacusai-npm-installer" } }, (res) => {
45
+ if (
46
+ res.statusCode &&
47
+ res.statusCode >= 300 &&
48
+ res.statusCode < 400 &&
49
+ res.headers.location
50
+ ) {
51
+ file.close();
52
+ fs.unlink(dest, () => {});
53
+ download(res.headers.location, dest).then(resolve, reject);
54
+ return;
55
+ }
56
+ if (res.statusCode !== 200) {
57
+ file.close();
58
+ fs.unlink(dest, () => {});
59
+ reject(new Error(`Download failed: HTTP ${res.statusCode} for ${url}`));
60
+ return;
61
+ }
62
+ pipeline(res, file).then(resolve, reject);
63
+ })
64
+ .on("error", (err) => {
65
+ file.close();
66
+ fs.unlink(dest, () => {});
67
+ reject(err);
68
+ });
69
+ });
70
+ }
71
+
72
+ function extract(archivePath, destDir, ext) {
73
+ if (ext === "tar.gz") {
74
+ execFileSync("tar", ["-xzf", archivePath, "-C", destDir], { stdio: "ignore" });
75
+ } else {
76
+ execFileSync(
77
+ "powershell.exe",
78
+ [
79
+ "-NoProfile",
80
+ "-NonInteractive",
81
+ "-Command",
82
+ `Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`,
83
+ ],
84
+ { stdio: "ignore" },
85
+ );
86
+ }
87
+ }
88
+
89
+ function readStamp(stampPath) {
90
+ try {
91
+ return fs.readFileSync(stampPath, "utf8").trim();
92
+ } catch {
93
+ return null;
94
+ }
95
+ }
96
+
97
+ function replaceBinary(stagedPath, targetPath) {
98
+ try {
99
+ fs.renameSync(stagedPath, targetPath);
100
+ return;
101
+ } catch (err) {
102
+ if (process.platform !== "win32") throw err;
103
+ }
104
+ const oldPath = `${targetPath}.old`;
105
+ try {
106
+ fs.unlinkSync(oldPath);
107
+ } catch {}
108
+ try {
109
+ fs.renameSync(targetPath, oldPath);
110
+ } catch {}
111
+ fs.renameSync(stagedPath, targetPath);
112
+ }
113
+
114
+ async function main() {
115
+ const { target, ext, binaryName } = detectPlatform();
116
+ const binDir = path.join(PKG_ROOT, "bin");
117
+ const targetPath = path.join(binDir, binaryName);
118
+ const stampPath = path.join(binDir, ".version");
119
+
120
+ if (readStamp(stampPath) === VERSION && fs.existsSync(targetPath)) return;
121
+
122
+ fs.mkdirSync(binDir, { recursive: true });
123
+
124
+ const archiveName = `abacusai-${target}.${ext}`;
125
+ const url = `${BASE_URL}/${VERSION}/${archiveName}`;
126
+
127
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "abacusai-install-"));
128
+ const archivePath = path.join(tmpDir, archiveName);
129
+
130
+ process.stdout.write(`abacusai: downloading v${VERSION} for ${target}...\n`);
131
+
132
+ try {
133
+ await download(url, archivePath);
134
+ extract(archivePath, tmpDir, ext);
135
+
136
+ const sourceBinary = path.join(tmpDir, binaryName);
137
+ const stagedPath = `${targetPath}.new`;
138
+ fs.copyFileSync(sourceBinary, stagedPath);
139
+ if (process.platform !== "win32") fs.chmodSync(stagedPath, 0o755);
140
+
141
+ replaceBinary(stagedPath, targetPath);
142
+ fs.writeFileSync(stampPath, VERSION);
143
+ fs.writeFileSync(path.join(binDir, ".install-source"), detectInstallPm());
144
+
145
+ process.stdout.write(`abacusai: installed v${VERSION} to ${targetPath}\n`);
146
+ } finally {
147
+ try {
148
+ fs.rmSync(tmpDir, { recursive: true, force: true });
149
+ } catch {}
150
+ }
151
+ }
152
+
153
+ main().catch((err) => {
154
+ process.stderr.write(`abacusai: install failed: ${err && err.message ? err.message : err}\n`);
155
+ process.stderr.write(
156
+ ` Re-run with: npm rebuild ${PKG_JSON.name} (or run \`abacusai\` to retry)\n`,
157
+ );
158
+ process.exit(0);
159
+ });
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const fs = require("node:fs");
5
+ const path = require("node:path");
6
+ const { spawnSync } = require("node:child_process");
7
+
8
+ const PKG_ROOT = path.resolve(__dirname, "..", "..");
9
+ const BIN_DIR = path.join(PKG_ROOT, "bin");
10
+ const BINARY_NAME = process.platform === "win32" ? "abacusai.exe" : "abacusai";
11
+ const BINARY_PATH = path.join(BIN_DIR, BINARY_NAME);
12
+
13
+ if (!fs.existsSync(BINARY_PATH)) {
14
+ const installer = path.join(__dirname, "install.cjs");
15
+ const res = spawnSync(process.execPath, [installer], { stdio: "inherit" });
16
+ if (res.status !== 0 || !fs.existsSync(BINARY_PATH)) {
17
+ process.stderr.write(`abacusai: failed to install native binary at ${BINARY_PATH}\n`);
18
+ process.exit(res.status ?? 1);
19
+ }
20
+ }
21
+
22
+ function readInstallSource() {
23
+ try {
24
+ return fs.readFileSync(path.join(BIN_DIR, ".install-source"), "utf8").trim() || "npm";
25
+ } catch {
26
+ return "npm";
27
+ }
28
+ }
29
+
30
+ const result = spawnSync(BINARY_PATH, process.argv.slice(2), {
31
+ stdio: "inherit",
32
+ env: { ...process.env, ABACUSAI_INSTALL_SOURCE: readInstallSource() },
33
+ });
34
+
35
+ if (result.error) {
36
+ process.stderr.write(`abacusai: failed to launch binary: ${result.error.message}\n`);
37
+ process.exit(1);
38
+ }
39
+
40
+ if (result.signal) {
41
+ process.kill(process.pid, result.signal);
42
+ return;
43
+ }
44
+
45
+ process.exit(result.status ?? 0);