sphere-cli 0.2.0 → 0.2.1

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,8 +1,13 @@
1
1
  {
2
2
  "name": "sphere-cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "SPHERE CLI — synthetic data generation, evaluation, and certification (sealed native binary)",
5
- "keywords": ["synthetic-data", "privacy", "cli", "data-science"],
5
+ "keywords": [
6
+ "synthetic-data",
7
+ "privacy",
8
+ "cli",
9
+ "data-science"
10
+ ],
6
11
  "homepage": "https://github.com/statzihuai/sphere-cli",
7
12
  "bugs": "https://github.com/statzihuai/sphere-cli/issues",
8
13
  "repository": {
@@ -24,6 +29,12 @@
24
29
  "engines": {
25
30
  "node": ">=18.0.0"
26
31
  },
27
- "os": ["darwin", "linux"],
28
- "cpu": ["arm64", "x64"]
32
+ "os": [
33
+ "darwin",
34
+ "linux"
35
+ ],
36
+ "cpu": [
37
+ "arm64",
38
+ "x64"
39
+ ]
29
40
  }
@@ -22,6 +22,9 @@ const { execFileSync } = require('child_process');
22
22
  const PKG = require('../package.json');
23
23
  const VERSION = PKG.version;
24
24
  const REPO = 'statzihuai/sphere-cli';
25
+ // Binary release tag — decoupled from the npm package version so JS-only patch
26
+ // releases reuse the same prebuilt/notarized binaries without re-uploading them.
27
+ const BINARY_RELEASE = 'v0.2.0';
25
28
 
26
29
  const PLATFORM = process.platform; // 'darwin' | 'linux'
27
30
  const ARCH = process.arch; // 'arm64' | 'x64'
@@ -32,7 +35,7 @@ const PKG_ROOT = path.join(__dirname, '..');
32
35
  const VENDOR = path.join(PKG_ROOT, 'vendor');
33
36
  const ASSET = `sphere-${KEY}.tar.gz`;
34
37
  const BASE = process.env.SPHERE_BINARY_BASEURL
35
- || `https://github.com/${REPO}/releases/download/v${VERSION}`;
38
+ || `https://github.com/${REPO}/releases/download/${BINARY_RELEASE}`;
36
39
 
37
40
  function log(m) { process.stdout.write(`sphere-cli: ${m}\n`); }
38
41
  function fail(m) { process.stderr.write(`sphere-cli: ${m}\n`); process.exit(1); }
@@ -55,8 +58,8 @@ if (!SUPPORTED.has(KEY)) {
55
58
  const STAMP = path.join(VENDOR, '.version');
56
59
  const BIN = path.join(VENDOR, 'sphere-cli', 'sphere');
57
60
  if (fs.existsSync(BIN) && fs.existsSync(STAMP) &&
58
- fs.readFileSync(STAMP, 'utf8').trim() === VERSION) {
59
- log(`binary already present for v${VERSION}.`);
61
+ fs.readFileSync(STAMP, 'utf8').trim() === BINARY_RELEASE) {
62
+ log(`binary already present (${BINARY_RELEASE}).`);
60
63
  process.exit(0);
61
64
  }
62
65
 
@@ -97,7 +100,31 @@ try {
97
100
  execFileSync('tar', ['-xzf', tarball, '-C', VENDOR], { stdio: 'inherit' });
98
101
  fs.chmodSync(BIN, 0o755);
99
102
  fs.unlinkSync(tarball);
100
- fs.writeFileSync(STAMP, VERSION);
103
+ fs.rmSync(sumsFile, { force: true });
104
+ fs.writeFileSync(STAMP, BINARY_RELEASE);
105
+
106
+ // ── macOS: avoid a painfully slow FIRST run ────────────────────────────────
107
+ // A downloaded, unstapled notarized onedir pays a one-time Gatekeeper check of
108
+ // all ~330 bundled libraries on first launch (looks frozen on "loading pandas").
109
+ // (1) strip quarantine/provenance xattrs → skips the slow *online* assessment;
110
+ // (2) warm the binary now (during install, when waiting is expected) so the
111
+ // user's first real command is instant. Both are best-effort.
112
+ if (PLATFORM === 'darwin') {
113
+ try { execFileSync('xattr', ['-cr', path.join(VENDOR, 'sphere-cli')], { stdio: 'ignore' }); } catch (_) {}
114
+ try {
115
+ log('warming binary (one-time macOS security scan, ~30–60s) …');
116
+ const warmIn = path.join(VENDOR, '.warm.csv');
117
+ const warmOut = path.join(VENDOR, '.warm_out.csv');
118
+ fs.writeFileSync(warmIn, 'a,b\n1.0,2.0\n3.0,4.0\n5.0,6.0\n');
119
+ execFileSync(BIN, ['generate', warmIn, '-o', warmOut], {
120
+ stdio: 'ignore',
121
+ timeout: 180000,
122
+ env: { ...process.env, SPHERE_LICENSE_REQUIRED: 'false' },
123
+ });
124
+ for (const f of [warmIn, warmOut, warmOut + '.sphere.json']) fs.rmSync(f, { force: true });
125
+ log('binary warmed ✓ — first run will be fast.');
126
+ } catch (_) { /* best-effort; user just pays the scan on first run */ }
127
+ }
101
128
 
102
129
  log(`installed sealed binary for ${KEY} ✓`);
103
130
  } catch (e) {