railwise-ai 1.2.30 → 1.2.32
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.
- package/bin/railwise +9 -1
- package/package.json +10 -11
- package/postinstall.mjs +181 -87
package/bin/railwise
CHANGED
|
@@ -160,7 +160,15 @@ function findBinary(startDir) {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
function findVendor() {
|
|
164
|
+
const root = path.resolve(scriptDir, "..")
|
|
165
|
+
for (const name of names) {
|
|
166
|
+
const candidate = path.join(root, "vendor", name, "bin", binary)
|
|
167
|
+
if (fs.existsSync(candidate)) return candidate
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const resolved = findBinary(scriptDir) || findVendor()
|
|
164
172
|
if (!resolved) {
|
|
165
173
|
// Fallback: run from source via bun for local development
|
|
166
174
|
const srcEntry = path.resolve(scriptDir, "..", "src", "index.ts")
|
package/package.json
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "railwise-ai",
|
|
3
3
|
"bin": {
|
|
4
|
-
"railwise": "./bin/railwise"
|
|
5
|
-
"rw": "./bin/railwise"
|
|
4
|
+
"railwise": "./bin/railwise"
|
|
6
5
|
},
|
|
7
6
|
"scripts": {
|
|
8
7
|
"postinstall": "node ./postinstall.mjs"
|
|
9
8
|
},
|
|
10
|
-
"version": "1.2.
|
|
9
|
+
"version": "1.2.32",
|
|
11
10
|
"license": "MIT",
|
|
12
11
|
"repository": {
|
|
13
12
|
"type": "git",
|
|
14
|
-
"url": "https://github.com/railwise-cn/RAILWISE-CLI"
|
|
13
|
+
"url": "git+https://github.com/railwise-cn/RAILWISE-CLI.git"
|
|
15
14
|
},
|
|
16
15
|
"optionalDependencies": {
|
|
17
|
-
"railwise-
|
|
18
|
-
"railwise-
|
|
19
|
-
"railwise-
|
|
20
|
-
"railwise-linux-
|
|
21
|
-
"railwise-
|
|
22
|
-
"railwise-
|
|
23
|
-
"railwise-linux-x64": "1.2.
|
|
16
|
+
"railwise-linux-arm64": "1.2.32",
|
|
17
|
+
"railwise-darwin-x64": "1.2.32",
|
|
18
|
+
"railwise-windows-x64": "1.2.32",
|
|
19
|
+
"railwise-linux-x64": "1.2.32",
|
|
20
|
+
"railwise-linux-x64-baseline": "1.2.32",
|
|
21
|
+
"railwise-darwin-arm64": "1.2.32",
|
|
22
|
+
"railwise-linux-x64-baseline-musl": "1.2.32"
|
|
24
23
|
}
|
|
25
24
|
}
|
package/postinstall.mjs
CHANGED
|
@@ -1,125 +1,219 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import fs from "fs"
|
|
4
|
-
import path from "path"
|
|
5
4
|
import os from "os"
|
|
6
|
-
import
|
|
5
|
+
import path from "path"
|
|
6
|
+
import { spawnSync } from "child_process"
|
|
7
7
|
import { createRequire } from "module"
|
|
8
|
+
import { fileURLToPath } from "url"
|
|
8
9
|
|
|
9
10
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
10
11
|
const require = createRequire(import.meta.url)
|
|
12
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf8"))
|
|
13
|
+
|
|
14
|
+
function platform() {
|
|
15
|
+
if (os.platform() === "darwin") return "darwin"
|
|
16
|
+
if (os.platform() === "linux") return "linux"
|
|
17
|
+
if (os.platform() === "win32") return "windows"
|
|
18
|
+
return os.platform()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function arch() {
|
|
22
|
+
if (os.arch() === "x64") return "x64"
|
|
23
|
+
if (os.arch() === "arm64") return "arm64"
|
|
24
|
+
if (os.arch() === "arm") return "arm"
|
|
25
|
+
return os.arch()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const system = platform()
|
|
29
|
+
const cpu = arch()
|
|
30
|
+
const base = `railwise-${system}-${cpu}`
|
|
31
|
+
const binary = system === "windows" ? "railwise.exe" : "railwise"
|
|
11
32
|
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
break
|
|
33
|
+
function supportsAvx2() {
|
|
34
|
+
if (cpu !== "x64") return false
|
|
35
|
+
|
|
36
|
+
if (system === "linux") {
|
|
37
|
+
if (!fs.existsSync("/proc/cpuinfo")) return false
|
|
38
|
+
return /(^|\s)avx2(\s|$)/i.test(fs.readFileSync("/proc/cpuinfo", "utf8"))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (system === "darwin") {
|
|
42
|
+
const result = spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], {
|
|
43
|
+
encoding: "utf8",
|
|
44
|
+
timeout: 1500,
|
|
45
|
+
})
|
|
46
|
+
if (result.status !== 0) return false
|
|
47
|
+
return (result.stdout || "").trim() === "1"
|
|
28
48
|
}
|
|
29
49
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
default:
|
|
43
|
-
arch = os.arch()
|
|
44
|
-
break
|
|
50
|
+
if (system === "windows") {
|
|
51
|
+
const cmd =
|
|
52
|
+
'(Add-Type -MemberDefinition "[DllImport(""kernel32.dll"")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);" -Name Kernel32 -Namespace Win32 -PassThru)::IsProcessorFeaturePresent(40)'
|
|
53
|
+
return ["powershell.exe", "pwsh.exe", "pwsh", "powershell"].some((exe) => {
|
|
54
|
+
const result = spawnSync(exe, ["-NoProfile", "-NonInteractive", "-Command", cmd], {
|
|
55
|
+
encoding: "utf8",
|
|
56
|
+
timeout: 3000,
|
|
57
|
+
windowsHide: true,
|
|
58
|
+
})
|
|
59
|
+
if (result.status !== 0) return false
|
|
60
|
+
return ["true", "1"].includes((result.stdout || "").trim().toLowerCase())
|
|
61
|
+
})
|
|
45
62
|
}
|
|
46
63
|
|
|
47
|
-
return
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function musl() {
|
|
68
|
+
if (system !== "linux") return false
|
|
69
|
+
if (fs.existsSync("/etc/alpine-release")) return true
|
|
70
|
+
const result = spawnSync("ldd", ["--version"], { encoding: "utf8" })
|
|
71
|
+
return `${result.stdout || ""}${result.stderr || ""}`.toLowerCase().includes("musl")
|
|
48
72
|
}
|
|
49
73
|
|
|
50
|
-
function
|
|
51
|
-
const
|
|
52
|
-
const packageName = `railwise-${platform}-${arch}`
|
|
53
|
-
const binaryName = platform === "windows" ? "railwise.exe" : "railwise"
|
|
74
|
+
function names() {
|
|
75
|
+
const baseline = cpu === "x64" && !supportsAvx2()
|
|
54
76
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
77
|
+
if (system === "linux") {
|
|
78
|
+
if (musl()) {
|
|
79
|
+
if (cpu === "x64") {
|
|
80
|
+
if (baseline) return [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base]
|
|
81
|
+
return [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]
|
|
82
|
+
}
|
|
83
|
+
return [`${base}-musl`, base]
|
|
84
|
+
}
|
|
60
85
|
|
|
61
|
-
if (
|
|
62
|
-
|
|
86
|
+
if (cpu === "x64") {
|
|
87
|
+
if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
|
|
88
|
+
return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
|
|
63
89
|
}
|
|
90
|
+
return [base, `${base}-musl`]
|
|
91
|
+
}
|
|
64
92
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
93
|
+
if (cpu === "x64") {
|
|
94
|
+
if (baseline) return [`${base}-baseline`, base]
|
|
95
|
+
return [base, `${base}-baseline`]
|
|
68
96
|
}
|
|
97
|
+
return [base]
|
|
69
98
|
}
|
|
70
99
|
|
|
71
|
-
function
|
|
72
|
-
const
|
|
73
|
-
const
|
|
100
|
+
function optional(name) {
|
|
101
|
+
const file = require.resolve(`${name}/package.json`)
|
|
102
|
+
const dir = path.dirname(file)
|
|
103
|
+
const found = path.join(dir, "bin", binary)
|
|
104
|
+
if (!fs.existsSync(found)) throw new Error(`Binary not found at ${found}`)
|
|
105
|
+
return found
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function vendor(name) {
|
|
109
|
+
return path.join(__dirname, "vendor", name, "bin", binary)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function run(exe, args) {
|
|
113
|
+
const result = spawnSync(exe, args, { stdio: "inherit", windowsHide: true })
|
|
114
|
+
if (result.error) throw result.error
|
|
115
|
+
if (result.status !== 0) throw new Error(`${exe} exited with ${result.status}`)
|
|
116
|
+
}
|
|
74
117
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
118
|
+
function quote(value) {
|
|
119
|
+
return `'${value.replace(/'/g, "''")}'`
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function extract(file, dir) {
|
|
123
|
+
if (file.endsWith(".tar.gz")) {
|
|
124
|
+
run("tar", ["-xzf", file, "-C", dir])
|
|
125
|
+
return
|
|
78
126
|
}
|
|
79
127
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
128
|
+
if (system === "windows") {
|
|
129
|
+
const cmd = `Expand-Archive -Path ${quote(file)} -DestinationPath ${quote(dir)} -Force`
|
|
130
|
+
const exe = ["powershell.exe", "pwsh.exe", "pwsh", "powershell"].find((item) => {
|
|
131
|
+
const result = spawnSync(item, ["-NoProfile", "-NonInteractive", "-Command", "$PSVersionTable.PSVersion"], {
|
|
132
|
+
stdio: "ignore",
|
|
133
|
+
windowsHide: true,
|
|
134
|
+
})
|
|
135
|
+
return result.status === 0
|
|
136
|
+
})
|
|
137
|
+
if (!exe) throw new Error("PowerShell is required to extract the Windows binary fallback")
|
|
138
|
+
run(exe, ["-NoProfile", "-NonInteractive", "-Command", cmd])
|
|
139
|
+
return
|
|
83
140
|
}
|
|
84
141
|
|
|
85
|
-
|
|
142
|
+
run("unzip", ["-oq", file, "-d", dir])
|
|
86
143
|
}
|
|
87
144
|
|
|
88
|
-
function
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
145
|
+
function timeout() {
|
|
146
|
+
const value = Number(process.env.RAILWISE_DOWNLOAD_TIMEOUT_MS || 60000)
|
|
147
|
+
if (Number.isFinite(value) && value > 0) return value
|
|
148
|
+
return 60000
|
|
149
|
+
}
|
|
93
150
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
151
|
+
async function download(name) {
|
|
152
|
+
const ext = system === "linux" ? ".tar.gz" : ".zip"
|
|
153
|
+
const asset = `${name}${ext}`
|
|
154
|
+
const base = (
|
|
155
|
+
process.env.RAILWISE_RELEASE_BASE_URL ||
|
|
156
|
+
`https://github.com/railwise-cn/RAILWISE-CLI/releases/download/v${pkg.version}`
|
|
157
|
+
).replace(/\/+$/, "")
|
|
158
|
+
const url = `${base}/${asset}`
|
|
159
|
+
const controller = new AbortController()
|
|
160
|
+
const timer = setTimeout(() => controller.abort(), timeout())
|
|
161
|
+
console.log(`Downloading ${asset} from ${base}`)
|
|
162
|
+
|
|
163
|
+
const tmp = path.join(os.tmpdir(), `${asset}.${process.pid}`)
|
|
164
|
+
const dir = path.join(__dirname, "vendor", name, "bin")
|
|
165
|
+
try {
|
|
166
|
+
const res = await fetch(url, {
|
|
167
|
+
signal: controller.signal,
|
|
168
|
+
headers: { "user-agent": `railwise-postinstall/${pkg.version}` },
|
|
169
|
+
})
|
|
170
|
+
if (!res.ok) throw new Error(`Download failed for ${asset}: ${res.status} ${res.statusText}`)
|
|
171
|
+
|
|
172
|
+
fs.rmSync(path.dirname(dir), { recursive: true, force: true })
|
|
173
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
174
|
+
fs.writeFileSync(tmp, Buffer.from(await res.arrayBuffer()))
|
|
175
|
+
extract(tmp, dir)
|
|
176
|
+
} finally {
|
|
177
|
+
clearTimeout(timer)
|
|
178
|
+
fs.rmSync(tmp, { force: true })
|
|
97
179
|
}
|
|
180
|
+
|
|
181
|
+
const found = vendor(name)
|
|
182
|
+
if (!fs.existsSync(found)) throw new Error(`Downloaded asset did not contain ${binary}`)
|
|
183
|
+
if (system !== "windows") fs.chmodSync(found, 0o755)
|
|
184
|
+
return found
|
|
98
185
|
}
|
|
99
186
|
|
|
100
187
|
async function main() {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return
|
|
188
|
+
const items = names()
|
|
189
|
+
const installed = items.flatMap((name) => {
|
|
190
|
+
try {
|
|
191
|
+
return [optional(name)]
|
|
192
|
+
} catch {
|
|
193
|
+
return []
|
|
107
194
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
console.log(`Platform binary verified at: ${binaryPath}`)
|
|
113
|
-
console.log("Wrapper script will handle binary execution")
|
|
114
|
-
} catch (error) {
|
|
115
|
-
console.error("Failed to setup railwise binary:", error.message)
|
|
116
|
-
process.exit(1)
|
|
195
|
+
})[0]
|
|
196
|
+
if (installed) {
|
|
197
|
+
console.log(`Platform binary verified at: ${installed}`)
|
|
198
|
+
return
|
|
117
199
|
}
|
|
118
|
-
}
|
|
119
200
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
201
|
+
const found = await items.reduce(async (prev, name) => {
|
|
202
|
+
const value = await prev
|
|
203
|
+
if (value) return value
|
|
204
|
+
try {
|
|
205
|
+
return await download(name)
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.warn(`Could not install fallback binary ${name}: ${error instanceof Error ? error.message : String(error)}`)
|
|
208
|
+
return undefined
|
|
209
|
+
}
|
|
210
|
+
}, Promise.resolve(undefined))
|
|
211
|
+
|
|
212
|
+
if (!found) throw new Error(`Could not install a RAILWISE binary for ${system}/${cpu}`)
|
|
213
|
+
console.log(`Platform binary downloaded to: ${found}`)
|
|
125
214
|
}
|
|
215
|
+
|
|
216
|
+
main().catch((error) => {
|
|
217
|
+
console.error("Failed to setup railwise binary:", error instanceof Error ? error.message : String(error))
|
|
218
|
+
process.exit(1)
|
|
219
|
+
})
|