@lumi-ai-lab/harness-data 0.0.22 → 0.0.23
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/README.md +8 -0
- package/package.json +1 -1
- package/src/cli.js +6 -3
- package/src/commands/auth.js +34 -0
- package/src/commands/install.js +9 -5
- package/src/lib/exec.js +3 -1
package/README.md
CHANGED
|
@@ -32,6 +32,14 @@ Update an existing runtime interactively:
|
|
|
32
32
|
npx @lumi-ai-lab/harness-data update
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Reconfigure CAS credentials after an account/password change or after `.qdm-auth` was deleted:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx @lumi-ai-lab/harness-data auth --dir /path/to/runtime
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The command recreates `.qdm-auth/cas`, stores the new encrypted CAS credentials, refreshes the CMR, Indicators, and SQL tokens, and validates all three tokens.
|
|
42
|
+
|
|
35
43
|
Diagnose a runtime:
|
|
36
44
|
|
|
37
45
|
```bash
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -2,8 +2,9 @@ import { installCommand } from "./commands/install.js";
|
|
|
2
2
|
import { updateCommand } from "./commands/update.js";
|
|
3
3
|
import { doctorCommand } from "./commands/doctor.js";
|
|
4
4
|
import { versionCommand } from "./commands/version.js";
|
|
5
|
+
import { authCommand } from "./commands/auth.js";
|
|
5
6
|
|
|
6
|
-
const commands = new Set(["install", "update", "doctor", "version"]);
|
|
7
|
+
const commands = new Set(["install", "update", "auth", "doctor", "version"]);
|
|
7
8
|
|
|
8
9
|
function parse(argv) {
|
|
9
10
|
const args = argv.slice(2);
|
|
@@ -31,17 +32,19 @@ export async function main(argv) {
|
|
|
31
32
|
const { command, options, unknown } = parse(argv);
|
|
32
33
|
if (command === "install") return installCommand(options);
|
|
33
34
|
if (command === "update") return updateCommand(options);
|
|
35
|
+
if (command === "auth") return authCommand(options);
|
|
34
36
|
if (command === "doctor") return doctorCommand(options);
|
|
35
37
|
if (command === "version") return versionCommand(options);
|
|
36
|
-
console.log(`Usage: harness-data <install|update|doctor|version> [options]
|
|
38
|
+
console.log(`Usage: harness-data <install|update|auth|doctor|version> [options]
|
|
37
39
|
|
|
38
40
|
Commands:
|
|
39
41
|
install Install a Harness Data runtime in the current directory
|
|
40
42
|
update Interactively check and apply runtime, CLI, and wikis updates
|
|
43
|
+
auth Configure CAS credentials and refresh access tokens
|
|
41
44
|
doctor Diagnose workspace CLI, config, auth, index, and Agent hooks
|
|
42
45
|
version Print installer, repository, wikis, and manifest versions
|
|
43
46
|
|
|
44
|
-
Install options:
|
|
47
|
+
Install and auth options:
|
|
45
48
|
--dir PATH Runtime directory (default: current directory)
|
|
46
49
|
--agent NAME claude, codex, pi, openclaw, hermes, both, or all
|
|
47
50
|
--github-token TOKEN GitHub token for private Release assets
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { findWorkspaceDir } from "../lib/paths.js";
|
|
4
|
+
import { packageVersion } from "../lib/package.js";
|
|
5
|
+
import { binaryName } from "../lib/platform.js";
|
|
6
|
+
import { blank, header, ok, step } from "../lib/log.js";
|
|
7
|
+
import { configureTokens, writeCasCredentials } from "./install.js";
|
|
8
|
+
|
|
9
|
+
const requiredBinaries = ["cas-cli", "qdm-cmr-cli", "qdm-indicators-cli", "qdm-sql-cli"];
|
|
10
|
+
|
|
11
|
+
function validateAuthRuntime(runtimeDir) {
|
|
12
|
+
if (!fs.existsSync(runtimeDir)) throw new Error(`runtime directory does not exist: ${runtimeDir}`);
|
|
13
|
+
for (const name of requiredBinaries) {
|
|
14
|
+
const file = path.join(runtimeDir, "bin", binaryName(name));
|
|
15
|
+
if (!fs.existsSync(file)) throw new Error(`runtime CLI is missing: ${file}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function authCommand(options = {}) {
|
|
20
|
+
const runtimeDir = findWorkspaceDir(options.dir);
|
|
21
|
+
validateAuthRuntime(runtimeDir);
|
|
22
|
+
header("Harness Data 认证配置", packageVersion(), [`运行目录:${runtimeDir}`]);
|
|
23
|
+
|
|
24
|
+
step(1, 2, "配置 CAS 凭证");
|
|
25
|
+
const casDir = await writeCasCredentials(runtimeDir, options);
|
|
26
|
+
blank();
|
|
27
|
+
|
|
28
|
+
step(2, 2, "刷新并校验访问 Token");
|
|
29
|
+
await configureTokens(runtimeDir, casDir);
|
|
30
|
+
blank();
|
|
31
|
+
|
|
32
|
+
ok("CAS 认证配置完成");
|
|
33
|
+
return { runtimeDir, casDir };
|
|
34
|
+
}
|
package/src/commands/install.js
CHANGED
|
@@ -213,14 +213,18 @@ function casConfigDir(runtimeDir) {
|
|
|
213
213
|
return path.join(runtimeDir, ".qdm-auth", "cas");
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
async function writeCasCredentials(runtimeDir, options = {}) {
|
|
216
|
+
export async function writeCasCredentials(runtimeDir, options = {}) {
|
|
217
217
|
const username = options.casUsername || await ask("CAS 用户名:", options);
|
|
218
218
|
const password = options.casPassword || await askSecret("CAS 密码:", options);
|
|
219
219
|
if (!username || !password) throw new Error("CAS username and password are required");
|
|
220
220
|
const dir = casConfigDir(runtimeDir);
|
|
221
221
|
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
222
222
|
const env = { QDM_CAS_CONFIG_DIR: dir };
|
|
223
|
-
await run(path.join(runtimeDir, "bin", binaryName("cas-cli")), ["config", "set-credentials", "--username", username, "--password", password], {
|
|
223
|
+
await run(path.join(runtimeDir, "bin", binaryName("cas-cli")), ["config", "set-credentials", "--username", username, "--password", password], {
|
|
224
|
+
cwd: runtimeDir,
|
|
225
|
+
env,
|
|
226
|
+
sensitiveArgs: [5]
|
|
227
|
+
});
|
|
224
228
|
ok("CAS 凭证已加密保存到 .qdm-auth/cas/credentials.enc");
|
|
225
229
|
return dir;
|
|
226
230
|
}
|
|
@@ -229,13 +233,13 @@ export async function configureTokens(runtimeDir, casDir) {
|
|
|
229
233
|
const env = { QDM_CAS_CONFIG_DIR: casDir };
|
|
230
234
|
const bin = (name) => path.join(runtimeDir, "bin", binaryName(name));
|
|
231
235
|
const cmrToken = (await run(bin("cas-cli"), ["token", "--app", "cmr"], { cwd: runtimeDir, env })).stdout.trim();
|
|
232
|
-
await run(bin("qdm-cmr-cli"), ["config", "set-token", cmrToken], { cwd: runtimeDir, env });
|
|
236
|
+
await run(bin("qdm-cmr-cli"), ["config", "set-token", cmrToken], { cwd: runtimeDir, env, sensitiveArgs: [2] });
|
|
233
237
|
ok("CMR Token 已配置");
|
|
234
238
|
const indicatorsToken = (await run(bin("cas-cli"), ["token", "--app", "indicators"], { cwd: runtimeDir, env })).stdout.trim();
|
|
235
|
-
await run(bin("qdm-indicators-cli"), ["config", "set-token", indicatorsToken], { cwd: runtimeDir, env });
|
|
239
|
+
await run(bin("qdm-indicators-cli"), ["config", "set-token", indicatorsToken], { cwd: runtimeDir, env, sensitiveArgs: [2] });
|
|
236
240
|
ok("Indicators Token 已配置");
|
|
237
241
|
const sqlToken = (await run(bin("cas-cli"), ["token", "--app", "rtp"], { cwd: runtimeDir, env })).stdout.trim();
|
|
238
|
-
await run(bin("qdm-sql-cli"), ["config", "set-token", sqlToken], { cwd: runtimeDir, env });
|
|
242
|
+
await run(bin("qdm-sql-cli"), ["config", "set-token", sqlToken], { cwd: runtimeDir, env, sensitiveArgs: [2] });
|
|
239
243
|
ok("SQL Token 已配置");
|
|
240
244
|
await run(bin("qdm-cmr-cli"), ["config", "check-token"], { cwd: runtimeDir, env });
|
|
241
245
|
await run(bin("qdm-indicators-cli"), ["config", "check-token"], { cwd: runtimeDir, env });
|
package/src/lib/exec.js
CHANGED
|
@@ -20,7 +20,9 @@ export function run(command, args = [], options = {}) {
|
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
const detail = stderr.trim() || stdout.trim();
|
|
23
|
-
|
|
23
|
+
const sensitiveArgs = new Set(options.sensitiveArgs || []);
|
|
24
|
+
const displayArgs = args.map((arg, index) => sensitiveArgs.has(index) ? "******" : arg);
|
|
25
|
+
reject(new Error(`${command} ${displayArgs.join(" ")} failed${detail ? `: ${detail}` : ""}`));
|
|
24
26
|
});
|
|
25
27
|
});
|
|
26
28
|
}
|