@myapihq/cli 1.0.73 → 1.0.74

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.
@@ -4,21 +4,44 @@ import { loadConfig } from '../config.js';
4
4
  import { info, success } from '../output.js';
5
5
  import { installSkills } from './setup.js';
6
6
  const REGISTRY_URL = 'https://registry.npmjs.org/@myapihq/cli/latest';
7
+ const PACKUMENT_URL = 'https://registry.npmjs.org/@myapihq/cli';
8
+ // Verify the version is listed in the full packument — the same data source
9
+ // `npm install` consults. The /latest endpoint and the tarball URL are on
10
+ // different CDN caches and can update before the packument does, causing
11
+ // `npm install` to fail with ETARGET. This check eliminates that race.
12
+ async function isVersionInstallable(version) {
13
+ try {
14
+ const res = await fetch(PACKUMENT_URL, {
15
+ headers: { Accept: 'application/vnd.npm.install-v1+json' },
16
+ signal: AbortSignal.timeout(5000),
17
+ });
18
+ if (!res.ok)
19
+ return false;
20
+ const data = await res.json();
21
+ return Boolean(data.versions && data.versions[version]);
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
7
27
  // Resolve the npm binary and global prefix to use for self-update.
8
28
  // We install to the same prefix where the current myapi binary lives,
9
29
  // so the update actually replaces the running binary.
30
+ // `--prefer-online` forces npm to revalidate its local packument cache
31
+ // against the registry — without it, a stale local cache can also produce
32
+ // ETARGET even when the registry itself has the version.
10
33
  function npmInstallArgs(version) {
11
34
  const npmCandidate = process.execPath.replace(/[/\\]node(\.exe)?$/, '/npm');
12
35
  const bin = existsSync(npmCandidate) ? npmCandidate : 'npm';
13
- // Find where the currently-running myapi binary is, derive its npm prefix.
36
+ const baseArgs = ['install', '-g', '--prefer-online', `@myapihq/cli@${version}`];
14
37
  try {
15
- const self = process.argv[1]; // e.g. /usr/local/bin/myapi or ~/.nvm/.../bin/myapi
16
- const binDir = self.replace(/[/\\][^/\\]+$/, ''); // strip the filename
17
- const prefix = binDir.replace(/[/\\]bin$/, ''); // strip /bin
18
- return { bin, args: ['install', '-g', '--prefix', prefix, `@myapihq/cli@${version}`] };
38
+ const self = process.argv[1];
39
+ const binDir = self.replace(/[/\\][^/\\]+$/, '');
40
+ const prefix = binDir.replace(/[/\\]bin$/, '');
41
+ return { bin, args: ['install', '-g', '--prefer-online', '--prefix', prefix, `@myapihq/cli@${version}`] };
19
42
  }
20
43
  catch {
21
- return { bin, args: ['install', '-g', `@myapihq/cli@${version}`] };
44
+ return { bin, args: baseArgs };
22
45
  }
23
46
  }
24
47
  // checkForUpdate runs silently in the background on every command.
@@ -31,17 +54,11 @@ export async function checkForUpdate(currentVersion) {
31
54
  const data = await res.json();
32
55
  const latest = data.version;
33
56
  if (latest && isNewer(latest, currentVersion)) {
34
- // Verify the tarball is actually available before attempting install —
35
- // the registry metadata can report a new version before the tarball is uploaded.
36
- const tarballUrl = `https://registry.npmjs.org/@myapihq/cli/-/cli-${latest}.tgz`;
37
- try {
38
- const check = await fetch(tarballUrl, { method: 'HEAD', signal: AbortSignal.timeout(3000) });
39
- if (!check.ok)
40
- return; // Tarball not ready yet — silently skip, retry next command.
41
- }
42
- catch {
57
+ // Verify the version is actually installable before attempting install —
58
+ // the /latest endpoint can report a new version before the packument
59
+ // (which `npm install` consults) has propagated through the CDN.
60
+ if (!(await isVersionInstallable(latest)))
43
61
  return;
44
- }
45
62
  info(`\n› New version available (${currentVersion} → ${latest}) — installing…`);
46
63
  try {
47
64
  const { bin, args } = npmInstallArgs(latest);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myapihq/cli",
3
- "version": "1.0.73",
3
+ "version": "1.0.74",
4
4
  "description": "MyAPI command-line interface",
5
5
  "type": "module",
6
6
  "files": [