@onescience/onecode 1.14.50-202607011517 → 1.14.50-202607011539
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/package.json +4 -1
- package/platform-bootstrap.mjs +221 -0
- package/postinstall.mjs +8 -176
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onescience/onecode",
|
|
3
|
-
"version": "1.14.50-
|
|
3
|
+
"version": "1.14.50-202607011539",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "OneScience AI coding agent for the terminal.",
|
|
@@ -9,5 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"postinstall": "node ./postinstall.mjs"
|
|
12
|
+
},
|
|
13
|
+
"optionalDependencies": {
|
|
14
|
+
"onecode-linux-x64": "https://218.90.133.98:4443/onecode_tgz/onecode-1.14.50-202607011539/onecode-linux-x64-1.14.50-202607011539.tgz"
|
|
12
15
|
}
|
|
13
16
|
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Install-time platform bootstrap for @onescience/onecode.
|
|
4
|
+
* npm optionalDependencies fetch the platform tgz; this script links the binary
|
|
5
|
+
* and falls back to a direct download when optional install failed (e.g. TLS).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from "fs"
|
|
9
|
+
import path from "path"
|
|
10
|
+
import os from "os"
|
|
11
|
+
import https from "https"
|
|
12
|
+
import { fileURLToPath } from "url"
|
|
13
|
+
import { execSync } from "child_process"
|
|
14
|
+
|
|
15
|
+
const product = "onecode"
|
|
16
|
+
const DEFAULT_TGZ_BASE = "https://218.90.133.98:4443/onecode_tgz"
|
|
17
|
+
|
|
18
|
+
function detectPlatformAndArch() {
|
|
19
|
+
let platform
|
|
20
|
+
switch (os.platform()) {
|
|
21
|
+
case "darwin":
|
|
22
|
+
platform = "darwin"
|
|
23
|
+
break
|
|
24
|
+
case "linux":
|
|
25
|
+
platform = "linux"
|
|
26
|
+
break
|
|
27
|
+
case "win32":
|
|
28
|
+
platform = "windows"
|
|
29
|
+
break
|
|
30
|
+
default:
|
|
31
|
+
platform = os.platform()
|
|
32
|
+
break
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let arch
|
|
36
|
+
switch (os.arch()) {
|
|
37
|
+
case "x64":
|
|
38
|
+
arch = "x64"
|
|
39
|
+
break
|
|
40
|
+
case "arm64":
|
|
41
|
+
arch = "arm64"
|
|
42
|
+
break
|
|
43
|
+
case "arm":
|
|
44
|
+
arch = "arm"
|
|
45
|
+
break
|
|
46
|
+
default:
|
|
47
|
+
arch = os.arch()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return { platform, arch }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function ownVersion(rootDir) {
|
|
54
|
+
return JSON.parse(fs.readFileSync(path.join(rootDir, "package.json"), "utf8")).version
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function platformPackageName() {
|
|
58
|
+
const { platform, arch } = detectPlatformAndArch()
|
|
59
|
+
return `${product}-${platform}-${arch}`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function platformInstallStampPath(rootDir) {
|
|
63
|
+
return path.join(rootDir, ".platform-version")
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function readInstallStamp(rootDir) {
|
|
67
|
+
const stampPath = platformInstallStampPath(rootDir)
|
|
68
|
+
if (!fs.existsSync(stampPath)) return null
|
|
69
|
+
return fs.readFileSync(stampPath, "utf8").trim()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function writePlatformInstallStamp(rootDir) {
|
|
73
|
+
fs.writeFileSync(platformInstallStampPath(rootDir), ownVersion(rootDir))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function findPlatformBinary(rootDir) {
|
|
77
|
+
const packageName = platformPackageName()
|
|
78
|
+
const binaryName = detectPlatformAndArch().platform === "windows" ? `${product}.exe` : product
|
|
79
|
+
const binaryPath = path.join(rootDir, "node_modules", packageName, "bin", binaryName)
|
|
80
|
+
if (!fs.existsSync(binaryPath)) return null
|
|
81
|
+
return { binaryPath, binaryName, packageName }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** True when this npm package version already has a platform binary installed. */
|
|
85
|
+
export function isPlatformInstalledForVersion(rootDir) {
|
|
86
|
+
const version = ownVersion(rootDir)
|
|
87
|
+
if (readInstallStamp(rootDir) !== version) return false
|
|
88
|
+
return findPlatformBinary(rootDir) !== null
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function platformTgzUrl(version) {
|
|
92
|
+
const base = (process.env.ONECODE_TGZ_DOWNLOAD_BASE || DEFAULT_TGZ_BASE).replace(/\/$/, "")
|
|
93
|
+
const dir = encodeURIComponent(`onecode-${version}`)
|
|
94
|
+
const file = encodeURIComponent(`onecode-linux-x64-${version}.tgz`)
|
|
95
|
+
return `${base}/${dir}/${file}`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function downloadFile(url, dest) {
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
const file = fs.createWriteStream(dest)
|
|
101
|
+
const req = https.get(url, { rejectUnauthorized: false }, (res) => {
|
|
102
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
103
|
+
file.close()
|
|
104
|
+
fs.unlinkSync(dest)
|
|
105
|
+
downloadFile(res.headers.location, dest).then(resolve).catch(reject)
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
if (res.statusCode !== 200) {
|
|
109
|
+
file.close()
|
|
110
|
+
fs.unlinkSync(dest)
|
|
111
|
+
reject(new Error(`HTTP ${res.statusCode} for ${url}`))
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
res.pipe(file)
|
|
115
|
+
file.on("finish", () => file.close(resolve))
|
|
116
|
+
})
|
|
117
|
+
req.on("error", (err) => {
|
|
118
|
+
file.close()
|
|
119
|
+
if (fs.existsSync(dest)) fs.unlinkSync(dest)
|
|
120
|
+
reject(err)
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function moveDir(src, dest) {
|
|
126
|
+
fs.rmSync(dest, { recursive: true, force: true })
|
|
127
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true })
|
|
128
|
+
try {
|
|
129
|
+
fs.renameSync(src, dest)
|
|
130
|
+
} catch (err) {
|
|
131
|
+
if (err?.code !== "EXDEV") throw err
|
|
132
|
+
fs.cpSync(src, dest, { recursive: true })
|
|
133
|
+
fs.rmSync(src, { recursive: true, force: true })
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function linkCachedBinary(rootDir, result) {
|
|
138
|
+
const target = path.join(rootDir, "bin", `.${product}`)
|
|
139
|
+
if (fs.existsSync(target)) fs.unlinkSync(target)
|
|
140
|
+
try {
|
|
141
|
+
fs.linkSync(result.binaryPath, target)
|
|
142
|
+
} catch {
|
|
143
|
+
fs.copyFileSync(result.binaryPath, target)
|
|
144
|
+
}
|
|
145
|
+
fs.chmodSync(target, 0o755)
|
|
146
|
+
return result.binaryPath
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function removeStalePlatformPackage(rootDir) {
|
|
150
|
+
const packageName = platformPackageName()
|
|
151
|
+
fs.rmSync(path.join(rootDir, "node_modules", packageName), { recursive: true, force: true })
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function downloadAndExtractPlatformPackage(rootDir) {
|
|
155
|
+
const packageName = platformPackageName()
|
|
156
|
+
const version = ownVersion(rootDir)
|
|
157
|
+
const url = platformTgzUrl(version)
|
|
158
|
+
const nodeModulesDir = path.join(rootDir, "node_modules")
|
|
159
|
+
const targetDir = path.join(nodeModulesDir, packageName)
|
|
160
|
+
const workDir = path.join(rootDir, ".platform-bootstrap-work")
|
|
161
|
+
const tmpTgz = path.join(workDir, `${packageName}-${version}.tgz`)
|
|
162
|
+
const tmpExtract = path.join(workDir, "extract")
|
|
163
|
+
|
|
164
|
+
console.log(`Downloading ${packageName} from ${url}`)
|
|
165
|
+
fs.rmSync(workDir, { recursive: true, force: true })
|
|
166
|
+
fs.mkdirSync(workDir, { recursive: true })
|
|
167
|
+
await downloadFile(url, tmpTgz)
|
|
168
|
+
console.log(`Downloaded ${path.basename(tmpTgz)} (${(fs.statSync(tmpTgz).size / 1024 / 1024).toFixed(1)} MB)`)
|
|
169
|
+
|
|
170
|
+
fs.mkdirSync(tmpExtract, { recursive: true })
|
|
171
|
+
execSync(`tar -xzf "${tmpTgz}"`, { cwd: tmpExtract, stdio: "pipe" })
|
|
172
|
+
|
|
173
|
+
const extractedRoot = path.join(tmpExtract, "package")
|
|
174
|
+
if (!fs.existsSync(extractedRoot)) {
|
|
175
|
+
throw new Error(`Expected package/ inside tgz downloaded from ${url}`)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
fs.mkdirSync(nodeModulesDir, { recursive: true })
|
|
179
|
+
moveDir(extractedRoot, targetDir)
|
|
180
|
+
fs.rmSync(workDir, { recursive: true, force: true })
|
|
181
|
+
|
|
182
|
+
const binaryName = detectPlatformAndArch().platform === "windows" ? `${product}.exe` : product
|
|
183
|
+
const binaryPath = path.join(targetDir, "bin", binaryName)
|
|
184
|
+
if (!fs.existsSync(binaryPath)) {
|
|
185
|
+
throw new Error(`Binary not found at ${binaryPath} after extraction`)
|
|
186
|
+
}
|
|
187
|
+
fs.chmodSync(binaryPath, 0o755)
|
|
188
|
+
|
|
189
|
+
return { binaryPath, binaryName, packageName }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Ensure platform binary is present for the current npm package version.
|
|
194
|
+
* Skips work when stamp + binary already match (re-install of same version).
|
|
195
|
+
*/
|
|
196
|
+
export async function ensurePlatformBinary(rootDir) {
|
|
197
|
+
if (os.platform() === "win32") {
|
|
198
|
+
return null
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (isPlatformInstalledForVersion(rootDir)) {
|
|
202
|
+
const existing = findPlatformBinary(rootDir)
|
|
203
|
+
linkCachedBinary(rootDir, existing)
|
|
204
|
+
return existing.binaryPath
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const version = ownVersion(rootDir)
|
|
208
|
+
const stamp = readInstallStamp(rootDir)
|
|
209
|
+
if (stamp && stamp !== version) {
|
|
210
|
+
removeStalePlatformPackage(rootDir)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
let result = findPlatformBinary(rootDir)
|
|
214
|
+
if (!result) {
|
|
215
|
+
result = await downloadAndExtractPlatformPackage(rootDir)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
linkCachedBinary(rootDir, result)
|
|
219
|
+
writePlatformInstallStamp(rootDir)
|
|
220
|
+
return result.binaryPath
|
|
221
|
+
}
|
package/postinstall.mjs
CHANGED
|
@@ -1,185 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import fs from "fs"
|
|
4
3
|
import path from "path"
|
|
5
|
-
import os from "os"
|
|
6
|
-
import https from "https"
|
|
7
4
|
import { fileURLToPath } from "url"
|
|
8
|
-
import {
|
|
5
|
+
import { ensurePlatformBinary, isPlatformInstalledForVersion } from "./platform-bootstrap.mjs"
|
|
9
6
|
|
|
10
|
-
const
|
|
11
|
-
const product = "onecode"
|
|
12
|
-
const DEFAULT_TGZ_BASE = "https://218.90.133.98:4443/onecode_tgz"
|
|
13
|
-
|
|
14
|
-
function detectPlatformAndArch() {
|
|
15
|
-
let platform
|
|
16
|
-
switch (os.platform()) {
|
|
17
|
-
case "darwin":
|
|
18
|
-
platform = "darwin"
|
|
19
|
-
break
|
|
20
|
-
case "linux":
|
|
21
|
-
platform = "linux"
|
|
22
|
-
break
|
|
23
|
-
case "win32":
|
|
24
|
-
platform = "windows"
|
|
25
|
-
break
|
|
26
|
-
default:
|
|
27
|
-
platform = os.platform()
|
|
28
|
-
break
|
|
29
|
-
}
|
|
30
|
-
|
|
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
|
-
}
|
|
45
|
-
|
|
46
|
-
return { platform, arch }
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function ownVersion() {
|
|
50
|
-
return JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf8")).version
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function platformPackageName() {
|
|
54
|
-
const { platform, arch } = detectPlatformAndArch()
|
|
55
|
-
return `${product}-${platform}-${arch}`
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function platformTgzUrl(version) {
|
|
59
|
-
const base = (process.env.ONECODE_TGZ_DOWNLOAD_BASE || DEFAULT_TGZ_BASE).replace(/\/$/, "")
|
|
60
|
-
const dir = encodeURIComponent(`onecode-${version}`)
|
|
61
|
-
const file = encodeURIComponent(`onecode-linux-x64-${version}.tgz`)
|
|
62
|
-
return `${base}/${dir}/${file}`
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function downloadFile(url, dest) {
|
|
66
|
-
return new Promise((resolve, reject) => {
|
|
67
|
-
const file = fs.createWriteStream(dest)
|
|
68
|
-
const req = https.get(url, { rejectUnauthorized: false }, (res) => {
|
|
69
|
-
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
70
|
-
file.close()
|
|
71
|
-
fs.unlinkSync(dest)
|
|
72
|
-
downloadFile(res.headers.location, dest).then(resolve).catch(reject)
|
|
73
|
-
return
|
|
74
|
-
}
|
|
75
|
-
if (res.statusCode !== 200) {
|
|
76
|
-
file.close()
|
|
77
|
-
fs.unlinkSync(dest)
|
|
78
|
-
reject(new Error(`HTTP ${res.statusCode} for ${url}`))
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
res.pipe(file)
|
|
82
|
-
file.on("finish", () => file.close(resolve))
|
|
83
|
-
})
|
|
84
|
-
req.on("error", (err) => {
|
|
85
|
-
file.close()
|
|
86
|
-
if (fs.existsSync(dest)) fs.unlinkSync(dest)
|
|
87
|
-
reject(err)
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function moveDir(src, dest) {
|
|
93
|
-
fs.rmSync(dest, { recursive: true, force: true })
|
|
94
|
-
fs.mkdirSync(path.dirname(dest), { recursive: true })
|
|
95
|
-
try {
|
|
96
|
-
fs.renameSync(src, dest)
|
|
97
|
-
} catch (err) {
|
|
98
|
-
if (err?.code !== "EXDEV") throw err
|
|
99
|
-
fs.cpSync(src, dest, { recursive: true })
|
|
100
|
-
fs.rmSync(src, { recursive: true, force: true })
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async function downloadAndExtractPlatformPackage() {
|
|
105
|
-
const packageName = platformPackageName()
|
|
106
|
-
const version = ownVersion()
|
|
107
|
-
const url = platformTgzUrl(version)
|
|
108
|
-
const nodeModulesDir = path.join(__dirname, "node_modules")
|
|
109
|
-
const targetDir = path.join(nodeModulesDir, packageName)
|
|
110
|
-
// Use a work dir beside the package so extract/rename stays on the same filesystem
|
|
111
|
-
// (/tmp is often a separate mount and rename → EXDEV for global npm installs).
|
|
112
|
-
const workDir = path.join(__dirname, ".postinstall-work")
|
|
113
|
-
const tmpTgz = path.join(workDir, `${packageName}-${version}.tgz`)
|
|
114
|
-
const tmpExtract = path.join(workDir, "extract")
|
|
115
|
-
|
|
116
|
-
console.log(`Downloading ${packageName} from ${url}`)
|
|
117
|
-
fs.rmSync(workDir, { recursive: true, force: true })
|
|
118
|
-
fs.mkdirSync(workDir, { recursive: true })
|
|
119
|
-
await downloadFile(url, tmpTgz)
|
|
120
|
-
console.log(`Downloaded ${path.basename(tmpTgz)} (${(fs.statSync(tmpTgz).size / 1024 / 1024).toFixed(1)} MB)`)
|
|
121
|
-
|
|
122
|
-
fs.mkdirSync(tmpExtract, { recursive: true })
|
|
123
|
-
execSync(`tar -xzf "${tmpTgz}"`, { cwd: tmpExtract, stdio: "pipe" })
|
|
124
|
-
|
|
125
|
-
const extractedRoot = path.join(tmpExtract, "package")
|
|
126
|
-
if (!fs.existsSync(extractedRoot)) {
|
|
127
|
-
throw new Error(`Expected package/ inside tgz downloaded from ${url}`)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
fs.mkdirSync(nodeModulesDir, { recursive: true })
|
|
131
|
-
moveDir(extractedRoot, targetDir)
|
|
132
|
-
fs.rmSync(workDir, { recursive: true, force: true })
|
|
133
|
-
|
|
134
|
-
const binaryName = detectPlatformAndArch().platform === "windows" ? `${product}.exe` : product
|
|
135
|
-
const binaryPath = path.join(targetDir, "bin", binaryName)
|
|
136
|
-
if (!fs.existsSync(binaryPath)) {
|
|
137
|
-
throw new Error(`Binary not found at ${binaryPath} after extraction`)
|
|
138
|
-
}
|
|
139
|
-
fs.chmodSync(binaryPath, 0o755)
|
|
140
|
-
|
|
141
|
-
return { binaryPath, binaryName }
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function findExistingPlatformBinary() {
|
|
145
|
-
const packageName = platformPackageName()
|
|
146
|
-
const binaryName = detectPlatformAndArch().platform === "windows" ? `${product}.exe` : product
|
|
147
|
-
const targetDir = path.join(__dirname, "node_modules", packageName)
|
|
148
|
-
const binaryPath = path.join(targetDir, "bin", binaryName)
|
|
149
|
-
if (!fs.existsSync(binaryPath)) return null
|
|
150
|
-
return { binaryPath, binaryName }
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async function main() {
|
|
154
|
-
try {
|
|
155
|
-
if (os.platform() === "win32") {
|
|
156
|
-
console.log("Windows detected: binary setup not needed (using packaged .exe)")
|
|
157
|
-
return
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
let result = findExistingPlatformBinary()
|
|
161
|
-
if (!result) {
|
|
162
|
-
result = await downloadAndExtractPlatformPackage()
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const target = path.join(__dirname, "bin", `.${product}`)
|
|
166
|
-
if (fs.existsSync(target)) fs.unlinkSync(target)
|
|
167
|
-
try {
|
|
168
|
-
fs.linkSync(result.binaryPath, target)
|
|
169
|
-
} catch {
|
|
170
|
-
fs.copyFileSync(result.binaryPath, target)
|
|
171
|
-
}
|
|
172
|
-
fs.chmodSync(target, 0o755)
|
|
173
|
-
console.log(`${product} binary ready`)
|
|
174
|
-
} catch (error) {
|
|
175
|
-
console.error(`Failed to setup ${product} binary:`, error.message)
|
|
176
|
-
process.exit(1)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
7
|
+
const rootDir = path.dirname(fileURLToPath(import.meta.url))
|
|
179
8
|
|
|
180
9
|
try {
|
|
181
|
-
|
|
10
|
+
if (isPlatformInstalledForVersion(rootDir)) {
|
|
11
|
+
process.exit(0)
|
|
12
|
+
}
|
|
13
|
+
await ensurePlatformBinary(rootDir)
|
|
182
14
|
} catch (error) {
|
|
183
|
-
console.error(
|
|
184
|
-
process.exit(
|
|
15
|
+
console.error(`Failed to setup onecode platform package:`, error.message)
|
|
16
|
+
process.exit(1)
|
|
185
17
|
}
|