@lpm-registry/cli 0.58.0 → 0.59.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.
Files changed (62) hide show
  1. package/README.md +25 -44
  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 +42 -82
  6. package/scripts/install-binary.js +219 -550
  7. package/CHANGELOG.md +0 -197
  8. package/LICENSE +0 -15
  9. package/index.d.ts +0 -131
  10. package/index.js +0 -31
  11. package/lib/api.js +0 -398
  12. package/lib/commands/add.js +0 -1217
  13. package/lib/commands/audit.js +0 -283
  14. package/lib/commands/cache.js +0 -209
  15. package/lib/commands/check-name.js +0 -112
  16. package/lib/commands/config.js +0 -186
  17. package/lib/commands/doctor.js +0 -140
  18. package/lib/commands/info.js +0 -215
  19. package/lib/commands/init.js +0 -146
  20. package/lib/commands/install.js +0 -264
  21. package/lib/commands/login.js +0 -595
  22. package/lib/commands/logout.js +0 -94
  23. package/lib/commands/marketplace-compare.js +0 -164
  24. package/lib/commands/marketplace-earnings.js +0 -89
  25. package/lib/commands/mcp-setup.js +0 -363
  26. package/lib/commands/npmrc.js +0 -178
  27. package/lib/commands/open.js +0 -82
  28. package/lib/commands/outdated.js +0 -291
  29. package/lib/commands/pool-stats.js +0 -100
  30. package/lib/commands/publish.js +0 -949
  31. package/lib/commands/quality.js +0 -211
  32. package/lib/commands/remove.js +0 -82
  33. package/lib/commands/run.js +0 -14
  34. package/lib/commands/search.js +0 -143
  35. package/lib/commands/setup.js +0 -221
  36. package/lib/commands/skills.js +0 -898
  37. package/lib/commands/token-rotate.js +0 -25
  38. package/lib/commands/uninstall.js +0 -107
  39. package/lib/commands/whoami.js +0 -129
  40. package/lib/config.js +0 -328
  41. package/lib/constants.js +0 -190
  42. package/lib/ecosystem.js +0 -501
  43. package/lib/editor-skills.js +0 -321
  44. package/lib/editors.js +0 -215
  45. package/lib/import-rewriter.js +0 -364
  46. package/lib/install-targets/mcp-server.js +0 -245
  47. package/lib/install-targets/vscode-extension.js +0 -178
  48. package/lib/install-targets.js +0 -82
  49. package/lib/integrity.js +0 -179
  50. package/lib/lpm-config-prompts.js +0 -102
  51. package/lib/lpm-config.js +0 -408
  52. package/lib/oidc.js +0 -166
  53. package/lib/project-utils.js +0 -152
  54. package/lib/quality/checks.js +0 -687
  55. package/lib/quality/display.js +0 -155
  56. package/lib/quality/score.js +0 -118
  57. package/lib/quality/swift-checks.js +0 -447
  58. package/lib/safe-path.js +0 -180
  59. package/lib/secure-store.js +0 -321
  60. package/lib/swift-project.js +0 -637
  61. package/lib/ui.js +0 -40
  62. package/scripts/__tests__/install-binary.test.js +0 -346
package/README.md CHANGED
@@ -1,64 +1,45 @@
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`. A tiny
12
+ `postinstall` verifier checks the native binary and wires the global command to
13
+ it where the platform allows that.
11
14
 
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>
19
-
20
- ## About This Package
21
-
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.
15
+ The JavaScript launcher does not implement package-manager behavior. All CLI
16
+ commands run in the native Rust binary.
23
17
 
24
- If the native binary isn't available for your platform, the JS fallback CLI activates automatically.
18
+ Source for this npm package lives in `lpm-dev/rust-client/npm/cli`.
25
19
 
26
- ## Quick Start
20
+ ## Updating
27
21
 
28
22
  ```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
23
+ lpm self-update
33
24
  ```
34
25
 
35
- ## Commands
26
+ When LPM was installed through npm, self-update runs:
36
27
 
37
- See the full command reference at [github.com/lpm-dev/rust-client](https://github.com/lpm-dev/rust-client#commands).
28
+ ```bash
29
+ npm install -g @lpm-registry/cli@<version>
30
+ ```
38
31
 
39
- ## API Exports
32
+ ## Troubleshooting
40
33
 
41
- This package exports utilities for programmatic use:
34
+ If your package manager was configured to omit optional dependencies, reinstall
35
+ with optional dependencies enabled:
42
36
 
43
- ```js
44
- import {
45
- generateIntegrity,
46
- verifyIntegrity,
47
- runQualityChecks,
48
- parseLpmPackageReference,
49
- detectFramework,
50
- } from "@lpm-registry/cli";
37
+ ```bash
38
+ npm install -g @lpm-registry/cli
51
39
  ```
52
40
 
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
41
+ If install scripts were disabled, reinstall without `--ignore-scripts` so npm
42
+ can validate the native binary during installation.
63
43
 
64
- MIT
44
+ Other install methods are documented at
45
+ [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
+ }