@neevcode/neev 0.0.0-dev-202607090852 → 0.0.0-dev-202607101251

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 (2) hide show
  1. package/package.json +14 -15
  2. package/postinstall.mjs +114 -68
package/package.json CHANGED
@@ -1,26 +1,25 @@
1
1
  {
2
2
  "name": "@neevcode/neev",
3
3
  "bin": {
4
- "neev": "./bin/opencode",
5
- "opencode": "./bin/opencode"
4
+ "neev": "./bin/opencode"
6
5
  },
7
6
  "scripts": {
8
7
  "postinstall": "bun ./postinstall.mjs || node ./postinstall.mjs"
9
8
  },
10
- "version": "0.0.0-dev-202607090852",
9
+ "version": "0.0.0-dev-202607101251",
11
10
  "license": "MIT",
12
11
  "optionalDependencies": {
13
- "@neevcode/neev-darwin-arm64": "0.0.0-dev-202607090852",
14
- "@neevcode/neev-darwin-x64": "0.0.0-dev-202607090852",
15
- "@neevcode/neev-darwin-x64-baseline": "0.0.0-dev-202607090852",
16
- "@neevcode/neev-linux-arm64": "0.0.0-dev-202607090852",
17
- "@neevcode/neev-linux-arm64-musl": "0.0.0-dev-202607090852",
18
- "@neevcode/neev-linux-x64": "0.0.0-dev-202607090852",
19
- "@neevcode/neev-linux-x64-baseline": "0.0.0-dev-202607090852",
20
- "@neevcode/neev-linux-x64-baseline-musl": "0.0.0-dev-202607090852",
21
- "@neevcode/neev-linux-x64-musl": "0.0.0-dev-202607090852",
22
- "@neevcode/neev-windows-arm64": "0.0.0-dev-202607090852",
23
- "@neevcode/neev-windows-x64": "0.0.0-dev-202607090852",
24
- "@neevcode/neev-windows-x64-baseline": "0.0.0-dev-202607090852"
12
+ "@neevcode/neev-linux-x64": "0.0.0-dev-202607101251",
13
+ "@neevcode/neev-linux-x64-baseline-musl": "0.0.0-dev-202607101251",
14
+ "@neevcode/neev-linux-arm64": "0.0.0-dev-202607101251",
15
+ "@neevcode/neev-linux-x64-musl": "0.0.0-dev-202607101251",
16
+ "@neevcode/neev-linux-x64-baseline": "0.0.0-dev-202607101251",
17
+ "@neevcode/neev-windows-x64-baseline": "0.0.0-dev-202607101251",
18
+ "@neevcode/neev-darwin-arm64": "0.0.0-dev-202607101251",
19
+ "@neevcode/neev-windows-x64": "0.0.0-dev-202607101251",
20
+ "@neevcode/neev-windows-arm64": "0.0.0-dev-202607101251",
21
+ "@neevcode/neev-linux-arm64-musl": "0.0.0-dev-202607101251",
22
+ "@neevcode/neev-darwin-x64-baseline": "0.0.0-dev-202607101251",
23
+ "@neevcode/neev-darwin-x64": "0.0.0-dev-202607101251"
25
24
  }
26
25
  }
package/postinstall.mjs CHANGED
@@ -1,102 +1,148 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // Runs inside the published @neevcode/neev meta package. Hardlinks the correct
4
+ // platform binary to bin/.opencode so the wrapper skips resolution on startup.
5
+ // Must stay zero-dependency plain node, and must NEVER fail the install: the
6
+ // wrapper (bin/opencode) does its own variant resolution at runtime, so any
7
+ // failure here only costs startup latency, not functionality.
8
+ //
9
+ // Variant priority (musl/AVX2 detection) mirrors bin/opencode — keep in sync.
10
+
3
11
  import fs from "fs"
4
12
  import path from "path"
5
13
  import os from "os"
14
+ import childProcess from "child_process"
6
15
  import { fileURLToPath } from "url"
7
16
  import { createRequire } from "module"
8
17
 
9
18
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
10
19
  const require = createRequire(import.meta.url)
11
20
 
12
- 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
21
+ // Keep in sync with DistNpmPackage in packages/core/src/installation/dist.ts.
22
+ const packageBase = "@neevcode/neev"
23
+
24
+ const platformMap = {
25
+ darwin: "darwin",
26
+ linux: "linux",
27
+ win32: "windows",
28
+ }
29
+ const archMap = {
30
+ x64: "x64",
31
+ arm64: "arm64",
32
+ arm: "arm",
33
+ }
34
+
35
+ const platform = platformMap[os.platform()] || os.platform()
36
+ const arch = archMap[os.arch()] || os.arch()
37
+ const base = `${packageBase}-${platform}-${arch}`
38
+ const binaryName = platform === "windows" ? "opencode.exe" : "opencode"
39
+
40
+ function supportsAvx2() {
41
+ if (arch !== "x64") return false
42
+
43
+ if (platform === "linux") {
44
+ try {
45
+ return /(^|\s)avx2(\s|$)/i.test(fs.readFileSync("/proc/cpuinfo", "utf8"))
46
+ } catch {
47
+ return false
48
+ }
28
49
  }
29
50
 
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
51
+ if (platform === "darwin") {
52
+ try {
53
+ const result = childProcess.spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], {
54
+ encoding: "utf8",
55
+ timeout: 1500,
56
+ })
57
+ if (result.status !== 0) return false
58
+ return (result.stdout || "").trim() === "1"
59
+ } catch {
60
+ return false
61
+ }
45
62
  }
46
63
 
47
- return { platform, arch }
64
+ return false
48
65
  }
49
66
 
50
- function findBinary() {
51
- const { platform, arch } = detectPlatformAndArch()
52
- const packageName = `@neevcode/neev-${platform}-${arch}`
53
- const binaryName = platform === "windows" ? "opencode.exe" : "opencode"
67
+ function isMusl() {
68
+ try {
69
+ if (fs.existsSync("/etc/alpine-release")) return true
70
+ } catch {
71
+ // ignore
72
+ }
54
73
 
55
74
  try {
56
- // Use require.resolve to find the package
57
- const packageJsonPath = require.resolve(`${packageName}/package.json`)
58
- const packageDir = path.dirname(packageJsonPath)
59
- const binaryPath = path.join(packageDir, "bin", binaryName)
75
+ const result = childProcess.spawnSync("ldd", ["--version"], { encoding: "utf8" })
76
+ const text = ((result.stdout || "") + (result.stderr || "")).toLowerCase()
77
+ if (text.includes("musl")) return true
78
+ } catch {
79
+ // ignore
80
+ }
60
81
 
61
- if (!fs.existsSync(binaryPath)) {
62
- throw new Error(`Binary not found at ${binaryPath}`)
82
+ return false
83
+ }
84
+
85
+ function candidateNames() {
86
+ const baseline = arch === "x64" && !supportsAvx2()
87
+
88
+ if (platform === "linux") {
89
+ if (isMusl()) {
90
+ if (arch === "x64") {
91
+ if (baseline) return [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base]
92
+ return [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]
93
+ }
94
+ return [`${base}-musl`, base]
63
95
  }
64
96
 
65
- return { binaryPath, binaryName }
66
- } catch (error) {
67
- throw new Error(`Could not find package ${packageName}: ${error.message}`, { cause: error })
97
+ if (arch === "x64") {
98
+ if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
99
+ return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
100
+ }
101
+ return [base, `${base}-musl`]
68
102
  }
69
- }
70
103
 
71
- async function main() {
72
- try {
73
- if (os.platform() === "win32") {
74
- // On Windows, the .exe is already included in the package and bin field points to it
75
- // No postinstall setup needed
76
- console.log("Windows detected: binary setup not needed (using packaged .exe)")
77
- return
78
- }
104
+ if (arch === "x64") {
105
+ if (baseline) return [`${base}-baseline`, base]
106
+ return [base, `${base}-baseline`]
107
+ }
108
+ return [base]
109
+ }
79
110
 
80
- // On non-Windows platforms, just verify the binary package exists
81
- // Don't replace the wrapper script - it handles binary execution
82
- const { binaryPath } = findBinary()
83
- const target = path.join(__dirname, "bin", ".opencode")
84
- if (fs.existsSync(target)) fs.unlinkSync(target)
111
+ function findBinary() {
112
+ const names = candidateNames()
113
+ for (const name of names) {
85
114
  try {
86
- fs.linkSync(binaryPath, target)
115
+ const packageJsonPath = require.resolve(`${name}/package.json`)
116
+ const binaryPath = path.join(path.dirname(packageJsonPath), "bin", binaryName)
117
+ if (fs.existsSync(binaryPath)) return binaryPath
87
118
  } catch {
88
- fs.copyFileSync(binaryPath, target)
119
+ continue
89
120
  }
90
- fs.chmodSync(target, 0o755)
91
- } catch (error) {
92
- console.error("Failed to setup opencode binary:", error.message)
93
- process.exit(1)
94
121
  }
122
+ throw new Error(`none of ${names.join(", ")} are installed`)
123
+ }
124
+
125
+ function main() {
126
+ if (os.platform() === "win32") {
127
+ // On Windows the bin field points at the wrapper and the .exe ships in the
128
+ // platform package — nothing to link.
129
+ return
130
+ }
131
+
132
+ const binaryPath = findBinary()
133
+ const target = path.join(__dirname, "bin", ".opencode")
134
+ if (fs.existsSync(target)) fs.unlinkSync(target)
135
+ try {
136
+ fs.linkSync(binaryPath, target)
137
+ } catch {
138
+ fs.copyFileSync(binaryPath, target)
139
+ }
140
+ fs.chmodSync(target, 0o755)
95
141
  }
96
142
 
97
143
  try {
98
- void main()
144
+ main()
99
145
  } catch (error) {
100
- console.error("Postinstall script error:", error.message)
101
- process.exit(0)
146
+ console.warn(`neev postinstall: skipping binary link (${error.message}); the CLI will resolve it at runtime`)
102
147
  }
148
+ process.exit(0)