obsidian-launcher 1.3.3 → 2.0.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/dist/index.d.ts CHANGED
@@ -2,18 +2,39 @@ import child_process from 'child_process';
2
2
 
3
3
  /**
4
4
  * Type of the obsidian-versions.json file.
5
+ * @category Types
5
6
  */
6
- type ObsidianVersionInfos = {
7
+ type ObsidianVersionList = {
7
8
  metadata: {
9
+ schemaVersion: string;
8
10
  commitDate: string;
9
11
  commitSha: string;
10
12
  timestamp: string;
11
13
  };
12
14
  versions: ObsidianVersionInfo[];
13
15
  };
16
+ /**
17
+ * Metadata about a specific Obsidian desktop installer.
18
+ * @category Types
19
+ */
20
+ type ObsidianInstallerInfo = {
21
+ /**
22
+ * Hash of the file content.
23
+ * For releases from before GitHub started storing digests, this will be set to file "id" which also changes if the
24
+ * file is updated.
25
+ */
26
+ digest: string;
27
+ /** Electron version */
28
+ electron: string;
29
+ /** Chrome version */
30
+ chrome: string;
31
+ /** platform-arch combinations supported by the installer */
32
+ platforms: string[];
33
+ };
14
34
  /**
15
35
  * Metadata about a specific Obsidian version, including the min/max compatible installer versions, download urls, and
16
- * the internal electron version.
36
+ * the internal Electron version.
37
+ * @category Types
17
38
  */
18
39
  type ObsidianVersionInfo = {
19
40
  version: string;
@@ -25,16 +46,28 @@ type ObsidianVersionInfo = {
25
46
  asar?: string;
26
47
  appImage?: string;
27
48
  appImageArm?: string;
28
- apk?: string;
49
+ tar?: string;
50
+ tarArm?: string;
29
51
  dmg?: string;
30
52
  exe?: string;
53
+ apk?: string;
54
+ };
55
+ installers: {
56
+ appImage?: ObsidianInstallerInfo;
57
+ appImageArm?: ObsidianInstallerInfo;
58
+ tar?: ObsidianInstallerInfo;
59
+ tarArm?: ObsidianInstallerInfo;
60
+ dmg?: ObsidianInstallerInfo;
61
+ exe?: ObsidianInstallerInfo;
31
62
  };
63
+ /** @deprecated Use installers instead */
32
64
  electronVersion?: string;
65
+ /** @deprecated Use installers instead */
33
66
  chromeVersion?: string;
34
- nodeVersion?: string;
35
67
  };
36
68
  /**
37
69
  * Schema of entries in https://github.com/obsidianmd/obsidian-releases/blob/HEAD/community-plugins.json
70
+ * @category Types
38
71
  */
39
72
  type ObsidianCommunityPlugin = {
40
73
  id: string;
@@ -45,6 +78,7 @@ type ObsidianCommunityPlugin = {
45
78
  };
46
79
  /**
47
80
  * Schema of entries in https://github.com/obsidianmd/obsidian-releases/blob/HEAD/community-css-themes.json
81
+ * @category Types
48
82
  */
49
83
  type ObsidianCommunityTheme = {
50
84
  name: string;
@@ -54,29 +88,29 @@ type ObsidianCommunityTheme = {
54
88
  modes: string[];
55
89
  };
56
90
  /** @inline */
57
- type BasePluginEntry = {
91
+ interface BasePluginEntry {
58
92
  /** Set false to install the plugin but start it disabled. Default true. */
59
93
  enabled?: boolean;
60
- };
94
+ }
61
95
  /** @inline */
62
- type LocalPluginEntry = BasePluginEntry & {
96
+ interface LocalPluginEntry extends BasePluginEntry {
63
97
  /** Path on disk to the plugin to install. */
64
98
  path: string;
65
- };
99
+ }
66
100
  /** @inline */
67
- type GitHubPluginEntry = BasePluginEntry & {
101
+ interface GitHubPluginEntry extends BasePluginEntry {
68
102
  /** Github repo of the plugin to install, e.g. "some-user/some-plugin". */
69
103
  repo: string;
70
104
  /** Version of the plugin to install. Defaults to latest. */
71
105
  version?: string;
72
- };
106
+ }
73
107
  /** @inline */
74
- type CommunityPluginEntry = BasePluginEntry & {
108
+ interface CommunityPluginEntry extends BasePluginEntry {
75
109
  /** Plugin ID to install from Obsidian community plugins. */
76
110
  id: string;
77
111
  /** Version of the plugin to install. Defaults to latest. */
78
112
  version?: string;
79
- };
113
+ }
80
114
  /**
81
115
  * A plugin to install. Can be a simple string path to the local plugin to install, or an object.
82
116
  * If an object set one of:
@@ -85,8 +119,14 @@ type CommunityPluginEntry = BasePluginEntry & {
85
119
  * - `id` to install a community plugin
86
120
  *
87
121
  * You can also pass `enabled: false` to install the plugin, but start it disabled by default.
122
+ *
123
+ * @category Types
88
124
  */
89
125
  type PluginEntry = string | LocalPluginEntry | GitHubPluginEntry | CommunityPluginEntry;
126
+ /**
127
+ * PluginEntry plus downloaded path.
128
+ * @category Types
129
+ */
90
130
  type DownloadedPluginEntry = {
91
131
  /** If the plugin is enabled */
92
132
  enabled: boolean;
@@ -98,28 +138,28 @@ type DownloadedPluginEntry = {
98
138
  originalType: "local" | "github" | "community";
99
139
  };
100
140
  /** @inline */
101
- type BaseThemeEntry = {
141
+ interface BaseThemeEntry {
102
142
  /**
103
143
  * Set false to install the theme but not enable it. Defaults to true.
104
144
  * Only one theme can be enabled.
105
145
  */
106
146
  enabled?: boolean;
107
- };
147
+ }
108
148
  /** @inline */
109
- type LocalThemeEntry = BaseThemeEntry & {
149
+ interface LocalThemeEntry extends BaseThemeEntry {
110
150
  /** Path on disk to the theme to install. */
111
151
  path: string;
112
- };
152
+ }
113
153
  /** @inline */
114
- type GitHubThemeEntry = BaseThemeEntry & {
154
+ interface GitHubThemeEntry extends BaseThemeEntry {
115
155
  /** Github repo of the theme to install, e.g. "some-user/some-theme". */
116
156
  repo: string;
117
- };
157
+ }
118
158
  /** @inline */
119
- type CommunityThemeEntry = BaseThemeEntry & {
159
+ interface CommunityThemeEntry extends BaseThemeEntry {
120
160
  /** Theme name to install from Obsidian community themes. */
121
161
  name: string;
122
- };
162
+ }
123
163
  /**
124
164
  * A theme to install. Can be a simple string path to the local theme to install, or an object.
125
165
  * If an object, set one of:
@@ -129,8 +169,14 @@ type CommunityThemeEntry = BaseThemeEntry & {
129
169
  *
130
170
  * You can also pass `enabled: false` to install the theme, but start it disabled by default. You can only have one
131
171
  * enabled theme, so if you pass multiple you need to disable all but one.
172
+ *
173
+ * @category Types
132
174
  */
133
175
  type ThemeEntry = string | LocalThemeEntry | GitHubThemeEntry | CommunityThemeEntry;
176
+ /**
177
+ * ThemeEntry plus downloaded path.
178
+ * @category Types
179
+ */
134
180
  type DownloadedThemeEntry = {
135
181
  /** If the theme is enabled */
136
182
  enabled: boolean;
@@ -156,20 +202,24 @@ declare class ObsidianLauncher {
156
202
  readonly cacheDuration: number;
157
203
  /** Cached metadata files and requests */
158
204
  private metadataCache;
205
+ readonly interactive: boolean;
206
+ private obsidianApiToken;
159
207
  /**
160
208
  * Construct an ObsidianLauncher.
161
- * @param options.cacheDir Path to the cache directory. Defaults to "OBSIDIAN_CACHE" env var or ".obsidian-cache".
162
- * @param options.versionsUrl Custom `obsidian-versions.json` url. Can be a file URL.
163
- * @param options.communityPluginsUrl Custom `community-plugins.json` url. Can be a file URL.
164
- * @param options.communityThemesUrl Custom `community-css-themes.json` url. Can be a file URL.
165
- * @param options.cacheDuration If the cached version list is older than this (in ms), refetch it. Defaults to 30 minutes.
209
+ * @param opts.cacheDir Path to the cache directory. Defaults to "OBSIDIAN_CACHE" env var or ".obsidian-cache".
210
+ * @param opts.versionsUrl Custom `obsidian-versions.json` url. Can be a file URL.
211
+ * @param opts.communityPluginsUrl Custom `community-plugins.json` url. Can be a file URL.
212
+ * @param opts.communityThemesUrl Custom `community-css-themes.json` url. Can be a file URL.
213
+ * @param opts.cacheDuration If the cached version list is older than this (in ms), refetch it. Defaults to 30 minutes.
214
+ * @param opts.interactive If it can prompt the user for input (e.g. for Obsidian credentials). Default false.
166
215
  */
167
- constructor(options?: {
216
+ constructor(opts?: {
168
217
  cacheDir?: string;
169
218
  versionsUrl?: string;
170
219
  communityPluginsUrl?: string;
171
220
  communityThemesUrl?: string;
172
221
  cacheDuration?: number;
222
+ interactive?: boolean;
173
223
  });
174
224
  /**
175
225
  * Returns file content fetched from url as JSON. Caches content to dest and uses that cache if its more recent than
@@ -194,11 +244,11 @@ declare class ObsidianLauncher {
194
244
  getCommunityThemes(): Promise<ObsidianCommunityTheme[]>;
195
245
  /**
196
246
  * Resolves Obsidian app and installer version strings to absolute versions.
197
- * @param appVersion Obsidian version string or one of
247
+ * @param appVersion specific version or one of
198
248
  * - "latest": Get the current latest non-beta Obsidian version
199
249
  * - "latest-beta": Get the current latest beta Obsidian version (or latest is there is no current beta)
200
250
  * - "earliest": Get the `minAppVersion` set in your `manifest.json`
201
- * @param installerVersion Obsidian version string or one of
251
+ * @param installerVersion specific version or one of
202
252
  * - "latest": Get the latest Obsidian installer compatible with `appVersion`
203
253
  * - "earliest": Get the oldest Obsidian installer compatible with `appVersion`
204
254
  *
@@ -206,27 +256,59 @@ declare class ObsidianLauncher {
206
256
  *
207
257
  * @returns [appVersion, installerVersion] with any "latest" etc. resolved to specific versions.
208
258
  */
209
- resolveVersions(appVersion: string, installerVersion?: string): Promise<[string, string]>;
259
+ resolveVersion(appVersion: string, installerVersion?: string): Promise<[string, string]>;
210
260
  /**
211
261
  * Gets details about an Obsidian version.
212
262
  * @param appVersion Obsidian app version
213
263
  */
214
264
  getVersionInfo(appVersion: string): Promise<ObsidianVersionInfo>;
215
265
  /**
216
- * Downloads the Obsidian installer for the given version and current platform. Returns the file path.
217
- * @param installerVersion Obsidian installer version to download
266
+ * Parses a string of Obsidian versions into [appVersion, installerVersion] tuples.
267
+ *
268
+ * `versions` should be a space separated list of Obsidian app versions. You can optionally specify the installer
269
+ * version by using "appVersion/installerVersion" e.g. `"1.7.7/1.8.10"`.
270
+ *
271
+ * Example:
272
+ * ```js
273
+ * launcher.parseVersions("1.8.10/1.7.7 latest latest-beta/earliest")
274
+ * ```
275
+ *
276
+ * See also: [Obsidian App vs Installer Versions](../README.md#obsidian-app-vs-installer-versions)
277
+ *
278
+ * @param versions string to parse
279
+ * @returns [appVersion, installerVersion][] resolved to specific versions.
218
280
  */
219
- downloadInstaller(installerVersion: string): Promise<string>;
281
+ parseVersions(versions: string): Promise<[string, string][]>;
282
+ private getInstallerKey;
220
283
  /**
221
- * Helper for downloadInstaller that doesn't require the obsidian-versions.json file so it can be used in
222
- * updateObsidianVersionInfos
284
+ * Gets details about the Obsidian installer for the given platform.
285
+ * @param installerVersion Obsidian installer version
286
+ * @param opts.platform Platform/os (defaults to host platform)
287
+ * @param opts.arch Architecture (defaults to host architecture)
288
+ */
289
+ getInstallerInfo(installerVersion: string, opts?: {
290
+ platform?: NodeJS.Platform;
291
+ arch?: NodeJS.Architecture;
292
+ }): Promise<ObsidianInstallerInfo & {
293
+ url: string;
294
+ }>;
295
+ /**
296
+ * Downloads the Obsidian installer for the given version and platform/arch (defaults to host platform/arch).
297
+ * Returns the file path.
298
+ * @param installerVersion Obsidian installer version to download
299
+ * @param opts.platform Platform/os of the installer to download (defaults to host platform)
300
+ * @param opts.arch Architecture of the installer to download (defaults to host architecture)
223
301
  */
224
- private downloadInstallerFromVersionInfo;
302
+ downloadInstaller(installerVersion: string, opts?: {
303
+ platform?: NodeJS.Platform;
304
+ arch?: NodeJS.Architecture;
305
+ }): Promise<string>;
225
306
  /**
226
307
  * Downloads the Obsidian asar for the given version. Returns the file path.
227
308
  *
228
- * To download beta versions you'll need to have an Obsidian account with Catalyst and set the `OBSIDIAN_USERNAME`
229
- * and `OBSIDIAN_PASSWORD` environment variables. 2FA needs to be disabled.
309
+ * To download Obsidian beta versions you'll need have an Obsidian Insiders account and either set the
310
+ * `OBSIDIAN_EMAIL` and `OBSIDIAN_PASSWORD` env vars (`.env` is supported) or pre-download the Obsidian beta with
311
+ * `npx obsidian-launcher download -v latest-beta`
230
312
  *
231
313
  * @param appVersion Obsidian version to download
232
314
  */
@@ -242,7 +324,14 @@ declare class ObsidianLauncher {
242
324
  *
243
325
  * @param installerVersion Obsidian installer version
244
326
  */
245
- downloadChromedriver(installerVersion: string): Promise<string>;
327
+ downloadChromedriver(installerVersion: string, opts?: {
328
+ platform?: NodeJS.Platform;
329
+ arch?: NodeJS.Architecture;
330
+ }): Promise<string>;
331
+ /**
332
+ * Downloads the Obsidian apk.
333
+ */
334
+ downloadAndroid(version: string): Promise<string>;
246
335
  /** Gets the latest version of a plugin. */
247
336
  private getLatestPluginVersion;
248
337
  /**
@@ -260,8 +349,8 @@ declare class ObsidianLauncher {
260
349
  */
261
350
  private downloadCommunityPlugin;
262
351
  /**
263
- * Downloads a list of plugins to the cache and returns a list of `DownloadedPluginEntry` with the downloaded paths.
264
- * Also adds the `id` property to the plugins based on the manifest.
352
+ * Downloads a list of plugins to the cache and returns a list of {@link DownloadedPluginEntry} with the downloaded
353
+ * paths. Also adds the `id` property to the plugins based on the manifest.
265
354
  *
266
355
  * You can download plugins from GitHub using `{repo: "org/repo"}` and community plugins using `{id: 'plugin-id'}`.
267
356
  * Local plugins will just be passed through.
@@ -284,8 +373,8 @@ declare class ObsidianLauncher {
284
373
  */
285
374
  private downloadCommunityTheme;
286
375
  /**
287
- * Downloads a list of themes to the cache and returns a list of `DownloadedThemeEntry` with the downloaded paths.
288
- * Also adds the `name` property to the plugins based on the manifest.
376
+ * Downloads a list of themes to the cache and returns a list of {@link DownloadedThemeEntry} with the downloaded
377
+ * paths. Also adds the `name` property to the plugins based on the manifest.
289
378
  *
290
379
  * You can download themes from GitHub using `{repo: "org/repo"}` and community themes using `{name: 'theme-name'}`.
291
380
  * Local themes will just be passed through.
@@ -311,15 +400,17 @@ declare class ObsidianLauncher {
311
400
  * @param params.appVersion Obsidian app version
312
401
  * @param params.installerVersion Obsidian version string.
313
402
  * @param params.appPath Path to the asar file to install. Will download if omitted.
314
- * @param params.vault Path to the vault to open in Obsidian.
315
- * @param params.dest Destination path for the config dir. If omitted it will create a temporary directory.
403
+ * @param params.vault Path to the vault to open in Obsidian
404
+ * @param params.localStorage items to add to localStorage. `$vaultId` in the keys will be replaced with the vaultId
405
+ * @param params.chromePreferences Chrome preferences to add to the Preferences file
316
406
  */
317
407
  setupConfigDir(params: {
318
408
  appVersion: string;
319
409
  installerVersion: string;
320
410
  appPath?: string;
321
411
  vault?: string;
322
- dest?: string;
412
+ localStorage?: Record<string, string>;
413
+ chromePreferences?: Record<string, any>;
323
414
  }): Promise<string>;
324
415
  /**
325
416
  * Sets up a vault for Obsidian, installing plugins and themes and optionally copying the vault to a temporary
@@ -340,8 +431,6 @@ declare class ObsidianLauncher {
340
431
  * Downloads and launches Obsidian with a sandboxed config dir and a specifc vault open. Optionally install plugins
341
432
  * and themes first.
342
433
  *
343
- * This is just a shortcut for calling `downloadApp`, `downloadInstaller`, `setupVault` and `setupConfDir`.
344
- *
345
434
  * @param params.appVersion Obsidian app version. Default "latest"
346
435
  * @param params.installerVersion Obsidian installer version. Default "latest"
347
436
  * @param params.vault Path to the vault to open in Obsidian
@@ -349,6 +438,7 @@ declare class ObsidianLauncher {
349
438
  * @param params.plugins List of plugins to install in the vault
350
439
  * @param params.themes List of themes to install in the vault
351
440
  * @param params.args CLI args to pass to Obsidian
441
+ * @param params.localStorage items to add to localStorage. `$vaultId` in the keys will be replaced with the vaultId
352
442
  * @param params.spawnOptions Options to pass to `spawn`
353
443
  * @returns The launched child process and the created tmpdirs
354
444
  */
@@ -360,6 +450,7 @@ declare class ObsidianLauncher {
360
450
  plugins?: PluginEntry[];
361
451
  themes?: ThemeEntry[];
362
452
  args?: string[];
453
+ localStorage?: Record<string, string>;
363
454
  spawnOptions?: child_process.SpawnOptions;
364
455
  }): Promise<{
365
456
  proc: child_process.ChildProcess;
@@ -367,13 +458,13 @@ declare class ObsidianLauncher {
367
458
  vault?: string;
368
459
  }>;
369
460
  /**
370
- * Updates the info obsidian-versions.json. The obsidian-versions.json file is used in other launcher commands
461
+ * Updates the info in obsidian-versions.json. The obsidian-versions.json file is used in other launcher commands
371
462
  * and in wdio-obsidian-service to get metadata about Obsidian versions in one place such as minInstallerVersion and
372
- * the internal electron version.
463
+ * the internal Electron version.
373
464
  */
374
- updateObsidianVersionInfos(original?: ObsidianVersionInfos, { maxInstances }?: {
375
- maxInstances?: number | undefined;
376
- }): Promise<ObsidianVersionInfos>;
465
+ updateVersionList(original?: ObsidianVersionList, opts?: {
466
+ maxInstances?: number;
467
+ }): Promise<ObsidianVersionList>;
377
468
  /**
378
469
  * Returns true if the Obsidian version is already in the cache.
379
470
  * @param type on of "app" or "installer"
@@ -393,4 +484,4 @@ declare class ObsidianLauncher {
393
484
  * @document ../README.md
394
485
  */
395
486
 
396
- export { type DownloadedPluginEntry, type DownloadedThemeEntry, type ObsidianCommunityPlugin, type ObsidianCommunityTheme, type ObsidianVersionInfo, type ObsidianVersionInfos, type PluginEntry, type ThemeEntry, ObsidianLauncher as default };
487
+ export { type DownloadedPluginEntry, type DownloadedThemeEntry, type ObsidianCommunityPlugin, type ObsidianCommunityTheme, type ObsidianInstallerInfo, type ObsidianVersionInfo, type ObsidianVersionList, type PluginEntry, type ThemeEntry, ObsidianLauncher as default };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ObsidianLauncher
3
- } from "./chunk-MZRDQQTK.js";
3
+ } from "./chunk-KPNJCYO4.js";
4
4
 
5
5
  // src/index.ts
6
6
  var index_default = ObsidianLauncher;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @module\n * @document ../README.md\n */\nimport { ObsidianLauncher } from \"./launcher.js\"\n\nexport default ObsidianLauncher;\nexport type {\n ObsidianVersionInfos, ObsidianVersionInfo, ObsidianCommunityPlugin, ObsidianCommunityTheme,\n PluginEntry, DownloadedPluginEntry, ThemeEntry, DownloadedThemeEntry,\n} from \"./types.js\";\n"],"mappings":";;;;;AAMA,IAAO,gBAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @module\n * @document ../README.md\n */\nimport { ObsidianLauncher } from \"./launcher.js\"\n\nexport default ObsidianLauncher;\nexport type {\n ObsidianVersionList, ObsidianVersionInfo, ObsidianInstallerInfo, ObsidianCommunityPlugin, ObsidianCommunityTheme,\n PluginEntry, DownloadedPluginEntry, ThemeEntry, DownloadedThemeEntry,\n} from \"./types.js\";\n"],"mappings":";;;;;AAMA,IAAO,gBAAQ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obsidian-launcher",
3
- "version": "1.3.3",
3
+ "version": "2.0.1",
4
4
  "description": "Download and launch sandboxed Obsidian instances",
5
5
  "keywords": [
6
6
  "obsidian"
@@ -27,7 +27,8 @@
27
27
  "scripts": {
28
28
  "build": "tsup",
29
29
  "test": "run-s test:*",
30
- "test:unit": "tsc --noEmit && mocha"
30
+ "test:unit": "tsc --noEmit && mocha --config .mocharc.unit.json",
31
+ "test:e2e": "tsc --noEmit && mocha --config .mocharc.e2e.json"
31
32
  },
32
33
  "repository": {
33
34
  "type": "git",
@@ -41,30 +42,38 @@
41
42
  },
42
43
  "homepage": "https://jesse-r-s-hines.github.io/wdio-obsidian-service/obsidian-launcher/README.html",
43
44
  "devDependencies": {
44
- "@types/chai": "^5.0.1",
45
+ "@types/chai": "^5.2.2",
45
46
  "@types/chrome-remote-interface": "^0.31.14",
46
- "@types/lodash": "^4.17.14",
47
+ "@types/cross-spawn": "^6.0.6",
48
+ "@types/lodash": "^4.17.20",
47
49
  "@types/mocha": "^10.0.10",
48
- "@types/node": "^18.11.9",
49
- "@types/semver": "^7.5.8",
50
- "chai": "^5.1.2",
51
- "mocha": "^11.0.1",
50
+ "@types/node": "^18.19.121",
51
+ "@types/readline-sync": "^1.4.8",
52
+ "@types/semver": "^7.7.0",
53
+ "@types/serve-handler": "^6.1.4",
54
+ "chai": "^5.2.1",
55
+ "mocha": "^11.7.1",
52
56
  "npm-run-all": "^4.1.5",
57
+ "serve": "^14.2.4",
58
+ "serve-handler": "^6.1.6",
59
+ "ts-essentials": "^10.1.1",
53
60
  "ts-node": "^10.9.2",
54
- "tsup": "^8.3.5",
55
- "tsx": "^4.19.2",
56
- "typescript": "^5.8.2"
61
+ "tsup": "^8.5.0",
62
+ "tsx": "^4.20.3",
63
+ "typescript": "^5.8.3"
57
64
  },
58
65
  "dependencies": {
59
66
  "@electron/get": "^3.1.0",
60
67
  "@supercharge/promise-pool": "^3.2.0",
61
- "chrome-remote-interface": "^0.33.2",
62
- "classic-level": "^2.0.0",
63
- "commander": "^13.0.0",
68
+ "7z-wasm": "1.2.0",
69
+ "chrome-remote-interface": "^0.33.3",
70
+ "classic-level": "^3.0.0",
71
+ "commander": "^13.1.0",
72
+ "dotenv": "^17.2.1",
64
73
  "extract-zip": "^2.0.1",
65
74
  "lodash": "^4.17.21",
66
- "semver": "^7.6.3",
67
- "which": "^5.0.0"
75
+ "readline-sync": "^1.4.10",
76
+ "semver": "^7.7.2"
68
77
  },
69
78
  "engines": {
70
79
  "node": ">=18"