@lpm-registry/cli 0.58.0 → 0.59.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.
Files changed (62) hide show
  1. package/README.md +21 -45
  2. package/bin/lpm.js +2 -354
  3. package/bin/lpx.js +4 -0
  4. package/bin/native.js +154 -0
  5. package/package.json +40 -82
  6. package/CHANGELOG.md +0 -197
  7. package/LICENSE +0 -15
  8. package/index.d.ts +0 -131
  9. package/index.js +0 -31
  10. package/lib/api.js +0 -398
  11. package/lib/commands/add.js +0 -1217
  12. package/lib/commands/audit.js +0 -283
  13. package/lib/commands/cache.js +0 -209
  14. package/lib/commands/check-name.js +0 -112
  15. package/lib/commands/config.js +0 -186
  16. package/lib/commands/doctor.js +0 -140
  17. package/lib/commands/info.js +0 -215
  18. package/lib/commands/init.js +0 -146
  19. package/lib/commands/install.js +0 -264
  20. package/lib/commands/login.js +0 -595
  21. package/lib/commands/logout.js +0 -94
  22. package/lib/commands/marketplace-compare.js +0 -164
  23. package/lib/commands/marketplace-earnings.js +0 -89
  24. package/lib/commands/mcp-setup.js +0 -363
  25. package/lib/commands/npmrc.js +0 -178
  26. package/lib/commands/open.js +0 -82
  27. package/lib/commands/outdated.js +0 -291
  28. package/lib/commands/pool-stats.js +0 -100
  29. package/lib/commands/publish.js +0 -949
  30. package/lib/commands/quality.js +0 -211
  31. package/lib/commands/remove.js +0 -82
  32. package/lib/commands/run.js +0 -14
  33. package/lib/commands/search.js +0 -143
  34. package/lib/commands/setup.js +0 -221
  35. package/lib/commands/skills.js +0 -898
  36. package/lib/commands/token-rotate.js +0 -25
  37. package/lib/commands/uninstall.js +0 -107
  38. package/lib/commands/whoami.js +0 -129
  39. package/lib/config.js +0 -328
  40. package/lib/constants.js +0 -190
  41. package/lib/ecosystem.js +0 -501
  42. package/lib/editor-skills.js +0 -321
  43. package/lib/editors.js +0 -215
  44. package/lib/import-rewriter.js +0 -364
  45. package/lib/install-targets/mcp-server.js +0 -245
  46. package/lib/install-targets/vscode-extension.js +0 -178
  47. package/lib/install-targets.js +0 -82
  48. package/lib/integrity.js +0 -179
  49. package/lib/lpm-config-prompts.js +0 -102
  50. package/lib/lpm-config.js +0 -408
  51. package/lib/oidc.js +0 -166
  52. package/lib/project-utils.js +0 -152
  53. package/lib/quality/checks.js +0 -687
  54. package/lib/quality/display.js +0 -155
  55. package/lib/quality/score.js +0 -118
  56. package/lib/quality/swift-checks.js +0 -447
  57. package/lib/safe-path.js +0 -180
  58. package/lib/secure-store.js +0 -321
  59. package/lib/swift-project.js +0 -637
  60. package/lib/ui.js +0 -40
  61. package/scripts/__tests__/install-binary.test.js +0 -346
  62. package/scripts/install-binary.js +0 -571
package/README.md CHANGED
@@ -1,64 +1,40 @@
1
- # LPM — The Package Manager for Modern Software
1
+ # LPM CLI
2
2
 
3
- Fast, secure, all-in-one. Written in Rust.
3
+ Fast, secure, all-in-one package manager written in Rust.
4
4
 
5
5
  ```bash
6
6
  npm install -g @lpm-registry/cli
7
7
  ```
8
8
 
9
- <details>
10
- <summary>Other install methods</summary>
9
+ This package is the npm gateway for the native LPM CLI. It installs a small
10
+ JavaScript launcher plus the matching platform package, such as
11
+ `@lpm-registry/cli-darwin-arm64` or `@lpm-registry/cli-linux-x64`.
11
12
 
12
- ```bash
13
- brew tap lpm-dev/lpm && brew install lpm # Homebrew
14
- curl -fsSL https://lpm.dev/install.sh | sh # Standalone
15
- cargo install --git https://github.com/lpm-dev/rust-client lpm-cli # Source
16
- ```
17
-
18
- </details>
13
+ The JavaScript launcher does not implement package-manager behavior. All CLI
14
+ commands run in the native Rust binary.
19
15
 
20
- ## About This Package
16
+ Source for this npm package lives in `lpm-dev/rust-client/npm/cli`.
21
17
 
22
- This npm package is a thin wrapper that downloads the native Rust binary on `postinstall`. All CLI functionality is provided by the Rust client — see [lpm-dev/rust-client](https://github.com/lpm-dev/rust-client) for full documentation, benchmarks, and the complete command reference.
23
-
24
- If the native binary isn't available for your platform, the JS fallback CLI activates automatically.
25
-
26
- ## Quick Start
18
+ ## Updating
27
19
 
28
20
  ```bash
29
- lpm login # Authenticate
30
- lpm install # Install deps (aliases: i)
31
- lpm publish # Publish to lpm.dev (aliases: p)
32
- lpm dev # Zero-config dev server + HTTPS + tunnel
21
+ lpm self-update
33
22
  ```
34
23
 
35
- ## Commands
24
+ When LPM was installed through npm, self-update runs:
36
25
 
37
- See the full command reference at [github.com/lpm-dev/rust-client](https://github.com/lpm-dev/rust-client#commands).
26
+ ```bash
27
+ npm install -g @lpm-registry/cli@<version>
28
+ ```
38
29
 
39
- ## API Exports
30
+ ## Troubleshooting
40
31
 
41
- This package exports utilities for programmatic use:
32
+ If your package manager was configured to omit optional dependencies, reinstall
33
+ with optional dependencies enabled:
42
34
 
43
- ```js
44
- import {
45
- generateIntegrity,
46
- verifyIntegrity,
47
- runQualityChecks,
48
- parseLpmPackageReference,
49
- detectFramework,
50
- } from "@lpm-registry/cli";
35
+ ```bash
36
+ npm install -g @lpm-registry/cli
51
37
  ```
52
38
 
53
- | Function | Description |
54
- | --- | --- |
55
- | `generateIntegrity(buffer, algorithm?)` | Generate an SRI integrity hash (default: `sha512`) |
56
- | `verifyIntegrity(buffer, expected)` | Verify a buffer against an SRI integrity string |
57
- | `runQualityChecks({ packageJson, readme, ... })` | Run all 28 quality checks and return score, tier, and checks |
58
- | `parseLpmPackageReference(ref)` | Parse `@lpm.dev/owner.pkg@version?key=val` into components |
59
- | `readLpmConfig(dir)` | Read and validate `lpm.config.json` from a directory |
60
- | `detectFramework()` | Detect the project framework (nextjs, vite, remix, astro) |
61
-
62
- ## License
63
-
64
- MIT
39
+ Other install methods are documented at
40
+ [github.com/lpm-dev/rust-client](https://github.com/lpm-dev/rust-client).
package/bin/lpm.js CHANGED
@@ -1,356 +1,4 @@
1
1
  #!/usr/bin/env node
2
+ import { runNativeCommand } from "./native.js";
2
3
 
3
- /**
4
- * LPM CLI Entry Point — Minimal fallback wrapper.
5
- *
6
- * In most cases, this file has been replaced by a hard link to the native
7
- * Rust binary during postinstall (zero Node.js overhead). This JS wrapper
8
- * only runs when:
9
- *
10
- * 1. Hard-link failed (cross-device mount, permissions)
11
- * 2. npm rebuild recreated the symlink
12
- * 3. Binary download failed during postinstall
13
- *
14
- * Resolution order:
15
- * 1. Try platform package binary (optionalDependencies)
16
- * 2. Try lpm-bin in bin/ directory (GitHub Releases download)
17
- * 3. Fall through to JS CLI implementation
18
- */
19
-
20
- import { execFileSync } from "node:child_process";
21
- import fs from "node:fs";
22
- import { createRequire } from "node:module";
23
- import os from "node:os";
24
- import path from "node:path";
25
- import { fileURLToPath } from "node:url";
26
-
27
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
- const require = createRequire(import.meta.url);
29
-
30
- // ─── Try native binary (Tier 1: platform package) ──────────────────
31
-
32
- const PLATFORMS = {
33
- "darwin-arm64": { pkg: "@lpm-registry/cli-darwin-arm64", binary: "lpm" },
34
- "darwin-x64": { pkg: "@lpm-registry/cli-darwin-x64", binary: "lpm" },
35
- "linux-x64": { pkg: "@lpm-registry/cli-linux-x64", binary: "lpm" },
36
- "linux-arm64": { pkg: "@lpm-registry/cli-linux-arm64", binary: "lpm" },
37
- "win32-x64": { pkg: "@lpm-registry/cli-win32-x64", binary: "lpm.exe" },
38
- };
39
-
40
- // Allow override via environment variable (for debugging / custom builds)
41
- const envBinary = process.env.LPM_BINARY_PATH;
42
- if (envBinary && fs.existsSync(envBinary)) {
43
- runBinary(envBinary);
44
- }
45
-
46
- // Try platform package from optionalDependencies
47
- const platform = `${process.platform}-${os.arch()}`;
48
- const platformInfo = PLATFORMS[platform];
49
-
50
- if (platformInfo) {
51
- try {
52
- const pkgJsonPath = require.resolve(`${platformInfo.pkg}/package.json`);
53
- const binaryPath = path.join(
54
- path.dirname(pkgJsonPath),
55
- platformInfo.binary,
56
- );
57
- if (fs.existsSync(binaryPath)) {
58
- runBinary(binaryPath);
59
- }
60
- } catch {
61
- // Package not installed
62
- }
63
- }
64
-
65
- // ─── Try native binary (Tier 2: downloaded by postinstall) ─────────
66
-
67
- const legacyBinaryName =
68
- process.platform === "win32" ? "lpm-bin.exe" : "lpm-bin";
69
- const legacyBinaryPath = path.join(__dirname, legacyBinaryName);
70
-
71
- if (fs.existsSync(legacyBinaryPath)) {
72
- runBinary(legacyBinaryPath);
73
- }
74
-
75
- // ─── JS CLI fallback (Tier 3) ──────────────────────────────────────
76
-
77
- import { Command } from "commander";
78
- import updateNotifier from "update-notifier";
79
- import { add } from "../lib/commands/add.js";
80
- import { audit } from "../lib/commands/audit.js";
81
- import { cache } from "../lib/commands/cache.js";
82
- import { checkName } from "../lib/commands/check-name.js";
83
- import { config } from "../lib/commands/config.js";
84
- import { doctor } from "../lib/commands/doctor.js";
85
- import { info } from "../lib/commands/info.js";
86
- import { init } from "../lib/commands/init.js";
87
- import { install } from "../lib/commands/install.js";
88
- import { login } from "../lib/commands/login.js";
89
- import { logout } from "../lib/commands/logout.js";
90
- import { marketplaceCompare } from "../lib/commands/marketplace-compare.js";
91
- import { marketplaceEarnings } from "../lib/commands/marketplace-earnings.js";
92
- import { mcpRemove, mcpSetup, mcpStatus } from "../lib/commands/mcp-setup.js";
93
- import { npmrc } from "../lib/commands/npmrc.js";
94
- import { openDashboard } from "../lib/commands/open.js";
95
- import { outdated } from "../lib/commands/outdated.js";
96
- import { poolStats } from "../lib/commands/pool-stats.js";
97
- import { publish } from "../lib/commands/publish.js";
98
- import { quality } from "../lib/commands/quality.js";
99
- import { remove } from "../lib/commands/remove.js";
100
- import { run } from "../lib/commands/run.js";
101
- import { search } from "../lib/commands/search.js";
102
- import { setup } from "../lib/commands/setup.js";
103
- import {
104
- skillsClean,
105
- skillsInstall,
106
- skillsList,
107
- skillsValidate,
108
- } from "../lib/commands/skills.js";
109
- import { rotateToken } from "../lib/commands/token-rotate.js";
110
- import { uninstall } from "../lib/commands/uninstall.js";
111
- import { whoami } from "../lib/commands/whoami.js";
112
-
113
- // Load package.json
114
- const pkg = JSON.parse(
115
- fs.readFileSync(path.join(__dirname, "../package.json"), "utf-8"),
116
- );
117
-
118
- // Check for updates
119
- updateNotifier({ pkg }).notify();
120
-
121
- const program = new Command();
122
-
123
- program
124
- .name("lpm")
125
- .description("CLI for Licensed Package Manager")
126
- .version(pkg.version);
127
-
128
- // Authentication
129
- program
130
- .command("login")
131
- .alias("l")
132
- .description("Authenticate with the registry")
133
- .action(login);
134
- program
135
- .command("logout")
136
- .alias("lo")
137
- .description("Clear stored authentication token")
138
- .option("--revoke", "Also revoke the token on the server")
139
- .option("--clear-cache", "Clear local package cache")
140
- .action(logout);
141
- program
142
- .command("whoami")
143
- .description("Check current authenticated user")
144
- .option("--json", "Output in JSON format")
145
- .action(whoami);
146
-
147
- // Package Management
148
- program
149
- .command("init")
150
- .description("Interactively create a package.json for LPM")
151
- .action(init);
152
- program
153
- .command("install [packages...]")
154
- .alias("i")
155
- .description("Install packages")
156
- .option("--json", "Machine-readable JSON output")
157
- .option("--no-skills", "Skip fetching Agent Skills")
158
- .option("--pm <manager>", "Package manager to use")
159
- .action(install);
160
- program
161
- .command("uninstall <packages...>")
162
- .aliases(["un", "unlink"])
163
- .description("Uninstall packages")
164
- .option("--pm <manager>", "Package manager to use")
165
- .action(uninstall);
166
- program
167
- .command("publish")
168
- .alias("p")
169
- .description("Publish a package to the registry")
170
- .option("--check", "Quality check only")
171
- .option("--min-score <score>", "Minimum quality score")
172
- .option("--provenance", "Force OIDC provenance")
173
- .option("--dry-run", "Preview without publishing")
174
- .action(publish);
175
- program
176
- .command("add <package>")
177
- .description("Extract package source code")
178
- .option("-p, --path <path>", "Target directory")
179
- .option("-f, --force", "Overwrite existing files")
180
- .option("-y, --yes", "Accept defaults")
181
- .option("--alias <alias>", "Import alias prefix")
182
- .option("--target <name>", "Swift SPM target")
183
- .option("--json", "JSON output")
184
- .option("--dry-run", "Preview only")
185
- .action(add);
186
- program
187
- .command("remove <package>")
188
- .alias("rm")
189
- .description("Remove a previously added package")
190
- .action(remove);
191
-
192
- // Discovery
193
- program
194
- .command("search <query>")
195
- .description("Search packages")
196
- .option("--limit <n>", "Max results", "20")
197
- .option("--json", "JSON output")
198
- .action((q, o) => search(q, { ...o, limit: parseInt(o.limit, 10) }));
199
- program
200
- .command("info <package>")
201
- .description("Package info")
202
- .option("--json", "JSON output")
203
- .option("-a, --all-versions", "Show all versions")
204
- .action(info);
205
- program
206
- .command("check-name <name>")
207
- .description("Check name availability")
208
- .option("--json", "JSON output")
209
- .action(checkName);
210
- program
211
- .command("quality <package>")
212
- .description("Quality report")
213
- .option("--json", "JSON output")
214
- .action(quality);
215
-
216
- // Maintenance
217
- program
218
- .command("audit [action]")
219
- .description("Security audit")
220
- .option("--json", "JSON output")
221
- .option("--level <level>", "Minimum severity")
222
- .action(audit);
223
- program
224
- .command("outdated")
225
- .description("Check outdated deps")
226
- .option("--json", "JSON output")
227
- .option("--all", "Show all deps")
228
- .action(outdated);
229
- program.command("doctor").description("Health check").action(doctor);
230
-
231
- // Configuration
232
- const setupCommand = program
233
- .command("setup")
234
- .description("Configure .npmrc for CI or local development")
235
- .action(() => setupCommand.help());
236
- setupCommand
237
- .command("ci")
238
- .description("Generate .npmrc for CI/CD")
239
- .option("-r, --registry <url>", "Custom registry URL")
240
- .option("--oidc", "Exchange OIDC token")
241
- .option("--proxy", "Route all npm traffic through lpm.dev")
242
- .option("--scoped", "Scoped registry only")
243
- .action(setup);
244
- setupCommand
245
- .command("local")
246
- .description("Generate read-only .npmrc token for local development")
247
- .option("-d, --days <number>", "Token expiry days")
248
- .option("--proxy", "Route all npm traffic through lpm.dev")
249
- .option("--scoped", "Scoped registry only")
250
- .action(npmrc);
251
- program
252
- .command("config [action] [key] [value]")
253
- .description("Manage CLI config")
254
- .action(config);
255
- program
256
- .command("set <key> <value>")
257
- .description('Shortcut for "lpm config set"')
258
- .action((k, v) => config("set", k, v));
259
- program
260
- .command("cache <action>")
261
- .description("Manage local cache")
262
- .action(cache);
263
-
264
- // Utility
265
- program
266
- .command("open")
267
- .description("Open dashboard in browser")
268
- .action(openDashboard);
269
- program
270
- .command("run <script>")
271
- .description("Run npm scripts")
272
- .allowUnknownOption()
273
- .action(run);
274
-
275
- // Subcommands
276
- const token = program.command("token").description("Token management");
277
- token.command("rotate").description("Rotate token").action(rotateToken);
278
-
279
- const pool = program.command("pool").description("Pool revenue");
280
- pool
281
- .command("stats")
282
- .description("Pool earnings")
283
- .option("--json", "JSON output")
284
- .action(poolStats);
285
-
286
- const mcp = program.command("mcp").description("MCP server");
287
- mcp
288
- .command("setup")
289
- .description("Configure MCP server")
290
- .option("--project", "Project-level config")
291
- .action(mcpSetup);
292
- mcp
293
- .command("remove")
294
- .description("Remove MCP server")
295
- .option("--project", "Project-level only")
296
- .action(mcpRemove);
297
- mcp
298
- .command("status")
299
- .description("MCP server status")
300
- .option("--verbose", "Show diagnostics")
301
- .action(mcpStatus);
302
-
303
- const skills = program.command("skills").description("Agent Skills");
304
- skills
305
- .command("validate")
306
- .description("Validate skills files")
307
- .option("--json", "JSON output")
308
- .action(skillsValidate);
309
- skills
310
- .command("install [package]")
311
- .description("Install skills")
312
- .option("--json", "JSON output")
313
- .action(skillsInstall);
314
- skills
315
- .command("list")
316
- .description("List available skills")
317
- .option("--json", "JSON output")
318
- .action(skillsList);
319
- skills
320
- .command("clean")
321
- .description("Remove installed skills")
322
- .option("--json", "JSON output")
323
- .action(skillsClean);
324
-
325
- const marketplace = program.command("marketplace").description("Marketplace");
326
- marketplace
327
- .command("compare <input>")
328
- .description("Find comparable packages")
329
- .option("--json", "JSON output")
330
- .option("--category <category>", "Filter by category")
331
- .option("--limit <n>", "Max results")
332
- .action(marketplaceCompare);
333
- marketplace
334
- .command("earnings")
335
- .description("Revenue summary")
336
- .option("--json", "JSON output")
337
- .action(marketplaceEarnings);
338
-
339
- program.parse();
340
-
341
- // ─── Helper ────────────────────────────────────────────────────────
342
-
343
- function runBinary(binaryPath) {
344
- try {
345
- execFileSync(binaryPath, process.argv.slice(2), {
346
- stdio: "inherit",
347
- env: process.env,
348
- });
349
- process.exit(0);
350
- } catch (err) {
351
- if (err.status != null) {
352
- process.exit(err.status);
353
- }
354
- // Binary failed to execute — fall through to JS CLI
355
- }
356
- }
4
+ runNativeCommand("lpm");
package/bin/lpx.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runNativeCommand } from "./native.js";
3
+
4
+ runNativeCommand("lpx");
package/bin/native.js ADDED
@@ -0,0 +1,154 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import { createRequire } from "node:module";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+
7
+ const require = createRequire(import.meta.url);
8
+
9
+ export const PLATFORMS = Object.freeze({
10
+ "darwin-arm64": {
11
+ pkg: "@lpm-registry/cli-darwin-arm64",
12
+ lpm: "lpm",
13
+ lpx: "lpx",
14
+ },
15
+ "darwin-x64": {
16
+ pkg: "@lpm-registry/cli-darwin-x64",
17
+ lpm: "lpm",
18
+ lpx: "lpx",
19
+ },
20
+ "linux-arm64": {
21
+ pkg: "@lpm-registry/cli-linux-arm64",
22
+ lpm: "lpm",
23
+ lpx: "lpx",
24
+ },
25
+ "linux-x64": {
26
+ pkg: "@lpm-registry/cli-linux-x64",
27
+ lpm: "lpm",
28
+ lpx: "lpx",
29
+ },
30
+ "win32-x64": {
31
+ pkg: "@lpm-registry/cli-win32-x64",
32
+ lpm: "lpm.exe",
33
+ lpx: "lpx.exe",
34
+ },
35
+ });
36
+
37
+ export function platformKey(platform = process.platform, arch = os.arch()) {
38
+ return `${platform}-${arch}`;
39
+ }
40
+
41
+ export function resolveNativeBinary(options = {}) {
42
+ const command = options.command ?? "lpm";
43
+ const env = options.env ?? process.env;
44
+ const platform = options.platform ?? process.platform;
45
+ const arch = options.arch ?? os.arch();
46
+ const requireFn = options.requireFn ?? require;
47
+
48
+ const override = env.LPM_BINARY_PATH;
49
+ if (override) {
50
+ return {
51
+ path: override,
52
+ source: "env",
53
+ argsPrefix: command === "lpx" ? ["dlx"] : [],
54
+ };
55
+ }
56
+
57
+ const key = platformKey(platform, arch);
58
+ const spec = PLATFORMS[key];
59
+ if (!spec) {
60
+ throw new LpmWrapperError(
61
+ `Unsupported platform: ${key}`,
62
+ [
63
+ "LPM publishes native npm packages for macOS, Linux, and Windows on x64/arm64.",
64
+ "Use another install method from https://github.com/lpm-dev/rust-client.",
65
+ ],
66
+ );
67
+ }
68
+
69
+ let packageJsonPath;
70
+ try {
71
+ packageJsonPath = requireFn.resolve(`${spec.pkg}/package.json`);
72
+ } catch (error) {
73
+ throw new LpmWrapperError(
74
+ `Native package ${spec.pkg} is not installed.`,
75
+ [
76
+ "Reinstall with optional dependencies enabled:",
77
+ " npm install -g @lpm-registry/cli",
78
+ "If you used --omit=optional, --no-optional, or a package-manager policy that blocks optional dependencies, remove that setting.",
79
+ ],
80
+ error,
81
+ );
82
+ }
83
+
84
+ const binaryPath = path.join(path.dirname(packageJsonPath), spec[command]);
85
+ if (!fs.existsSync(binaryPath)) {
86
+ throw new LpmWrapperError(
87
+ `Native package ${spec.pkg} is installed, but ${spec[command]} is missing.`,
88
+ ["Reinstall LPM with `npm install -g @lpm-registry/cli`."],
89
+ );
90
+ }
91
+
92
+ return {
93
+ path: binaryPath,
94
+ source: spec.pkg,
95
+ argsPrefix: [],
96
+ };
97
+ }
98
+
99
+ export function runNativeCommand(command) {
100
+ let native;
101
+ try {
102
+ native = resolveNativeBinary({ command });
103
+ } catch (error) {
104
+ printWrapperError(error);
105
+ process.exit(1);
106
+ }
107
+
108
+ const args = native.argsPrefix.concat(process.argv.slice(2));
109
+ const result = spawnSync(native.path, args, {
110
+ stdio: "inherit",
111
+ env: process.env,
112
+ });
113
+
114
+ if (result.error) {
115
+ console.error(`[lpm] Failed to run native binary at ${native.path}`);
116
+ console.error(`[lpm] ${result.error.message}`);
117
+ process.exit(1);
118
+ }
119
+
120
+ if (result.signal) {
121
+ forwardSignalExit(result.signal);
122
+ }
123
+
124
+ process.exit(result.status ?? 1);
125
+ }
126
+
127
+ export class LpmWrapperError extends Error {
128
+ constructor(message, hints = [], cause = undefined) {
129
+ super(message, cause ? { cause } : undefined);
130
+ this.name = "LpmWrapperError";
131
+ this.hints = hints;
132
+ }
133
+ }
134
+
135
+ function printWrapperError(error) {
136
+ if (error instanceof LpmWrapperError) {
137
+ console.error(`[lpm] ${error.message}`);
138
+ for (const hint of error.hints) {
139
+ console.error(`[lpm] ${hint}`);
140
+ }
141
+ return;
142
+ }
143
+
144
+ console.error(`[lpm] ${error?.message ?? error}`);
145
+ }
146
+
147
+ function forwardSignalExit(signal) {
148
+ const signalNumber = os.constants.signals[signal];
149
+ if (signalNumber) {
150
+ process.kill(process.pid, signal);
151
+ process.exit(128 + signalNumber);
152
+ }
153
+ process.exit(1);
154
+ }