slopcode 0.2.65 → 0.2.67

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 (3) hide show
  1. package/bin/slopcode +115 -59
  2. package/package.json +12 -12
  3. package/postinstall.mjs +111 -74
package/bin/slopcode CHANGED
@@ -5,6 +5,7 @@ const childProcess = require("child_process")
5
5
  const fs = require("fs")
6
6
  const path = require("path")
7
7
  const os = require("os")
8
+ const pkg = require("../package.json")
8
9
 
9
10
  function run(target) {
10
11
  const result = childProcess.spawnSync(target, process.argv.slice(2), {
@@ -25,13 +26,9 @@ if (envPath) {
25
26
 
26
27
  const scriptPath = fs.realpathSync(__filename)
27
28
  const scriptDir = path.dirname(scriptPath)
28
-
29
- //
30
29
  const cached = path.join(scriptDir, ".slopcode")
31
- if (fs.existsSync(cached)) {
32
- run(cached)
33
- }
34
-
30
+ const meta = path.join(scriptDir, ".slopcode.json")
31
+ const sidecar = path.join(scriptDir, "neovim")
35
32
  const platformMap = {
36
33
  darwin: "darwin",
37
34
  linux: "linux",
@@ -42,6 +39,11 @@ const archMap = {
42
39
  arm64: "arm64",
43
40
  arm: "arm",
44
41
  }
42
+ const supported = {
43
+ darwin: ["arm64", "x64"],
44
+ linux: ["arm64", "x64"],
45
+ windows: ["x64"],
46
+ }
45
47
 
46
48
  let platform = platformMap[os.platform()]
47
49
  if (!platform) {
@@ -53,28 +55,55 @@ if (!arch) {
53
55
  }
54
56
  const binary = platform === "windows" ? "slopcode.exe" : "slopcode"
55
57
 
58
+ function remove(target) {
59
+ if (!fs.existsSync(target)) return
60
+ fs.rmSync(target, { recursive: true, force: true })
61
+ }
62
+
63
+ function clearCache() {
64
+ remove(cached)
65
+ remove(meta)
66
+ remove(sidecar)
67
+ }
68
+
69
+ function libc() {
70
+ if (platform !== "linux") return
71
+ const report = process.report?.getReport?.()
72
+ if (typeof report?.header?.glibcVersionRuntime === "string" && report.header.glibcVersionRuntime) {
73
+ return "glibc"
74
+ }
75
+ if (fs.existsSync("/etc/alpine-release")) return "musl"
76
+ const getconf = childProcess.spawnSync("getconf", ["GNU_LIBC_VERSION"], {
77
+ encoding: "utf8",
78
+ timeout: 1500,
79
+ })
80
+ const fromGetconf = ((getconf.stdout || "") + (getconf.stderr || "")).toLowerCase()
81
+ if (getconf.status === 0 && fromGetconf.includes("glibc")) return "glibc"
82
+ const result = childProcess.spawnSync("ldd", ["--version"], {
83
+ encoding: "utf8",
84
+ timeout: 1500,
85
+ })
86
+ const text = ((result.stdout || "") + (result.stderr || "")).toLowerCase()
87
+ if (text.includes("musl")) return "musl"
88
+ if (text.includes("glibc") || text.includes("gnu libc")) return "glibc"
89
+ const loader = arch === "arm64" ? "/lib/ld-musl-aarch64.so.1" : arch === "x64" ? "/lib/ld-musl-x86_64.so.1" : ""
90
+ if (loader && fs.existsSync(loader)) return "musl"
91
+ }
92
+
56
93
  function supportsAvx2() {
57
94
  if (arch !== "x64") return false
58
95
 
59
96
  if (platform === "linux") {
60
- try {
61
- return /(^|\s)avx2(\s|$)/i.test(fs.readFileSync("/proc/cpuinfo", "utf8"))
62
- } catch {
63
- return false
64
- }
97
+ return /(^|\s)avx2(\s|$)/i.test(fs.readFileSync("/proc/cpuinfo", "utf8"))
65
98
  }
66
99
 
67
100
  if (platform === "darwin") {
68
- try {
69
- const result = childProcess.spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], {
70
- encoding: "utf8",
71
- timeout: 1500,
72
- })
73
- if (result.status !== 0) return false
74
- return (result.stdout || "").trim() === "1"
75
- } catch {
76
- return false
77
- }
101
+ const result = childProcess.spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], {
102
+ encoding: "utf8",
103
+ timeout: 1500,
104
+ })
105
+ if (result.status !== 0) return false
106
+ return (result.stdout || "").trim() === "1"
78
107
  }
79
108
 
80
109
  if (platform === "windows") {
@@ -82,22 +111,16 @@ function supportsAvx2() {
82
111
  '(Add-Type -MemberDefinition "[DllImport(""kernel32.dll"")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);" -Name Kernel32 -Namespace Win32 -PassThru)::IsProcessorFeaturePresent(40)'
83
112
 
84
113
  for (const exe of ["powershell.exe", "pwsh.exe", "pwsh", "powershell"]) {
85
- try {
86
- const result = childProcess.spawnSync(exe, ["-NoProfile", "-NonInteractive", "-Command", cmd], {
87
- encoding: "utf8",
88
- timeout: 3000,
89
- windowsHide: true,
90
- })
91
- if (result.status !== 0) continue
92
- const out = (result.stdout || "").trim().toLowerCase()
93
- if (out === "true" || out === "1") return true
94
- if (out === "false" || out === "0") return false
95
- } catch {
96
- continue
97
- }
114
+ const result = childProcess.spawnSync(exe, ["-NoProfile", "-NonInteractive", "-Command", cmd], {
115
+ encoding: "utf8",
116
+ timeout: 3000,
117
+ windowsHide: true,
118
+ })
119
+ if (result.error || result.status !== 0) continue
120
+ const out = (result.stdout || "").trim().toLowerCase()
121
+ if (out === "true" || out === "1") return true
122
+ if (out === "false" || out === "0") return false
98
123
  }
99
-
100
- return false
101
124
  }
102
125
 
103
126
  return false
@@ -107,34 +130,23 @@ function names(prefix) {
107
130
  const base = `${prefix}-${platform}-${arch}`
108
131
  const avx2 = supportsAvx2()
109
132
  const baseline = arch === "x64" && !avx2
133
+ const kind = libc()
110
134
 
111
135
  if (platform === "linux") {
112
- const musl = (() => {
113
- try {
114
- if (fs.existsSync("/etc/alpine-release")) return true
115
- } catch {
116
- // ignore
117
- }
118
-
119
- try {
120
- const result = childProcess.spawnSync("ldd", ["--version"], { encoding: "utf8" })
121
- const text = ((result.stdout || "") + (result.stderr || "")).toLowerCase()
122
- if (text.includes("musl")) return true
123
- } catch {
124
- // ignore
125
- }
126
-
127
- return false
128
- })()
129
-
130
- if (musl) {
136
+ if (kind === "musl") {
131
137
  if (arch === "x64") {
132
138
  if (baseline) return [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base]
133
139
  return [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]
134
140
  }
135
141
  return [`${base}-musl`, base]
136
142
  }
137
-
143
+ if (kind === "glibc") {
144
+ if (arch === "x64") {
145
+ if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
146
+ return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
147
+ }
148
+ return [base, `${base}-musl`]
149
+ }
138
150
  if (arch === "x64") {
139
151
  if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
140
152
  return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
@@ -149,8 +161,51 @@ function names(prefix) {
149
161
  return [base]
150
162
  }
151
163
 
164
+ function readMeta() {
165
+ if (!fs.existsSync(meta)) return
166
+ try {
167
+ return JSON.parse(fs.readFileSync(meta, "utf8"))
168
+ } catch {
169
+ return
170
+ }
171
+ }
172
+
173
+ function cacheReady(names) {
174
+ if (!fs.existsSync(cached)) return
175
+ const info = readMeta()
176
+ if (!info) return
177
+ if (info.version !== pkg.version) return
178
+ if (info.platform !== platform || info.arch !== arch) return
179
+ if (info.binary !== binary) return
180
+ if (platform === "linux" && info.libc !== libc()) return
181
+ if (typeof info.package !== "string" || !names.includes(info.package)) return
182
+ if (info.sidecar === true && !fs.existsSync(sidecar)) return
183
+ return cached
184
+ }
185
+
186
+ function unsupported() {
187
+ const hit = supported[platform]
188
+ return !hit || !hit.includes(arch)
189
+ }
190
+
191
+ function supportedMessage() {
192
+ return Object.entries(supported)
193
+ .map(([platform, archs]) => `${platform}:${archs.join(",")}`)
194
+ .join(" ")
195
+ }
196
+
152
197
  const packageNames = names("slopcode-bin")
153
198
  const resolvedNames = Array.from(new Set([...packageNames, ...names("slopcode")]))
199
+ const hit = cacheReady(resolvedNames)
200
+ if (hit) {
201
+ run(hit)
202
+ }
203
+ clearCache()
204
+
205
+ if (unsupported()) {
206
+ console.error(`Unsupported platform ${platform}/${arch}. Supported targets: ${supportedMessage()}`)
207
+ process.exit(1)
208
+ }
154
209
 
155
210
  function resolveBinary() {
156
211
  for (const name of resolvedNames) {
@@ -158,7 +213,7 @@ function resolveBinary() {
158
213
  const candidate = require.resolve(`${name}/bin/${binary}`, {
159
214
  paths: [scriptDir],
160
215
  })
161
- if (fs.existsSync(candidate)) return candidate
216
+ if (fs.existsSync(candidate)) return { path: candidate, package: name }
162
217
  } catch {
163
218
  continue
164
219
  }
@@ -172,7 +227,7 @@ function findBinary(startDir) {
172
227
  if (fs.existsSync(modules)) {
173
228
  for (const name of resolvedNames) {
174
229
  const candidate = path.join(modules, name, "bin", binary)
175
- if (fs.existsSync(candidate)) return candidate
230
+ if (fs.existsSync(candidate)) return { path: candidate, package: name }
176
231
  }
177
232
  }
178
233
  const parent = path.dirname(current)
@@ -193,4 +248,5 @@ if (!resolved) {
193
248
  process.exit(1)
194
249
  }
195
250
 
196
- run(resolved)
251
+ run(resolved.path)
252
+
package/package.json CHANGED
@@ -34,19 +34,19 @@
34
34
  "scripts": {
35
35
  "postinstall": "bun ./postinstall.mjs || node ./postinstall.mjs"
36
36
  },
37
- "version": "0.2.65",
37
+ "version": "0.2.67",
38
38
  "license": "MIT",
39
39
  "optionalDependencies": {
40
- "slopcode-bin-linux-arm64": "0.2.65",
41
- "slopcode-bin-linux-x64-musl": "0.2.65",
42
- "slopcode-bin-windows-x64": "0.2.65",
43
- "slopcode-bin-linux-x64-baseline-musl": "0.2.65",
44
- "slopcode-bin-linux-x64": "0.2.65",
45
- "slopcode-bin-windows-x64-baseline": "0.2.65",
46
- "slopcode-bin-darwin-x64-baseline": "0.2.65",
47
- "slopcode-bin-linux-x64-baseline": "0.2.65",
48
- "slopcode-bin-darwin-x64": "0.2.65",
49
- "slopcode-bin-darwin-arm64": "0.2.65",
50
- "slopcode-bin-linux-arm64-musl": "0.2.65"
40
+ "slopcode-bin-linux-arm64": "0.2.67",
41
+ "slopcode-bin-linux-x64-musl": "0.2.67",
42
+ "slopcode-bin-windows-x64": "0.2.67",
43
+ "slopcode-bin-linux-x64-baseline-musl": "0.2.67",
44
+ "slopcode-bin-linux-x64": "0.2.67",
45
+ "slopcode-bin-windows-x64-baseline": "0.2.67",
46
+ "slopcode-bin-darwin-x64-baseline": "0.2.67",
47
+ "slopcode-bin-linux-x64-baseline": "0.2.67",
48
+ "slopcode-bin-darwin-x64": "0.2.67",
49
+ "slopcode-bin-darwin-arm64": "0.2.67",
50
+ "slopcode-bin-linux-arm64-musl": "0.2.67"
51
51
  }
52
52
  }
package/postinstall.mjs CHANGED
@@ -8,43 +8,51 @@ import { createRequire } from "module"
8
8
 
9
9
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
10
10
  const require = createRequire(import.meta.url)
11
+ const pkg = require("./package.json")
12
+ const supported = {
13
+ darwin: ["arm64", "x64"],
14
+ linux: ["arm64", "x64"],
15
+ windows: ["x64"],
16
+ }
11
17
 
12
18
  function detectPlatformAndArch() {
13
- // Map platform names
14
- let platform
15
- switch (os.platform()) {
16
- case "darwin":
17
- platform = "darwin"
18
- break
19
- case "linux":
20
- platform = "linux"
21
- break
22
- case "win32":
23
- platform = "windows"
24
- break
25
- default:
26
- platform = os.platform()
27
- break
28
- }
19
+ const platform =
20
+ {
21
+ darwin: "darwin",
22
+ linux: "linux",
23
+ win32: "windows",
24
+ }[os.platform()] ?? os.platform()
25
+ const arch =
26
+ {
27
+ x64: "x64",
28
+ arm64: "arm64",
29
+ arm: "arm",
30
+ }[os.arch()] ?? os.arch()
31
+ return { platform, arch }
32
+ }
29
33
 
30
- // Map architecture names
31
- let arch
32
- switch (os.arch()) {
33
- case "x64":
34
- arch = "x64"
35
- break
36
- case "arm64":
37
- arch = "arm64"
38
- break
39
- case "arm":
40
- arch = "arm"
41
- break
42
- default:
43
- arch = os.arch()
44
- break
34
+ function detectLibc(platform, arch) {
35
+ if (platform !== "linux") return
36
+ const report = process.report?.getReport?.()
37
+ if (typeof report?.header?.glibcVersionRuntime === "string" && report.header.glibcVersionRuntime) {
38
+ return "glibc"
45
39
  }
46
-
47
- return { platform, arch }
40
+ if (fs.existsSync("/etc/alpine-release")) return "musl"
41
+ const getconf = require("child_process").spawnSync("getconf", ["GNU_LIBC_VERSION"], {
42
+ encoding: "utf8",
43
+ timeout: 1500,
44
+ })
45
+ const fromGetconf = ((getconf.stdout || "") + (getconf.stderr || "")).toLowerCase()
46
+ if (getconf.status === 0 && fromGetconf.includes("glibc")) return "glibc"
47
+ const result = require("child_process").spawnSync("ldd", ["--version"], {
48
+ encoding: "utf8",
49
+ timeout: 1500,
50
+ })
51
+ const text = ((result.stdout || "") + (result.stderr || "")).toLowerCase()
52
+ if (text.includes("musl")) return "musl"
53
+ if (text.includes("glibc") || text.includes("gnu libc")) return "glibc"
54
+ const loader = arch === "arm64" ? "/lib/ld-musl-aarch64.so.1" : arch === "x64" ? "/lib/ld-musl-x86_64.so.1" : ""
55
+ if (loader && fs.existsSync(loader)) return "musl"
48
56
  }
49
57
 
50
58
  function supportsAvx2(platform, arch) {
@@ -78,35 +86,27 @@ function names(platform, arch) {
78
86
  const base = `slopcode-bin-${platform}-${arch}`
79
87
  const avx2 = supportsAvx2(platform, arch)
80
88
  const baseline = arch === "x64" && !avx2
89
+ const libc = detectLibc(platform, arch)
81
90
 
82
91
  if (platform === "linux") {
83
- const musl = (() => {
84
- try {
85
- if (fs.existsSync("/etc/alpine-release")) return true
86
- } catch {}
87
-
88
- try {
89
- const result = require("child_process").spawnSync("ldd", ["--version"], { encoding: "utf8" })
90
- const text = ((result.stdout || "") + (result.stderr || "")).toLowerCase()
91
- if (text.includes("musl")) return true
92
- } catch {}
93
-
94
- return false
95
- })()
96
-
97
- if (musl) {
92
+ if (libc === "musl") {
98
93
  if (arch === "x64") {
99
94
  if (baseline) return [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base]
100
95
  return [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]
101
96
  }
102
97
  return [`${base}-musl`, base]
103
98
  }
104
-
99
+ if (libc === "glibc") {
100
+ if (arch === "x64") {
101
+ if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
102
+ return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
103
+ }
104
+ return [base, `${base}-musl`]
105
+ }
105
106
  if (arch === "x64") {
106
107
  if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
107
108
  return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
108
109
  }
109
-
110
110
  return [base, `${base}-musl`]
111
111
  }
112
112
 
@@ -118,6 +118,18 @@ function names(platform, arch) {
118
118
  return [base]
119
119
  }
120
120
 
121
+ function clearCache() {
122
+ fs.rmSync(path.join(__dirname, "bin", ".slopcode"), { force: true })
123
+ fs.rmSync(path.join(__dirname, "bin", ".slopcode.json"), { force: true })
124
+ fs.rmSync(path.join(__dirname, "bin", "neovim"), { recursive: true, force: true })
125
+ }
126
+
127
+ function supportedMessage() {
128
+ return Object.entries(supported)
129
+ .map(([platform, archs]) => `${platform}:${archs.join(",")}`)
130
+ .join(" ")
131
+ }
132
+
121
133
  function findBinary() {
122
134
  const { platform, arch } = detectPlatformAndArch()
123
135
  const binaryName = platform === "windows" ? "slopcode.exe" : "slopcode"
@@ -128,71 +140,95 @@ function findBinary() {
128
140
  const packageDir = path.dirname(packageJsonPath)
129
141
  const binaryPath = path.join(packageDir, "bin", binaryName)
130
142
  if (fs.existsSync(binaryPath)) {
131
- return { binaryPath, binaryName }
143
+ return { binaryPath, binaryName, packageName: name, platform, arch, libc: detectLibc(platform, arch) }
132
144
  }
133
145
  } catch {
134
146
  continue
135
147
  }
136
148
  }
149
+ }
137
150
 
138
- return
151
+ function cacheSidecar(sourcePath) {
152
+ const source = path.join(path.dirname(sourcePath), "neovim")
153
+ if (!fs.existsSync(source)) return false
154
+ const target = path.join(__dirname, "bin", "neovim")
155
+ fs.rmSync(target, { recursive: true, force: true })
156
+ fs.cpSync(source, target, { recursive: true, force: true })
157
+ return true
139
158
  }
140
159
 
141
160
  function prepareBinDirectory(binaryName) {
142
161
  const binDir = path.join(__dirname, "bin")
143
162
  const targetPath = path.join(binDir, binaryName)
144
163
 
145
- // Ensure bin directory exists
146
164
  if (!fs.existsSync(binDir)) {
147
165
  fs.mkdirSync(binDir, { recursive: true })
148
166
  }
149
-
150
- // Remove existing binary/symlink if it exists
151
167
  if (fs.existsSync(targetPath)) {
152
168
  fs.unlinkSync(targetPath)
153
169
  }
154
170
 
155
- return { binDir, targetPath }
171
+ return { targetPath }
156
172
  }
157
173
 
158
- function symlinkBinary(sourcePath, binaryName) {
159
- const { targetPath } = prepareBinDirectory(binaryName)
160
-
161
- fs.symlinkSync(sourcePath, targetPath)
162
- console.log(`slopcode binary symlinked: ${targetPath} -> ${sourcePath}`)
163
-
164
- // Verify the file exists after operation
165
- if (!fs.existsSync(targetPath)) {
166
- throw new Error(`Failed to symlink binary to ${targetPath}`)
167
- }
174
+ function writeMeta(input) {
175
+ fs.writeFileSync(
176
+ path.join(__dirname, "bin", ".slopcode.json"),
177
+ JSON.stringify(
178
+ {
179
+ version: pkg.version,
180
+ platform: input.platform,
181
+ arch: input.arch,
182
+ libc: input.libc,
183
+ package: input.packageName,
184
+ binary: input.binaryName,
185
+ sidecar: input.sidecar,
186
+ },
187
+ null,
188
+ 2,
189
+ ),
190
+ )
168
191
  }
169
192
 
170
193
  async function main() {
171
194
  try {
195
+ const { platform, arch } = detectPlatformAndArch()
196
+ if (!(supported[platform] ?? []).includes(arch)) {
197
+ clearCache()
198
+ console.log(
199
+ `Unsupported slopcode platform during postinstall: ${platform}/${arch}. Supported targets: ${supportedMessage()}`,
200
+ )
201
+ return
202
+ }
203
+
172
204
  if (os.platform() === "win32") {
173
- // On Windows, the .exe is already included in the package and bin field points to it
174
- // No postinstall setup needed
175
205
  console.log("Windows detected: binary setup not needed (using packaged .exe)")
176
206
  return
177
207
  }
178
208
 
179
- // On non-Windows platforms, just verify the binary package exists
180
- // Don't replace the wrapper script - it handles binary execution
181
209
  const found = findBinary()
182
210
  if (!found) {
211
+ clearCache()
183
212
  console.log("No platform binary package detected during postinstall; runtime resolver will handle it")
184
213
  return
185
214
  }
186
- const binaryPath = found.binaryPath
215
+
216
+ clearCache()
187
217
  const target = path.join(__dirname, "bin", ".slopcode")
188
- if (fs.existsSync(target)) fs.unlinkSync(target)
218
+ const { targetPath } = prepareBinDirectory(".slopcode")
189
219
  try {
190
- fs.linkSync(binaryPath, target)
220
+ fs.linkSync(found.binaryPath, targetPath)
191
221
  } catch {
192
- fs.copyFileSync(binaryPath, target)
222
+ fs.copyFileSync(found.binaryPath, target)
193
223
  }
194
224
  fs.chmodSync(target, 0o755)
225
+ const sidecar = cacheSidecar(found.binaryPath)
226
+ writeMeta({
227
+ ...found,
228
+ sidecar,
229
+ })
195
230
  } catch (error) {
231
+ clearCache()
196
232
  console.error("Failed to setup slopcode binary cache:", error.message)
197
233
  process.exit(0)
198
234
  }
@@ -201,6 +237,7 @@ async function main() {
201
237
  try {
202
238
  main()
203
239
  } catch (error) {
240
+ clearCache()
204
241
  console.error("Postinstall script error:", error.message)
205
242
  process.exit(0)
206
243
  }