@lumi-ai-lab/harness-data 0.0.18 → 0.0.20
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 +1 -1
- package/src/commands/doctor.js +5 -3
- package/src/commands/install.js +29 -7
- package/src/commands/update.js +8 -1
- package/src/lib/config.js +1 -1
package/package.json
CHANGED
package/src/commands/doctor.js
CHANGED
|
@@ -61,9 +61,11 @@ export async function collectDoctor(workspace, options = {}) {
|
|
|
61
61
|
const add = (name, ok, detail = "") => checks.push({ name, ok, detail });
|
|
62
62
|
|
|
63
63
|
add("runtime", fs.existsSync(path.join(workspace, "bootstrap", "cli-manifest.json")) && fs.existsSync(path.join(workspace, "agents")), workspace);
|
|
64
|
-
add("wikis/
|
|
65
|
-
add("wikis/
|
|
66
|
-
add("wikis/
|
|
64
|
+
add("wikis/index.md", fs.existsSync(path.join(workspace, "wikis", "index.md")));
|
|
65
|
+
add("wikis/metrics", fs.existsSync(path.join(workspace, "wikis", "metrics")));
|
|
66
|
+
add("wikis/reports", fs.existsSync(path.join(workspace, "wikis", "reports")));
|
|
67
|
+
add("wikis/dims", fs.existsSync(path.join(workspace, "wikis", "dims")));
|
|
68
|
+
add("wikis/rules", fs.existsSync(path.join(workspace, "wikis", "rules")));
|
|
67
69
|
for (const binary of ["data-harness-cli", "qdm-cmr-cli", "qdm-indicators-cli", "cas-cli"]) {
|
|
68
70
|
add(`bin/${binary}`, existsExecutable(path.join(workspace, "bin", binaryName(binary))));
|
|
69
71
|
}
|
package/src/commands/install.js
CHANGED
|
@@ -57,6 +57,21 @@ function cleanupRuntimeBackups(backups) {
|
|
|
57
57
|
for (const item of backups) fs.rmSync(item.backup, { recursive: true, force: true });
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
function mergeRuntimeConfig(runtimeDir, sourceDir) {
|
|
61
|
+
const targetDir = path.join(runtimeDir, "config");
|
|
62
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
63
|
+
for (const file of fs.readdirSync(sourceDir)) {
|
|
64
|
+
const source = path.join(sourceDir, file);
|
|
65
|
+
const target = path.join(targetDir, file);
|
|
66
|
+
const stat = fs.statSync(source);
|
|
67
|
+
if (stat.isDirectory()) {
|
|
68
|
+
if (!fs.existsSync(target)) fs.cpSync(source, target, { recursive: true });
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (file.endsWith(".example") || !fs.existsSync(target)) fs.copyFileSync(source, target);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
60
75
|
export async function installRuntimeBundle(runtimeDir, options = {}) {
|
|
61
76
|
if (!options.force && fs.existsSync(path.join(runtimeDir, "agents")) &&
|
|
62
77
|
fs.existsSync(path.join(runtimeDir, "config")) &&
|
|
@@ -102,7 +117,8 @@ export async function installRuntimeBundle(runtimeDir, options = {}) {
|
|
|
102
117
|
fs.mkdirSync(path.join(stagedRoot, "config"), { recursive: true });
|
|
103
118
|
for (const file of fs.readdirSync(configSource)) fs.copyFileSync(path.join(configSource, file), path.join(stagedRoot, "config", file));
|
|
104
119
|
|
|
105
|
-
for (const name of ["agents", "bootstrap"
|
|
120
|
+
for (const name of ["agents", "bootstrap"]) replaceRuntimePath(runtimeDir, name, stagedRoot, backups);
|
|
121
|
+
mergeRuntimeConfig(runtimeDir, path.join(stagedRoot, "config"));
|
|
106
122
|
cleanupRuntimeBackups(backups);
|
|
107
123
|
} catch (error) {
|
|
108
124
|
restoreRuntimeBackups(backups);
|
|
@@ -179,15 +195,20 @@ async function installWikis(runtimeDir, options = {}) {
|
|
|
179
195
|
|
|
180
196
|
const auto = path.join(runtimeDir, "harness-data-wikis");
|
|
181
197
|
const source = fs.existsSync(auto) ? auto : path.resolve(await ask("请输入 harness-data-wikis 的绝对路径:", options));
|
|
182
|
-
|
|
183
|
-
if (!fs.existsSync(path.join(source, dir))) throw new Error(`harness-data-wikis missing ${dir}/: ${source}`);
|
|
184
|
-
}
|
|
198
|
+
validateLocalWikisSource(source);
|
|
185
199
|
fs.rmSync(target, { recursive: true, force: true });
|
|
186
200
|
fs.cpSync(source, target, { recursive: true });
|
|
187
201
|
ok(`harness-data-wikis 本地路径 ${source}`);
|
|
188
202
|
return { mode: "local-path", source, path: target };
|
|
189
203
|
}
|
|
190
204
|
|
|
205
|
+
export function validateLocalWikisSource(source) {
|
|
206
|
+
if (!fs.existsSync(path.join(source, "index.md"))) throw new Error(`harness-data-wikis missing index.md: ${source}`);
|
|
207
|
+
for (const dir of ["metrics", "reports", "dims", "rules"]) {
|
|
208
|
+
if (!fs.existsSync(path.join(source, dir))) throw new Error(`harness-data-wikis missing ${dir}/: ${source}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
191
212
|
function casConfigDir(runtimeDir) {
|
|
192
213
|
return path.join(runtimeDir, ".qdm-auth", "cas");
|
|
193
214
|
}
|
|
@@ -239,9 +260,10 @@ export function printDoctorSummary(doctor, options = {}) {
|
|
|
239
260
|
const warnings = doctor.checks.filter((check) => !check.ok && nonBlocking(check));
|
|
240
261
|
if (!failed.length) {
|
|
241
262
|
ok("runtime");
|
|
242
|
-
ok("wikis/
|
|
243
|
-
ok("wikis/
|
|
244
|
-
ok("wikis/
|
|
263
|
+
ok("wikis/metrics");
|
|
264
|
+
ok("wikis/reports");
|
|
265
|
+
ok("wikis/dims");
|
|
266
|
+
ok("wikis/rules");
|
|
245
267
|
ok("4 个 CLI");
|
|
246
268
|
ok("本地配置");
|
|
247
269
|
ok("CAS 凭证");
|
package/src/commands/update.js
CHANGED
|
@@ -11,10 +11,15 @@ import { resolveLatestTool } from "../lib/tool-release.js";
|
|
|
11
11
|
import { protocolFromUrl, runGitWithProtocol } from "../lib/git-auth.js";
|
|
12
12
|
import { buildAndCheck, installRuntimeBundle, printDoctorSummary } from "./install.js";
|
|
13
13
|
import { collectDoctor } from "./doctor.js";
|
|
14
|
+
import { writeLocalConfig } from "../lib/config.js";
|
|
14
15
|
import { action, blank, header, ok, shortSha, skip, step, warn } from "../lib/log.js";
|
|
15
16
|
|
|
16
17
|
export function isNonBlockingUpdateDoctorCheck(check) {
|
|
17
|
-
return check.name === "Agent hook" ||
|
|
18
|
+
return check.name === "Agent hook" ||
|
|
19
|
+
check.name.startsWith("Agent hook .") ||
|
|
20
|
+
check.name === "CAS credentials file" ||
|
|
21
|
+
check.name === "CMR token" ||
|
|
22
|
+
check.name === "Indicators token";
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
async function npmLatest() {
|
|
@@ -187,6 +192,8 @@ export async function updateCommand(options = {}) {
|
|
|
187
192
|
|
|
188
193
|
step(6, 6, "安装校验");
|
|
189
194
|
if (changed) {
|
|
195
|
+
writeLocalConfig(runtimeDir, { overwrite: true });
|
|
196
|
+
ok("本地配置已刷新");
|
|
190
197
|
const doctor = await collectDoctor(runtimeDir, trackingOptions);
|
|
191
198
|
printDoctorSummary(doctor, { nonBlocking: isNonBlockingUpdateDoctorCheck });
|
|
192
199
|
if (doctor.checks.some((check) => !check.ok && !isNonBlockingUpdateDoctorCheck(check))) throw new Error("doctor failed; update is incomplete");
|
package/src/lib/config.js
CHANGED
|
@@ -31,7 +31,7 @@ export function writeLocalConfig(workspace, options = {}) {
|
|
|
31
31
|
}
|
|
32
32
|
const bin = (name) => path.join(workspace, "bin", binaryName(name)).replaceAll("\\", "/");
|
|
33
33
|
const casConfigDir = path.join(workspace, ".qdm-auth", "cas").replaceAll("\\", "/");
|
|
34
|
-
fs.writeFileSync(harness, `paths:\n
|
|
34
|
+
fs.writeFileSync(harness, `paths:\n knowledge: wikis\n\ncli:\n qdm_cmr_cli: ${bin("qdm-cmr-cli")}\n qdm_indicators_cli: ${bin("qdm-indicators-cli")}\n qdm_cas_cli: ${bin("cas-cli")}\n`);
|
|
35
35
|
fs.writeFileSync(env, `export QDM_CMR_CLI="${bin("qdm-cmr-cli")}"\nexport QDM_INDICATORS_CLI="${bin("qdm-indicators-cli")}"\nexport QDM_CAS_CLI="${bin("cas-cli")}"\nexport QDM_CAS_CONFIG_DIR="${casConfigDir}"\n`);
|
|
36
36
|
}
|
|
37
37
|
|