@starkscan/cli 0.1.0-alpha.0 → 0.1.0-alpha.2

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 CHANGED
@@ -15,6 +15,23 @@ One-off agent run:
15
15
  npx @starkscan/cli@alpha doctor
16
16
  ```
17
17
 
18
+ For unattended agents or production services, pin a smoked exact version instead
19
+ of floating on `@alpha`.
20
+
21
+ ## Trust status
22
+
23
+ - npm: <https://www.npmjs.com/package/@starkscan/cli>
24
+ - public trust docs: <https://starkscan.co/docs/build/package-trust>
25
+ - machine-readable matrix: <https://starkscan.co/public-client-surface-matrix.json>
26
+ - Socket signal: <https://socket.dev/npm/package/@starkscan/cli>
27
+
28
+ Socket is an external package-risk signal, not a formal Starkscan security
29
+ certificate. Starkscan package promotion also requires bundled-artifact checksum
30
+ verification, manual passkey or Trusted Publishing/OIDC publish control, and
31
+ the launch gates documented at the public package trust page. The canonical
32
+ source repository is private, so public package trust links intentionally point
33
+ to Starkscan docs instead of GitHub.
34
+
18
35
  The wrapper uses bundled native artifacts when they are present in the published package, verifies downloaded or bundled archives against checksums in the release manifest, rejects malformed archives, caches the native `starkscan` binary, and forwards all arguments to it. It does not require a Rust toolchain or repository access.
19
36
 
20
37
  MCP client setup uses the same package. `print-config` emits machine-readable
@@ -46,10 +63,10 @@ By default, the package resolves to bundled artifacts under `artifacts/v<package
46
63
 
47
64
  - `STARKSCAN_CLI_RELEASE_TAG`: release tag, or `latest`
48
65
  - `STARKSCAN_CLI_BUNDLED_ARTIFACT_DIR`: maintainer/test override for the bundled artifact root. Use an absolute path in CI, or a cwd-relative path locally, pointing to a root that contains `artifacts/v<release-tag>/starkscan-cli-manifest.json` and matching platform archives. Example: `STARKSCAN_CLI_BUNDLED_ARTIFACT_DIR=/tmp/starkscan-cli-artifacts npx @starkscan/cli@alpha doctor`
49
- - `STARKSCAN_CLI_RELEASE_BASE_URL`: release base URL, default `https://github.com/starknet-innovation/starkscan/releases`
66
+ - `STARKSCAN_CLI_RELEASE_BASE_URL`: maintainer/test release base URL override. Published public packages use bundled artifacts first; beta clients should not set this.
50
67
  - `STARKSCAN_CLI_CACHE_DIR`: cache root for downloaded native binaries
51
68
  - `STARKSCAN_CLI_BIN_PATH`: use an existing local `starkscan` binary and skip download
52
- - `STARKSCAN_CLI_RELEASE_REPO`: GitHub repo path, default `starknet-innovation/starkscan`
69
+ - `STARKSCAN_CLI_RELEASE_REPO`: maintainer/test GitHub repo path override
53
70
  - `STARKSCAN_CLI_PLATFORM_OVERRIDE`: force a specific target platform for cross-platform testing
54
71
  - `STARKSCAN_CLI_DOWNLOAD_TIMEOUT_MS`: download inactivity timeout in milliseconds, default `120000`
55
72
 
@@ -1,34 +1,34 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-05-28T07:50:25Z",
3
+ "generatedAt": "2026-06-04T11:06:41Z",
4
4
  "artifacts": [
5
5
  {
6
6
  "name": "starkscan-darwin-aarch64.tar.gz",
7
7
  "platform": "darwin-aarch64",
8
8
  "target": "darwin-aarch64",
9
9
  "archive": "starkscan-darwin-aarch64.tar.gz",
10
- "sha256": "ab12b551feb00ea3680b098dae25345f96fb22a1715c7f576488fd02ee6120e7"
10
+ "sha256": "a7b841e723af2c89269ca28b461ca6ef94b3cda329a38076356837225e649496"
11
11
  },
12
12
  {
13
13
  "name": "starkscan-darwin-x86_64.tar.gz",
14
14
  "platform": "darwin-x86_64",
15
15
  "target": "darwin-x86_64",
16
16
  "archive": "starkscan-darwin-x86_64.tar.gz",
17
- "sha256": "d2eb41a1a8c70cfe2ba064fcc018b4c2c34ea7b1d2fc2f61a004ed365d8a43d6"
17
+ "sha256": "c99ddc5b28f6dcfab8523a6c13ab629fbc38a772c001bb75320490cb83fef382"
18
18
  },
19
19
  {
20
20
  "name": "starkscan-linux-aarch64.tar.gz",
21
21
  "platform": "linux-aarch64",
22
22
  "target": "linux-aarch64",
23
23
  "archive": "starkscan-linux-aarch64.tar.gz",
24
- "sha256": "18e93c6e3ccbce6d9084607f8f86c729b8cb6a67a65d05e566be8f8ad066e250"
24
+ "sha256": "b41ed5a797590eab738a63999b64244e18a546d3ffb4b7659e3e67f81f894597"
25
25
  },
26
26
  {
27
27
  "name": "starkscan-linux-x86_64.tar.gz",
28
28
  "platform": "linux-x86_64",
29
29
  "target": "linux-x86_64",
30
30
  "archive": "starkscan-linux-x86_64.tar.gz",
31
- "sha256": "1a97868b0096dc491c0b6b2f7b41e5056d9581c4117010f25ae769ee9e14bd03"
31
+ "sha256": "604970a343d948d426f5482630ac36cd42eb56989f1b3c6eae9113e0bc1584de"
32
32
  }
33
33
  ]
34
34
  }
@@ -0,0 +1 @@
1
+ a7b841e723af2c89269ca28b461ca6ef94b3cda329a38076356837225e649496 starkscan-darwin-aarch64.tar.gz
@@ -0,0 +1 @@
1
+ c99ddc5b28f6dcfab8523a6c13ab629fbc38a772c001bb75320490cb83fef382 starkscan-darwin-x86_64.tar.gz
@@ -0,0 +1 @@
1
+ b41ed5a797590eab738a63999b64244e18a546d3ffb4b7659e3e67f81f894597 starkscan-linux-aarch64.tar.gz
@@ -0,0 +1 @@
1
+ 604970a343d948d426f5482630ac36cd42eb56989f1b3c6eae9113e0bc1584de starkscan-linux-x86_64.tar.gz
package/package.json CHANGED
@@ -1,20 +1,14 @@
1
1
  {
2
2
  "name": "@starkscan/cli",
3
3
  "private": false,
4
- "version": "0.1.0-alpha.0",
4
+ "version": "0.1.0-alpha.2",
5
5
  "description": "npm/npx launcher for the prebuilt Starkscan explorer CLI.",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "publishConfig": {
9
- "access": "public",
10
- "provenance": true
9
+ "access": "public"
11
10
  },
12
- "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/starknet-innovation/mezcal.git",
15
- "directory": "webapp/packages/cli"
16
- },
17
- "homepage": "https://github.com/starknet-innovation/mezcal/tree/main/webapp/packages/cli",
11
+ "homepage": "https://starkscan.co/docs/ai/agent-cli",
18
12
  "keywords": [
19
13
  "starkscan",
20
14
  "starknet",
@@ -22,9 +22,7 @@ const SUPPORTED_PLATFORMS = new Set([
22
22
  'linux-x86_64',
23
23
  ]);
24
24
  const PUBLIC_BINARY_NAME = 'starkscan';
25
- const LEGACY_BINARY_NAME = 'mezcal';
26
25
  const PUBLIC_MANIFEST_FILENAME = 'starkscan-cli-manifest.json';
27
- const LEGACY_MANIFEST_FILENAME = 'mezcal-cli-manifest.json';
28
26
 
29
27
  function env(name) {
30
28
  const value = process.env[name]?.trim();
@@ -204,14 +202,9 @@ function bundledArtifactRootUrl(releaseTag) {
204
202
  }
205
203
 
206
204
  async function hasBundledArtifacts(releaseTag) {
207
- for (const manifestFilename of [PUBLIC_MANIFEST_FILENAME, LEGACY_MANIFEST_FILENAME]) {
208
- const manifestPath = path.join(bundledArtifactRoot(), releaseTag, manifestFilename);
209
- const stat = await lstat(manifestPath).catch(() => null);
210
- if (stat?.isFile()) {
211
- return true;
212
- }
213
- }
214
- return false;
205
+ const manifestPath = path.join(bundledArtifactRoot(), releaseTag, PUBLIC_MANIFEST_FILENAME);
206
+ const stat = await lstat(manifestPath).catch(() => null);
207
+ return Boolean(stat?.isFile());
215
208
  }
216
209
 
217
210
  export function resolveRedirectUrl(url, location, redirectsLeft) {
@@ -322,15 +315,15 @@ function validateArtifact(artifact, platform) {
322
315
  if (artifact.platform !== platform) {
323
316
  fail(`release manifest selected wrong platform: ${artifact.platform}`);
324
317
  }
325
- const acceptedArchives = [`starkscan-${platform}.tar.gz`, `mezcal-${platform}.tar.gz`];
318
+ const expectedArchive = `starkscan-${platform}.tar.gz`;
326
319
  if (artifact.archive === undefined && artifact.name === undefined) {
327
- fail(`release manifest artifact for ${platform} must use one of ${acceptedArchives.join(', ')}`);
320
+ fail(`release manifest artifact for ${platform} must use ${expectedArchive}`);
328
321
  }
329
- if (artifact.archive !== undefined && !acceptedArchives.includes(artifact.archive)) {
330
- fail(`release manifest artifact archive for ${platform} must be one of ${acceptedArchives.join(', ')}`);
322
+ if (artifact.archive !== undefined && artifact.archive !== expectedArchive) {
323
+ fail(`release manifest artifact archive for ${platform} must be ${expectedArchive}`);
331
324
  }
332
- if (artifact.name !== undefined && !acceptedArchives.includes(artifact.name)) {
333
- fail(`release manifest artifact name for ${platform} must be one of ${acceptedArchives.join(', ')}`);
325
+ if (artifact.name !== undefined && artifact.name !== expectedArchive) {
326
+ fail(`release manifest artifact name for ${platform} must be ${expectedArchive}`);
334
327
  }
335
328
  if (artifact.archive !== undefined && artifact.name !== undefined && artifact.archive !== artifact.name) {
336
329
  fail(`release manifest artifact name and archive for ${platform} must match`);
@@ -345,22 +338,17 @@ function validateArtifact(artifact, platform) {
345
338
  }
346
339
 
347
340
  async function readManifest(rootUrl, tempDir) {
348
- const attempts = [];
349
- for (const manifestFilename of [PUBLIC_MANIFEST_FILENAME, LEGACY_MANIFEST_FILENAME]) {
350
- const manifestPath = path.join(tempDir, manifestFilename);
351
- try {
352
- await downloadFile(releaseAssetUrl(rootUrl, manifestFilename), manifestPath);
353
- } catch (error) {
354
- await rm(manifestPath, { force: true }).catch(() => {});
355
- if (!isMissingManifestDownload(error)) {
356
- fail(`release manifest ${manifestFilename} could not be downloaded: ${errorMessage(error)}`);
357
- }
358
- attempts.push(`${manifestFilename}: ${errorMessage(error)}`);
359
- continue;
341
+ const manifestPath = path.join(tempDir, PUBLIC_MANIFEST_FILENAME);
342
+ try {
343
+ await downloadFile(releaseAssetUrl(rootUrl, PUBLIC_MANIFEST_FILENAME), manifestPath);
344
+ } catch (error) {
345
+ await rm(manifestPath, { force: true }).catch(() => {});
346
+ if (!isMissingManifestDownload(error)) {
347
+ fail(`release manifest ${PUBLIC_MANIFEST_FILENAME} could not be downloaded: ${errorMessage(error)}`);
360
348
  }
361
- return await readDownloadedManifest(manifestPath, manifestFilename);
349
+ fail(`release manifest ${PUBLIC_MANIFEST_FILENAME} not found: ${errorMessage(error)}`);
362
350
  }
363
- fail(`release manifest not found; tried ${attempts.join('; ')}`);
351
+ return await readDownloadedManifest(manifestPath, PUBLIC_MANIFEST_FILENAME);
364
352
  }
365
353
 
366
354
  async function installFromRelease({ platform, releaseTag, cachePath, rootUrl }) {
@@ -382,7 +370,7 @@ async function installFromRelease({ platform, releaseTag, cachePath, rootUrl })
382
370
  }
383
371
 
384
372
  const listing = runChecked('tar', ['-tzf', archivePath]).stdout.trim();
385
- if (listing !== PUBLIC_BINARY_NAME && listing !== LEGACY_BINARY_NAME) {
373
+ if (listing !== PUBLIC_BINARY_NAME) {
386
374
  fail(`release artifact ${artifact.archive} must contain exactly one top-level Starkscan binary`);
387
375
  }
388
376
 
@@ -427,23 +415,6 @@ export async function ensureStarkscanBinary(options = {}) {
427
415
  await validateExecutableFile(cachePath, 'cached Starkscan binary');
428
416
  return cachePath;
429
417
  }
430
- const legacyCachePath = path.join(cacheDir, LEGACY_BINARY_NAME);
431
- const legacyExisting = await lstat(legacyCachePath).catch(() => null);
432
- if (legacyExisting) {
433
- await validateExecutableFile(legacyCachePath, 'legacy cached Starkscan binary');
434
- await mkdir(cacheDir, { recursive: true });
435
- const stagePath = `${cachePath}.${process.pid}.${randomBytes(6).toString('hex')}.tmp`;
436
- try {
437
- await copyFile(legacyCachePath, stagePath);
438
- await chmod(stagePath, 0o755);
439
- await rename(stagePath, cachePath);
440
- } catch (error) {
441
- await rm(stagePath, { force: true }).catch(() => {});
442
- throw error;
443
- }
444
- await validateExecutableFile(cachePath, 'cached Starkscan binary');
445
- return cachePath;
446
- }
447
418
  }
448
419
 
449
420
  const releaseRepo = cliEnv('RELEASE_REPO');
@@ -465,7 +436,3 @@ export async function ensureStarkscanBinary(options = {}) {
465
436
  }
466
437
  return installFromRelease({ platform, releaseTag, cachePath, rootUrl });
467
438
  }
468
-
469
- // Deprecated #1117/#1456 compatibility alias. New package consumers should use
470
- // ensureStarkscanBinary so the public API is Starkscan-named.
471
- export const ensureMezcalBinary = ensureStarkscanBinary;
@@ -15,7 +15,6 @@ const SUPPORTED_PLATFORMS = [
15
15
  'linux-x86_64',
16
16
  ];
17
17
  const PUBLIC_MANIFEST_FILENAME = 'starkscan-cli-manifest.json';
18
- const LEGACY_MANIFEST_FILENAME = 'mezcal-cli-manifest.json';
19
18
 
20
19
  function env(name) {
21
20
  const value = process.env[name]?.trim();
@@ -68,19 +67,8 @@ async function main() {
68
67
  `Expected bundled artifacts under ${releaseRoot}. ` +
69
68
  'Run native CLI packaging for every supported platform, merge the manifest, then run ' +
70
69
  '`./webapp/packages/cli/scripts/package-starkscan-cli-npm.sh .artifacts/release/npm-cli` from the repository root.';
71
- let manifestPath;
72
- for (const manifestFilename of [PUBLIC_MANIFEST_FILENAME, LEGACY_MANIFEST_FILENAME]) {
73
- const candidate = path.join(releaseRoot, manifestFilename);
74
- const stat = await lstat(candidate).catch(() => null);
75
- if (stat?.isFile()) {
76
- manifestPath = candidate;
77
- break;
78
- }
79
- }
80
- if (!manifestPath) {
81
- manifestPath = path.join(releaseRoot, PUBLIC_MANIFEST_FILENAME);
82
- await assertFile(manifestPath, 'bundled manifest', remediation);
83
- }
70
+ const manifestPath = path.join(releaseRoot, PUBLIC_MANIFEST_FILENAME);
71
+ await assertFile(manifestPath, 'bundled manifest', remediation);
84
72
 
85
73
  const manifest = JSON.parse(await readFile(manifestPath, 'utf8'));
86
74
  if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) {
@@ -91,7 +79,7 @@ async function main() {
91
79
  }
92
80
 
93
81
  for (const platform of SUPPORTED_PLATFORMS) {
94
- const acceptedArchives = [`starkscan-${platform}.tar.gz`, `mezcal-${platform}.tar.gz`];
82
+ const expectedArchive = `starkscan-${platform}.tar.gz`;
95
83
  const matches = manifest.artifacts.filter((artifact) => artifact?.platform === platform);
96
84
  if (matches.length !== 1) {
97
85
  fail(`manifest must contain exactly one artifact for ${platform}; found ${matches.length}`);
@@ -101,8 +89,8 @@ async function main() {
101
89
  if (!archiveName) {
102
90
  fail(`artifact for ${platform} must define archive or name`);
103
91
  }
104
- if (!acceptedArchives.includes(archiveName)) {
105
- fail(`artifact for ${platform} must be named one of ${acceptedArchives.join(', ')}`);
92
+ if (archiveName !== expectedArchive) {
93
+ fail(`artifact for ${platform} must be named ${expectedArchive}`);
106
94
  }
107
95
  if (artifact.archive !== undefined && artifact.name !== undefined && artifact.archive !== artifact.name) {
108
96
  fail(`artifact archive and name for ${platform} must match`);
@@ -1 +0,0 @@
1
- ab12b551feb00ea3680b098dae25345f96fb22a1715c7f576488fd02ee6120e7 starkscan-darwin-aarch64.tar.gz
@@ -1 +0,0 @@
1
- d2eb41a1a8c70cfe2ba064fcc018b4c2c34ea7b1d2fc2f61a004ed365d8a43d6 starkscan-darwin-x86_64.tar.gz
@@ -1 +0,0 @@
1
- 18e93c6e3ccbce6d9084607f8f86c729b8cb6a67a65d05e566be8f8ad066e250 starkscan-linux-aarch64.tar.gz
@@ -1 +0,0 @@
1
- 1a97868b0096dc491c0b6b2f7b41e5056d9581c4117010f25ae769ee9e14bd03 starkscan-linux-x86_64.tar.gz