@dptech-corp/bohr-cli 2.6.44 → 2.6.47-preview.964
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/CHANGELOG.md +11 -0
- package/package.json +7 -7
- package/postinstall.js +113 -19
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,16 @@
|
|
|
16
16
|
|
|
17
17
|
## [Unreleased]
|
|
18
18
|
|
|
19
|
+
## [2.6.45] - 2026-08-24
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **`bohr config set openapi_host` 支持 UAT 环境**:白名单新增 `https://open.uat.bohrium.com`。
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **companion 扩展生命周期修复**:配套扩展的发现与管理在特定条件下失效,现已修正。
|
|
28
|
+
|
|
19
29
|
## [2.6.44] - 2026-08-24
|
|
20
30
|
|
|
21
31
|
### Fixed
|
|
@@ -23,6 +33,7 @@
|
|
|
23
33
|
- **`job list`、`job_group list` 与 notebook 六条命令补回机读输出的 `meta.request_id`**:此前重建信封时丢失,出问题无 ID 可追。
|
|
24
34
|
- **不发请求的命令不再编造 `meta.request_id`**:2.6.43 只把字段改可选,六条命令仍在编;dry run 也不再报。
|
|
25
35
|
- **`billing recharge`、`dataset create`、`sandbox template delete` 的机读输出补上 `meta`**:此前完全没有。
|
|
36
|
+
- **配套扩展可完整管理**:CLI 或 npm 安装的 trisol/wenyon 现可被 list/info/verify/pin/remove 识别;remove 需 `--yes`。
|
|
26
37
|
|
|
27
38
|
|
|
28
39
|
## [2.6.43] - 2026-08-23
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dptech-corp/bohr-cli",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.47-preview.964",
|
|
4
4
|
"description": "CLI tool for Bohrium scientific computing platform",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bohr": "run.js"
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"CHANGELOG.md"
|
|
33
33
|
],
|
|
34
34
|
"optionalDependencies": {
|
|
35
|
-
"@dptech-corp/bohr-cli-darwin-
|
|
36
|
-
"@dptech-corp/bohr-cli-darwin-
|
|
37
|
-
"@dptech-corp/bohr-cli-linux-amd64": "2.6.
|
|
38
|
-
"@dptech-corp/bohr-cli-linux-arm64": "2.6.
|
|
39
|
-
"@dptech-corp/bohr-cli-windows-amd64": "2.6.
|
|
40
|
-
"@dptech-corp/bohr-cli-windows-arm64": "2.6.
|
|
35
|
+
"@dptech-corp/bohr-cli-darwin-amd64": "2.6.47-preview.964",
|
|
36
|
+
"@dptech-corp/bohr-cli-darwin-arm64": "2.6.47-preview.964",
|
|
37
|
+
"@dptech-corp/bohr-cli-linux-amd64": "2.6.47-preview.964",
|
|
38
|
+
"@dptech-corp/bohr-cli-linux-arm64": "2.6.47-preview.964",
|
|
39
|
+
"@dptech-corp/bohr-cli-windows-amd64": "2.6.47-preview.964",
|
|
40
|
+
"@dptech-corp/bohr-cli-windows-arm64": "2.6.47-preview.964"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/postinstall.js
CHANGED
|
@@ -14,13 +14,73 @@ const os = require("os");
|
|
|
14
14
|
const crypto = require("crypto");
|
|
15
15
|
|
|
16
16
|
const WENYON_SERVER = "https://wenyon.dp.tech";
|
|
17
|
-
const
|
|
17
|
+
const WENYON_ROOT = path.join(os.homedir(), ".bohr", "tools", "wenyon");
|
|
18
|
+
const INSTALL_DIR = path.join(WENYON_ROOT, "current");
|
|
18
19
|
|
|
19
20
|
// trisol is installed from the trisol manifest protocol (trisol-manifest).
|
|
20
21
|
// BOHR_TRISOL_SERVER / BOHR_TRISOL_CHANNEL let a dev build point at a non-prod
|
|
21
22
|
// env (e.g. https://trisol-dev.dp.tech + channel dev).
|
|
22
23
|
const TRISOL_SERVER = process.env.BOHR_TRISOL_SERVER || "https://trisol.dp.tech";
|
|
23
|
-
const
|
|
24
|
+
const TRISOL_ROOT = path.join(os.homedir(), ".bohr", "tools", "trisol");
|
|
25
|
+
const TRISOL_INSTALL_DIR = path.join(TRISOL_ROOT, "current");
|
|
26
|
+
|
|
27
|
+
function readPinnedHash(toolRoot) {
|
|
28
|
+
const manifestPath = path.join(toolRoot, "manifest.yaml");
|
|
29
|
+
try {
|
|
30
|
+
const text = fs.readFileSync(manifestPath, "utf8");
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(text).pinned_hash || "";
|
|
33
|
+
} catch (_) {
|
|
34
|
+
const match = text.match(/^pinned_hash:\s*(?:"([^"]*)"|'([^']*)'|(\S*))\s*$/m);
|
|
35
|
+
return match ? (match[1] || match[2] || match[3] || "") : "";
|
|
36
|
+
}
|
|
37
|
+
} catch (_) {
|
|
38
|
+
return "";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function writeManagedManifest(toolRoot, { name, version, executable, sha256, pinnedHash = "" }) {
|
|
43
|
+
const manifest = {
|
|
44
|
+
name,
|
|
45
|
+
version: version || "",
|
|
46
|
+
description: "Managed companion CLI installed by bohr",
|
|
47
|
+
binary: path.join("current", executable),
|
|
48
|
+
scopes: [],
|
|
49
|
+
trust: "community",
|
|
50
|
+
billing: "none",
|
|
51
|
+
signature: "",
|
|
52
|
+
public_key: "",
|
|
53
|
+
sha256,
|
|
54
|
+
pinned_hash: pinnedHash,
|
|
55
|
+
};
|
|
56
|
+
fs.mkdirSync(toolRoot, { recursive: true });
|
|
57
|
+
const manifestPath = path.join(toolRoot, "manifest.yaml");
|
|
58
|
+
const temporaryPath = `${manifestPath}.${process.pid}.tmp`;
|
|
59
|
+
fs.writeFileSync(temporaryPath, `${JSON.stringify(manifest, null, 2)}\n`, { mode: 0o600 });
|
|
60
|
+
try {
|
|
61
|
+
try {
|
|
62
|
+
fs.renameSync(temporaryPath, manifestPath);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (process.platform !== "win32" || !["EEXIST", "EPERM"].includes(error.code)) {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
fs.rmSync(manifestPath, { force: true });
|
|
68
|
+
fs.renameSync(temporaryPath, manifestPath);
|
|
69
|
+
}
|
|
70
|
+
} finally {
|
|
71
|
+
fs.rmSync(temporaryPath, { force: true });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function hashFile(filePath) {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
const hash = crypto.createHash("sha256");
|
|
78
|
+
const input = fs.createReadStream(filePath);
|
|
79
|
+
input.on("data", (chunk) => hash.update(chunk));
|
|
80
|
+
input.on("end", () => resolve(hash.digest("hex")));
|
|
81
|
+
input.on("error", reject);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
24
84
|
|
|
25
85
|
function getPlatform() {
|
|
26
86
|
const p = os.platform();
|
|
@@ -113,29 +173,39 @@ async function installTrisol() {
|
|
|
113
173
|
const ext = osName === "windows" ? ".exe" : "";
|
|
114
174
|
const destPath = path.join(TRISOL_INSTALL_DIR, `trisol${ext}`);
|
|
115
175
|
|
|
116
|
-
|
|
176
|
+
let expectedHash;
|
|
177
|
+
try {
|
|
178
|
+
const buf = await get(shaURL);
|
|
179
|
+
expectedHash = buf.toString().trim().split(/\s+/)[0];
|
|
180
|
+
} catch (e) {
|
|
181
|
+
console.error(`[postinstall] trisol: could not fetch sha256 (${e.message}), skipping`);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Retain an existing binary only when both its reported version and its
|
|
186
|
+
// publisher-provided hash match. This also repairs metadata omitted by older
|
|
187
|
+
// postinstall versions without treating the local file as its own authority.
|
|
117
188
|
if (fs.existsSync(destPath)) {
|
|
118
189
|
try {
|
|
119
190
|
const { execFileSync } = require("child_process");
|
|
120
191
|
const out = execFileSync(destPath, ["version"], { encoding: "utf8", timeout: 5000 });
|
|
121
|
-
|
|
192
|
+
const localHash = await hashFile(destPath);
|
|
193
|
+
if (out.includes(version) && localHash === expectedHash) {
|
|
194
|
+
writeManagedManifest(TRISOL_ROOT, {
|
|
195
|
+
name: "trisol",
|
|
196
|
+
version,
|
|
197
|
+
executable: `trisol${ext}`,
|
|
198
|
+
sha256: localHash,
|
|
199
|
+
pinnedHash: readPinnedHash(TRISOL_ROOT),
|
|
200
|
+
});
|
|
122
201
|
console.log(`[postinstall] trisol ${version} already installed`);
|
|
123
202
|
return;
|
|
124
203
|
}
|
|
125
204
|
} catch (_) {
|
|
126
|
-
// version check failed, proceed with install
|
|
205
|
+
// version/hash check failed, proceed with install
|
|
127
206
|
}
|
|
128
207
|
}
|
|
129
208
|
|
|
130
|
-
let expectedHash;
|
|
131
|
-
try {
|
|
132
|
-
const buf = await get(shaURL);
|
|
133
|
-
expectedHash = buf.toString().trim().split(/\s+/)[0];
|
|
134
|
-
} catch (e) {
|
|
135
|
-
console.error(`[postinstall] trisol: could not fetch sha256 (${e.message}), skipping`);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
209
|
console.log(`[postinstall] Installing trisol ${version} (${platform}, variant=bohrium)...`);
|
|
140
210
|
fs.mkdirSync(TRISOL_INSTALL_DIR, { recursive: true });
|
|
141
211
|
const tmpPath = destPath + ".tmp";
|
|
@@ -148,6 +218,12 @@ async function installTrisol() {
|
|
|
148
218
|
}
|
|
149
219
|
fs.chmodSync(tmpPath, 0o755);
|
|
150
220
|
fs.renameSync(tmpPath, destPath);
|
|
221
|
+
writeManagedManifest(TRISOL_ROOT, {
|
|
222
|
+
name: "trisol",
|
|
223
|
+
version,
|
|
224
|
+
executable: `trisol${ext}`,
|
|
225
|
+
sha256: actualHash,
|
|
226
|
+
});
|
|
151
227
|
console.log(`[postinstall] trisol ${version} installed to ${destPath}`);
|
|
152
228
|
} catch (e) {
|
|
153
229
|
try { fs.unlinkSync(tmpPath); } catch (_) {}
|
|
@@ -185,7 +261,15 @@ async function main() {
|
|
|
185
261
|
try {
|
|
186
262
|
const { execFileSync } = require("child_process");
|
|
187
263
|
const out = execFileSync(destPath, ["version"], { encoding: "utf8", timeout: 5000 });
|
|
188
|
-
|
|
264
|
+
const localHash = await hashFile(destPath);
|
|
265
|
+
if (out.includes(meta.version) && (!meta.sha256 || localHash === meta.sha256)) {
|
|
266
|
+
writeManagedManifest(WENYON_ROOT, {
|
|
267
|
+
name: "wenyon",
|
|
268
|
+
version: meta.version,
|
|
269
|
+
executable: `wenyon-cli${ext}`,
|
|
270
|
+
sha256: localHash,
|
|
271
|
+
pinnedHash: readPinnedHash(WENYON_ROOT),
|
|
272
|
+
});
|
|
189
273
|
console.log(`[postinstall] wenyon-cli ${meta.version} already installed`);
|
|
190
274
|
return;
|
|
191
275
|
}
|
|
@@ -210,6 +294,12 @@ async function main() {
|
|
|
210
294
|
|
|
211
295
|
fs.chmodSync(tmpPath, 0o755);
|
|
212
296
|
fs.renameSync(tmpPath, destPath);
|
|
297
|
+
writeManagedManifest(WENYON_ROOT, {
|
|
298
|
+
name: "wenyon",
|
|
299
|
+
version: meta.version,
|
|
300
|
+
executable: `wenyon-cli${ext}`,
|
|
301
|
+
sha256: actualHash,
|
|
302
|
+
});
|
|
213
303
|
console.log(`[postinstall] wenyon-cli ${meta.version || ""} installed to ${destPath}`);
|
|
214
304
|
} catch (e) {
|
|
215
305
|
try { fs.unlinkSync(tmpPath); } catch (_) {}
|
|
@@ -217,7 +307,11 @@ async function main() {
|
|
|
217
307
|
}
|
|
218
308
|
}
|
|
219
309
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
});
|
|
310
|
+
if (require.main === module) {
|
|
311
|
+
main().catch((e) => {
|
|
312
|
+
// postinstall failures must not break npm install
|
|
313
|
+
console.error(`[postinstall] wenyon-cli: ${e.message}`);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
module.exports = { readPinnedHash, writeManagedManifest };
|