@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
@@ -1,264 +0,0 @@
1
- import { spawn } from "node:child_process"
2
- import fs from "node:fs"
3
- import path from "node:path"
4
- import { getPackageManager, getRegistryUrl, getToken } from "../config.js"
5
- import { createSpinner, log, printHeader } from "../ui.js"
6
- import { skillsInstall } from "./skills.js"
7
-
8
- /**
9
- * Check if a package name is an LPM package
10
- * LPM packages use the @lpm.dev scope
11
- */
12
- function isLpmPackage(pkgName) {
13
- return pkgName.startsWith("@lpm.dev/")
14
- }
15
-
16
- export async function install(packages, options) {
17
- const isJson = options?.json
18
-
19
- if (!isJson) printHeader()
20
-
21
- const token = await getToken()
22
- if (!token) {
23
- if (isJson) {
24
- process.stdout.write(
25
- `${JSON.stringify(
26
- {
27
- success: false,
28
- packages: [],
29
- npmOutput: "",
30
- warnings: [],
31
- errors: [
32
- 'You must be logged in to install packages. Run "lpm login" first.',
33
- ],
34
- },
35
- null,
36
- 2,
37
- )}\n`,
38
- )
39
- } else {
40
- log.error(
41
- 'You must be logged in to install packages. Run "lpm login" first.',
42
- )
43
- }
44
- process.exit(1)
45
- }
46
-
47
- // Track if user specified packages explicitly (for scoped skills fetch)
48
- const explicitPackages = packages && packages.length > 0
49
-
50
- if (!packages || packages.length === 0) {
51
- // No packages specified - read from package.json
52
- const packageJsonPath = path.resolve(process.cwd(), "package.json")
53
- if (!fs.existsSync(packageJsonPath)) {
54
- if (isJson) {
55
- process.stdout.write(
56
- `${JSON.stringify(
57
- {
58
- success: false,
59
- packages: [],
60
- npmOutput: "",
61
- warnings: [],
62
- errors: ["No packages specified and no package.json found."],
63
- },
64
- null,
65
- 2,
66
- )}\n`,
67
- )
68
- } else {
69
- log.error("No packages specified and no package.json found.")
70
- }
71
- process.exit(1)
72
- }
73
-
74
- const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"))
75
- const allDeps = {
76
- ...pkg.dependencies,
77
- ...pkg.devDependencies,
78
- }
79
-
80
- // Filter to LPM packages only (@lpm.dev scope)
81
- packages = Object.keys(allDeps).filter(isLpmPackage)
82
-
83
- if (packages.length === 0) {
84
- if (isJson) {
85
- process.stdout.write(
86
- `${JSON.stringify(
87
- {
88
- success: true,
89
- packages: [],
90
- npmOutput: "",
91
- warnings: ["No LPM packages (@lpm.dev/*) found in package.json."],
92
- errors: [],
93
- },
94
- null,
95
- 2,
96
- )}\n`,
97
- )
98
- } else {
99
- log.info("No LPM packages (@lpm.dev/*) found in package.json.")
100
- }
101
- process.exit(0)
102
- }
103
-
104
- if (!isJson) {
105
- log.info(`Found ${packages.length} LPM packages in package.json:`)
106
- for (const pkg of packages) {
107
- log.info(` ${pkg}`)
108
- }
109
- }
110
- }
111
-
112
- let spinner
113
- if (!isJson) {
114
- spinner = createSpinner("Configuring registry authentication...").start()
115
- }
116
-
117
- const baseRegistryUrl = getRegistryUrl()
118
- // Ensure we have the full registry path for npm
119
- const registryUrl = baseRegistryUrl.endsWith("/api/registry")
120
- ? baseRegistryUrl
121
- : `${baseRegistryUrl}/api/registry`
122
- // Remove protocol for auth token config (e.g. https://registry.com/ -> //registry.com/)
123
- const registryHost = registryUrl.replace(/^https?:/, "")
124
-
125
- // Create temporary .npmrc content
126
- // Simple configuration - all LPM packages use @lpm.dev scope
127
- const npmrcContent = `${registryHost}/:_authToken=${token}
128
- @lpm.dev:registry=${registryUrl}
129
- `
130
-
131
- const pm = getPackageManager(options?.pm)
132
-
133
- // For npm we can use --userconfig with a temp file.
134
- // For pnpm/yarn/bun we write a temporary project .npmrc (all PMs read it).
135
- const projectNpmrcPath = path.resolve(process.cwd(), ".npmrc")
136
- let existingNpmrc = null
137
- let tempNpmrcPath = null
138
-
139
- if (pm === "npm") {
140
- // npm supports --userconfig — use a separate temp file (doesn't touch project .npmrc)
141
- tempNpmrcPath = path.resolve(process.cwd(), `.npmrc.lpm-${Date.now()}`)
142
- fs.writeFileSync(tempNpmrcPath, npmrcContent)
143
- } else {
144
- // pnpm/yarn/bun read project .npmrc — back up existing, write temp, restore after
145
- if (fs.existsSync(projectNpmrcPath)) {
146
- existingNpmrc = fs.readFileSync(projectNpmrcPath, "utf8")
147
- }
148
- fs.writeFileSync(projectNpmrcPath, npmrcContent)
149
- }
150
-
151
- if (!isJson) {
152
- spinner.succeed(`Configuration generated. Running ${pm} install...`)
153
- }
154
-
155
- const pmArgs =
156
- pm === "npm"
157
- ? ["install", ...packages, "--userconfig", tempNpmrcPath]
158
- : ["install", ...packages]
159
-
160
- // In JSON mode, capture stdout/stderr instead of inheriting
161
- const child = spawn(pm, pmArgs, {
162
- stdio: isJson ? "pipe" : "inherit",
163
- env: { ...process.env, LPM_TOKEN: token },
164
- })
165
-
166
- const cleanup = () => {
167
- if (pm === "npm") {
168
- // Remove temp file
169
- if (tempNpmrcPath && fs.existsSync(tempNpmrcPath)) {
170
- fs.unlinkSync(tempNpmrcPath)
171
- }
172
- } else {
173
- // Restore original .npmrc (or remove if there wasn't one)
174
- if (existingNpmrc !== null) {
175
- fs.writeFileSync(projectNpmrcPath, existingNpmrc)
176
- } else if (fs.existsSync(projectNpmrcPath)) {
177
- fs.unlinkSync(projectNpmrcPath)
178
- }
179
- }
180
- }
181
-
182
- const fetchSkills = options?.skills !== false
183
- const editorSetup = options?.editorSetup !== false
184
-
185
- if (isJson) {
186
- let stdout = ""
187
- let stderr = ""
188
- child.stdout.on("data", data => {
189
- stdout += data.toString()
190
- })
191
- child.stderr.on("data", data => {
192
- stderr += data.toString()
193
- })
194
-
195
- child.on("close", async code => {
196
- cleanup()
197
- const output = {
198
- success: code === 0,
199
- packages: packages.map(p => ({ name: p })),
200
- npmOutput: (stdout + stderr).trim(),
201
- warnings: [],
202
- errors: code !== 0 ? [`${pm} install failed with code ${code}`] : [],
203
- }
204
- process.stdout.write(`${JSON.stringify(output, null, 2)}\n`)
205
- if (code !== 0) process.exit(code)
206
- if (fetchSkills) {
207
- const skillOpts = { json: true, editorSetup }
208
- if (explicitPackages) {
209
- for (const pkg of packages.filter(isLpmPackage)) {
210
- await skillsInstall(pkg, skillOpts)
211
- }
212
- } else {
213
- await skillsInstall(null, skillOpts)
214
- }
215
- }
216
- })
217
-
218
- child.on("error", err => {
219
- cleanup()
220
- const output = {
221
- success: false,
222
- packages: packages.map(p => ({ name: p })),
223
- npmOutput: "",
224
- warnings: [],
225
- errors: [`Failed to start ${pm}: ${err.message}`],
226
- }
227
- process.stdout.write(`${JSON.stringify(output, null, 2)}\n`)
228
- process.exit(1)
229
- })
230
- } else {
231
- child.on("close", async code => {
232
- cleanup()
233
- if (code !== 0) {
234
- log.error(`${pm} install failed with code ${code}`)
235
- process.exit(code)
236
- } else {
237
- log.success("Packages installed successfully.")
238
- if (fetchSkills) {
239
- console.log("")
240
- const skillOpts = { editorSetup }
241
- if (explicitPackages) {
242
- for (const pkg of packages.filter(isLpmPackage)) {
243
- await skillsInstall(pkg, skillOpts)
244
- }
245
- } else {
246
- await skillsInstall(null, skillOpts)
247
- }
248
- }
249
- }
250
- })
251
-
252
- child.on("error", err => {
253
- log.error(`Failed to start ${pm}: ${err.message}`)
254
- cleanup()
255
- process.exit(1)
256
- })
257
- }
258
-
259
- // Handle interrupt to cleanup
260
- process.on("SIGINT", () => {
261
- cleanup()
262
- process.exit()
263
- })
264
- }