@hcmai/cli 0.3.2 → 0.3.4
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/dist/index.js +278 -26
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2034,6 +2034,11 @@ async function readStdin() {
|
|
|
2034
2034
|
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
2035
2035
|
return Buffer.concat(chunks).toString("utf-8").trim();
|
|
2036
2036
|
}
|
|
2037
|
+
async function readSecretFromStdin() {
|
|
2038
|
+
const chunks = [];
|
|
2039
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
2040
|
+
return Buffer.concat(chunks).toString("utf-8").replace(/\r?\n$/, "");
|
|
2041
|
+
}
|
|
2037
2042
|
async function promptConfirm(question) {
|
|
2038
2043
|
const ans = await promptText(question);
|
|
2039
2044
|
return /^y(es)?$/i.test(ans.trim());
|
|
@@ -2281,9 +2286,9 @@ async function loginCommand(args) {
|
|
|
2281
2286
|
} catch (e) {
|
|
2282
2287
|
const err = e;
|
|
2283
2288
|
if (err.isAxiosError) {
|
|
2284
|
-
const { fromAxiosError:
|
|
2289
|
+
const { fromAxiosError: fromAxiosError18 } = await import("@hcmai/sdk");
|
|
2285
2290
|
exitWithError(
|
|
2286
|
-
|
|
2291
|
+
fromAxiosError18(
|
|
2287
2292
|
e,
|
|
2288
2293
|
envName
|
|
2289
2294
|
)
|
|
@@ -2498,13 +2503,13 @@ async function envRemove(name, args) {
|
|
|
2498
2503
|
}
|
|
2499
2504
|
}
|
|
2500
2505
|
const ids = await listIdentities(name);
|
|
2501
|
-
const
|
|
2506
|
+
const failed2 = [];
|
|
2502
2507
|
for (const id of ids) {
|
|
2503
2508
|
try {
|
|
2504
2509
|
await TokenStore2.forIdentity(id).clear();
|
|
2505
2510
|
await deleteIdentity(id);
|
|
2506
2511
|
} catch (err) {
|
|
2507
|
-
|
|
2512
|
+
failed2.push(id);
|
|
2508
2513
|
process.stderr.write(
|
|
2509
2514
|
`[hcm] event=identity_cleanup_failed identity=${id} reason=${JSON.stringify(String(err.message))}
|
|
2510
2515
|
`
|
|
@@ -2517,9 +2522,9 @@ async function envRemove(name, args) {
|
|
|
2517
2522
|
g.activeEnv = "default";
|
|
2518
2523
|
await saveGlobalConfig2(g);
|
|
2519
2524
|
}
|
|
2520
|
-
const removedCount = ids.length -
|
|
2525
|
+
const removedCount = ids.length - failed2.length;
|
|
2521
2526
|
const noun = (n) => n === 1 ? "identity" : "identities";
|
|
2522
|
-
const failPart =
|
|
2527
|
+
const failPart = failed2.length > 0 ? `, ${failed2.length} ${noun(failed2.length)} failed: ${failed2.join(", ")}` : "";
|
|
2523
2528
|
exitOk(`\u2705 env '${name}' removed (${removedCount} ${noun(removedCount)} removed${failPart})`);
|
|
2524
2529
|
} catch (e) {
|
|
2525
2530
|
exitWithError(e);
|
|
@@ -7563,9 +7568,15 @@ async function identityRemove(name) {
|
|
|
7563
7568
|
}
|
|
7564
7569
|
}
|
|
7565
7570
|
|
|
7571
|
+
// src/commands/delivery-action-policy.ts
|
|
7572
|
+
init_auth_guard();
|
|
7573
|
+
import {
|
|
7574
|
+
HcmClient as HcmClient17,
|
|
7575
|
+
formatObject as formatObject17
|
|
7576
|
+
} from "@hcmai/sdk";
|
|
7577
|
+
|
|
7566
7578
|
// src/commands/delivery.ts
|
|
7567
7579
|
import { createHash as createHash5 } from "crypto";
|
|
7568
|
-
import { formatObject as formatObject17 } from "@hcmai/sdk";
|
|
7569
7580
|
var APPROVAL_BYPASS_FLAGS = /* @__PURE__ */ new Set(["-y", "--yes", "--force", "--auto-approve"]);
|
|
7570
7581
|
var CREDENTIAL_FLAGS = /* @__PURE__ */ new Set([
|
|
7571
7582
|
"--password",
|
|
@@ -7581,18 +7592,22 @@ var GUARDED_EXECUTOR_REASON_CODES = /* @__PURE__ */ new Set([
|
|
|
7581
7592
|
"record-create",
|
|
7582
7593
|
"record-update",
|
|
7583
7594
|
"cache-mutation",
|
|
7584
|
-
"setting-write"
|
|
7595
|
+
"setting-write",
|
|
7596
|
+
"credential-reset",
|
|
7597
|
+
"action-write"
|
|
7585
7598
|
]);
|
|
7586
|
-
function assessDeliveryCommand(inputArgv) {
|
|
7599
|
+
function assessDeliveryCommand(inputArgv, options = {}) {
|
|
7587
7600
|
const argv = inputArgv[0] === "--" ? inputArgv.slice(1) : [...inputArgv];
|
|
7588
7601
|
const commandSha256 = sha2565(JSON.stringify(argv));
|
|
7589
7602
|
const name = argv[0] ?? "";
|
|
7590
7603
|
const subcommand = argv[1] && !argv[1].startsWith("-") ? argv[1] : void 0;
|
|
7591
7604
|
const envAlias = flagValue(argv, "--env");
|
|
7592
7605
|
const identityAlias = flagValue(argv, "--as");
|
|
7593
|
-
const sensitiveFlags = [
|
|
7594
|
-
|
|
7595
|
-
|
|
7606
|
+
const sensitiveFlags = [
|
|
7607
|
+
...new Set([...PAYLOAD_FLAGS, ...CREDENTIAL_FLAGS].filter((flag) => hasFlag(argv, flag)))
|
|
7608
|
+
];
|
|
7609
|
+
const target = summarizeTarget(argv, options.actionResolution);
|
|
7610
|
+
let classification = classify(argv, options.actionResolution);
|
|
7596
7611
|
const invalidPayload = payloadError(argv);
|
|
7597
7612
|
if (invalidPayload) {
|
|
7598
7613
|
classification = forbidden("invalid-input", "JSON payload \u65E0\u6548\uFF0C\u4E0D\u80FD\u8FDB\u5165\u4EFB\u4F55\u6267\u884C\u8DEF\u5F84\u3002");
|
|
@@ -7613,8 +7628,8 @@ function assessDeliveryCommand(inputArgv) {
|
|
|
7613
7628
|
const allowed = classification.risk === "R0" || classification.risk === "R1";
|
|
7614
7629
|
return {
|
|
7615
7630
|
schemaVersion: 1,
|
|
7616
|
-
contractVersion: "2026-08-
|
|
7617
|
-
assessmentId: sha2565(`2026-08-
|
|
7631
|
+
contractVersion: "2026-08-29",
|
|
7632
|
+
assessmentId: sha2565(`2026-08-29
|
|
7618
7633
|
${commandSha256}`).slice(0, 24),
|
|
7619
7634
|
commandSha256,
|
|
7620
7635
|
command: { name: name || "(empty)", ...subcommand ? { subcommand } : {} },
|
|
@@ -7634,16 +7649,25 @@ ${commandSha256}`).slice(0, 24),
|
|
|
7634
7649
|
}
|
|
7635
7650
|
};
|
|
7636
7651
|
}
|
|
7637
|
-
function
|
|
7638
|
-
const assessment = assessDeliveryCommand(argv);
|
|
7639
|
-
process.stdout.write(formatObject17(assessment, { format: args.output ?? "json" }) + "\n");
|
|
7640
|
-
}
|
|
7641
|
-
function classify(argv) {
|
|
7652
|
+
function classify(argv, actionResolution) {
|
|
7642
7653
|
const name = argv[0] ?? "";
|
|
7643
7654
|
const subcommand = argv[1] ?? "";
|
|
7644
7655
|
if (argv.some((arg) => APPROVAL_BYPASS_FLAGS.has(flagName(arg)))) {
|
|
7645
7656
|
return forbidden("approval-bypass", "\u547D\u4EE4\u5305\u542B\u8DF3\u8FC7\u786E\u8BA4\u7684\u65D7\u6807\uFF0C\u987E\u95EE\u4EA4\u4ED8\u9762\u4E0D\u6267\u884C\u3002");
|
|
7646
7657
|
}
|
|
7658
|
+
if (name === "user" && subcommand === "reset-password") {
|
|
7659
|
+
const nonStdinCredential = argv.some((arg) => {
|
|
7660
|
+
const flag = flagName(arg);
|
|
7661
|
+
return CREDENTIAL_FLAGS.has(flag) && flag !== "--password-stdin";
|
|
7662
|
+
});
|
|
7663
|
+
if (nonStdinCredential || !argv.includes("--password-stdin")) {
|
|
7664
|
+
return forbidden(
|
|
7665
|
+
"credential-governance",
|
|
7666
|
+
"\u7528\u6237\u5BC6\u7801\u91CD\u7F6E\u53EA\u80FD\u901A\u8FC7 --password-stdin \u8FDB\u5165\u53D7\u63A7\u51ED\u636E\u6D41\u7A0B\u3002"
|
|
7667
|
+
);
|
|
7668
|
+
}
|
|
7669
|
+
return guarded("credential-write", "credential-reset");
|
|
7670
|
+
}
|
|
7647
7671
|
if (argv.some((arg) => CREDENTIAL_FLAGS.has(flagName(arg)))) {
|
|
7648
7672
|
return forbidden("credential-governance", "\u547D\u4EE4\u643A\u5E26\u8EAB\u4EFD\u51ED\u636E\u53C2\u6570\uFF0C\u5FC5\u987B\u8F6C\u4EA4\u8EAB\u4EFD\u6CBB\u7406\u6D41\u7A0B\u3002");
|
|
7649
7673
|
}
|
|
@@ -7726,9 +7750,15 @@ function classify(argv) {
|
|
|
7726
7750
|
if (name === "upload") return guarded("tenant-write", "document-upload");
|
|
7727
7751
|
if (name === "download") return direct("R1", "managed-local-write", "document-download");
|
|
7728
7752
|
if (name === "action") {
|
|
7753
|
+
if (actionResolution?.status === "resolved") {
|
|
7754
|
+
return classifyAction(actionResolution.policy);
|
|
7755
|
+
}
|
|
7756
|
+
if (actionResolution?.status === "failed") {
|
|
7757
|
+
return forbidden(actionResolution.reasonCode, actionResolution.reason);
|
|
7758
|
+
}
|
|
7729
7759
|
return forbidden(
|
|
7730
7760
|
"action-effect-unclassified",
|
|
7731
|
-
"
|
|
7761
|
+
"\u5C1A\u672A\u8BFB\u53D6 Core Action \u98CE\u63A7\u58F0\u660E\uFF0C\u4E0D\u80FD\u6309\u540D\u79F0\u731C\u6D4B\u540E\u653E\u884C\u3002"
|
|
7732
7762
|
);
|
|
7733
7763
|
}
|
|
7734
7764
|
if (name === "delete" || name === "meta" && subcommand === "delete") {
|
|
@@ -7745,14 +7775,19 @@ function classify(argv) {
|
|
|
7745
7775
|
}
|
|
7746
7776
|
return forbidden("unknown-command", "\u672A\u77E5\u547D\u4EE4\u6309\u6700\u9AD8\u98CE\u9669\u5173\u95ED\u3002");
|
|
7747
7777
|
}
|
|
7748
|
-
function summarizeTarget(argv) {
|
|
7778
|
+
function summarizeTarget(argv, actionResolution) {
|
|
7749
7779
|
const name = argv[0] ?? "";
|
|
7750
7780
|
const subcommand = argv[1] ?? "";
|
|
7751
7781
|
const target = {};
|
|
7752
7782
|
if (["query", "describe", "create", "update", "delete"].includes(name) && subcommand) {
|
|
7753
7783
|
target.model = subcommand;
|
|
7754
7784
|
}
|
|
7755
|
-
if (name === "action" && subcommand)
|
|
7785
|
+
if (name === "action" && subcommand) {
|
|
7786
|
+
target.action = subcommand;
|
|
7787
|
+
if (actionResolution?.status === "resolved") {
|
|
7788
|
+
target.actionPolicy = { ...actionResolution.policy };
|
|
7789
|
+
}
|
|
7790
|
+
}
|
|
7756
7791
|
if (name === "skills" && argv[2] && !argv[2].startsWith("-")) target.skill = argv[2];
|
|
7757
7792
|
if (name === "meta" && argv[2] && !argv[2].startsWith("-")) target.path = argv[2];
|
|
7758
7793
|
if (name === "cache" && argv[2] && !argv[2].startsWith("-")) {
|
|
@@ -7765,7 +7800,14 @@ function summarizeTarget(argv) {
|
|
|
7765
7800
|
if (settingKeys.length > 0) target.settingKeys = settingKeys;
|
|
7766
7801
|
}
|
|
7767
7802
|
const id = flagValue(argv, "--id");
|
|
7768
|
-
if (
|
|
7803
|
+
if (name === "user" && subcommand === "reset-password") {
|
|
7804
|
+
if (id) target.userIdSha256 = sha2565(id);
|
|
7805
|
+
const username = flagValue(argv, "--username");
|
|
7806
|
+
if (username) target.usernameSha256 = sha2565(username);
|
|
7807
|
+
target.forceChangeOnNextLogin = !hasFlag(argv, "--no-force-change");
|
|
7808
|
+
} else if (id) {
|
|
7809
|
+
target.recordIdSha256 = sha2565(id);
|
|
7810
|
+
}
|
|
7769
7811
|
for (const flag of PAYLOAD_FLAGS) {
|
|
7770
7812
|
const raw = flagValue(argv, flag);
|
|
7771
7813
|
if (!raw) continue;
|
|
@@ -7809,6 +7851,18 @@ function guarded(effect, reasonCode) {
|
|
|
7809
7851
|
reason: "\u666E\u901A\u526F\u4F5C\u7528\u64CD\u4F5C\uFF1B\u53EA\u5141\u8BB8\u5728 controlled \u9879\u76EE\u4E2D\u901A\u8FC7 delivery prepare + delivery execute \u5355\u6B21\u53D7\u63A7\u6267\u884C\u3002"
|
|
7810
7852
|
};
|
|
7811
7853
|
}
|
|
7854
|
+
function classifyAction(policy) {
|
|
7855
|
+
if (policy.readOnly) {
|
|
7856
|
+
return {
|
|
7857
|
+
risk: "R1",
|
|
7858
|
+
execution: "direct",
|
|
7859
|
+
effect: "remote-read",
|
|
7860
|
+
reasonCode: "action-read-only",
|
|
7861
|
+
reason: "Core \u58F0\u660E\u8BE5 Action \u4E3A\u53EA\u8BFB\uFF0C\u4E0E Moirai \u7684\u53EA\u8BFB Action \u8DEF\u5F84\u4E00\u81F4\uFF0C\u53EF\u76F4\u63A5\u6267\u884C\u3002"
|
|
7862
|
+
};
|
|
7863
|
+
}
|
|
7864
|
+
return guarded("tenant-write", "action-write");
|
|
7865
|
+
}
|
|
7812
7866
|
function forbidden(reasonCode, reason) {
|
|
7813
7867
|
return { risk: "R3", execution: "forbidden", effect: reasonCode, reasonCode, reason };
|
|
7814
7868
|
}
|
|
@@ -7861,6 +7915,104 @@ function isPlainObject(value) {
|
|
|
7861
7915
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7862
7916
|
}
|
|
7863
7917
|
|
|
7918
|
+
// src/commands/delivery-action-policy.ts
|
|
7919
|
+
async function assessEffectiveDeliveryCommand(inputArgv, dependencies = {}) {
|
|
7920
|
+
const local = assessDeliveryCommand(inputArgv);
|
|
7921
|
+
if (local.reasonCode !== "action-effect-unclassified") return local;
|
|
7922
|
+
const request = parseActionRequest(inputArgv);
|
|
7923
|
+
if ("status" in request) {
|
|
7924
|
+
return assessDeliveryCommand(inputArgv, { actionResolution: request });
|
|
7925
|
+
}
|
|
7926
|
+
const resolution = await (dependencies.resolveAction ?? resolveCoreAction)(request);
|
|
7927
|
+
return assessDeliveryCommand(inputArgv, { actionResolution: resolution });
|
|
7928
|
+
}
|
|
7929
|
+
async function deliveryAssessCommand(argv, args) {
|
|
7930
|
+
const assessment = await assessEffectiveDeliveryCommand(argv);
|
|
7931
|
+
process.stdout.write(formatObject17(assessment, { format: args.output ?? "json" }) + "\n");
|
|
7932
|
+
}
|
|
7933
|
+
async function resolveCoreAction(request) {
|
|
7934
|
+
try {
|
|
7935
|
+
const auth = await getActiveAuthContextFromCli({
|
|
7936
|
+
env: request.env,
|
|
7937
|
+
as: request.identity,
|
|
7938
|
+
profile: request.profile
|
|
7939
|
+
});
|
|
7940
|
+
const description = await HcmClient17.fromAuthContext(auth).describe(request.model);
|
|
7941
|
+
const matches = description.actions.filter((action2) => matchesRequest(action2, request));
|
|
7942
|
+
if (matches.length === 0) {
|
|
7943
|
+
return failed(
|
|
7944
|
+
"action-metadata-not-found",
|
|
7945
|
+
"Core \u5143\u6570\u636E\u4E2D\u6CA1\u6709\u4E0E\u672C\u6B21 method/scope \u7CBE\u786E\u5339\u914D\u7684 Action\uFF0C\u62D2\u7EDD\u6267\u884C\u3002"
|
|
7946
|
+
);
|
|
7947
|
+
}
|
|
7948
|
+
if (matches.length > 1) {
|
|
7949
|
+
return failed(
|
|
7950
|
+
"action-metadata-ambiguous",
|
|
7951
|
+
"Core \u5143\u6570\u636E\u5B58\u5728\u591A\u4E2A\u4E0E\u672C\u6B21 method/scope \u5339\u914D\u7684 Action\uFF0C\u65E0\u6CD5\u552F\u4E00\u5224\u5B9A\uFF0C\u62D2\u7EDD\u6267\u884C\u3002"
|
|
7952
|
+
);
|
|
7953
|
+
}
|
|
7954
|
+
const action = matches[0];
|
|
7955
|
+
if (typeof action.readOnly !== "boolean") {
|
|
7956
|
+
return failed(
|
|
7957
|
+
"action-readonly-unclassified",
|
|
7958
|
+
"Core \u672A\u8FD4\u56DE Action \u7684 readOnly \u58F0\u660E\uFF0C\u6309\u5B89\u5168\u9ED8\u8BA4\u62D2\u7EDD\u6267\u884C\u3002"
|
|
7959
|
+
);
|
|
7960
|
+
}
|
|
7961
|
+
return {
|
|
7962
|
+
status: "resolved",
|
|
7963
|
+
policy: {
|
|
7964
|
+
scope: action.scope,
|
|
7965
|
+
httpMethod: action.httpMethod.toUpperCase(),
|
|
7966
|
+
readOnly: action.readOnly,
|
|
7967
|
+
...action.source ? { source: action.source } : {}
|
|
7968
|
+
}
|
|
7969
|
+
};
|
|
7970
|
+
} catch {
|
|
7971
|
+
return failed(
|
|
7972
|
+
"action-metadata-unavailable",
|
|
7973
|
+
"\u65E0\u6CD5\u8BFB\u53D6 Core Action \u5143\u6570\u636E\uFF0C\u6309\u5B89\u5168\u9ED8\u8BA4\u62D2\u7EDD\u6267\u884C\u3002"
|
|
7974
|
+
);
|
|
7975
|
+
}
|
|
7976
|
+
}
|
|
7977
|
+
function matchesRequest(action, request) {
|
|
7978
|
+
return action.name === request.action && action.httpMethod?.toUpperCase() === request.httpMethod && action.scope?.toLowerCase() === request.scope;
|
|
7979
|
+
}
|
|
7980
|
+
function parseActionRequest(inputArgv) {
|
|
7981
|
+
const argv = inputArgv[0] === "--" ? inputArgv.slice(1) : [...inputArgv];
|
|
7982
|
+
const spec = argv[1] ?? "";
|
|
7983
|
+
const separator = spec.indexOf(".");
|
|
7984
|
+
if (separator <= 0 || separator === spec.length - 1) {
|
|
7985
|
+
return failed("invalid-action-spec", "Action \u5FC5\u987B\u4F7F\u7528 <Model>.<Action> \u683C\u5F0F\u3002");
|
|
7986
|
+
}
|
|
7987
|
+
const httpMethod = (flagValue2(argv, "--method") ?? "POST").toUpperCase();
|
|
7988
|
+
if (!["GET", "POST", "PUT", "DELETE"].includes(httpMethod)) {
|
|
7989
|
+
return failed("invalid-action-method", "Action method \u5FC5\u987B\u662F GET\u3001POST\u3001PUT \u6216 DELETE\u3002");
|
|
7990
|
+
}
|
|
7991
|
+
const explicitScope = flagValue2(argv, "--scope");
|
|
7992
|
+
const scope = explicitScope ?? (flagValue2(argv, "--id") ? "object" : "class");
|
|
7993
|
+
if (scope !== "class" && scope !== "object") {
|
|
7994
|
+
return failed("invalid-action-scope", "Action scope \u5FC5\u987B\u662F class \u6216 object\u3002");
|
|
7995
|
+
}
|
|
7996
|
+
return {
|
|
7997
|
+
model: spec.slice(0, separator),
|
|
7998
|
+
action: spec.slice(separator + 1),
|
|
7999
|
+
httpMethod,
|
|
8000
|
+
scope,
|
|
8001
|
+
env: flagValue2(argv, "--env"),
|
|
8002
|
+
identity: flagValue2(argv, "--as"),
|
|
8003
|
+
profile: flagValue2(argv, "--profile")
|
|
8004
|
+
};
|
|
8005
|
+
}
|
|
8006
|
+
function failed(reasonCode, reason) {
|
|
8007
|
+
return { status: "failed", reasonCode, reason };
|
|
8008
|
+
}
|
|
8009
|
+
function flagValue2(argv, flag) {
|
|
8010
|
+
const equals = argv.find((arg) => arg.startsWith(`${flag}=`));
|
|
8011
|
+
if (equals) return equals.slice(flag.length + 1);
|
|
8012
|
+
const index = argv.indexOf(flag);
|
|
8013
|
+
return index >= 0 ? argv[index + 1] : void 0;
|
|
8014
|
+
}
|
|
8015
|
+
|
|
7864
8016
|
// src/commands/delivery-execution.ts
|
|
7865
8017
|
import { createHash as createHash6, randomBytes as secureRandomBytes } from "crypto";
|
|
7866
8018
|
import { spawn } from "child_process";
|
|
@@ -7876,7 +8028,7 @@ var PLAN_ID_PATTERN = /^[a-f0-9]{24}$/;
|
|
|
7876
8028
|
async function prepareDeliveryExecution(input) {
|
|
7877
8029
|
const project = await realProject(input.project);
|
|
7878
8030
|
await readProjectMode(project);
|
|
7879
|
-
const assessment =
|
|
8031
|
+
const assessment = await (input.assessCommand ?? assessEffectiveDeliveryCommand)(input.argv);
|
|
7880
8032
|
assertGuardedAssessment(assessment, input.argv);
|
|
7881
8033
|
const ttlSeconds = input.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
7882
8034
|
if (!Number.isInteger(ttlSeconds) || ttlSeconds < MIN_TTL_SECONDS || ttlSeconds > MAX_TTL_SECONDS) {
|
|
@@ -7939,7 +8091,7 @@ async function executeDeliveryPlan(input) {
|
|
|
7939
8091
|
}
|
|
7940
8092
|
if (now.getTime() < createdAt - 5e3) throw invalid4("\u5F53\u524D\u65F6\u95F4\u65E9\u4E8E\u8BA1\u5212\u521B\u5EFA\u65F6\u95F4");
|
|
7941
8093
|
if (now.getTime() > expiresAt) throw invalid4("\u6267\u884C\u8BA1\u5212\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0 prepare");
|
|
7942
|
-
const assessment =
|
|
8094
|
+
const assessment = await (input.assessCommand ?? assessEffectiveDeliveryCommand)(input.argv);
|
|
7943
8095
|
assertGuardedAssessment(assessment, input.argv);
|
|
7944
8096
|
if (canonicalJson(assessment) !== canonicalJson(plan.assessment)) {
|
|
7945
8097
|
throw invalid4("\u5B9E\u9645 argv \u4E0E\u6267\u884C\u8BA1\u5212\u7684\u547D\u4EE4\u6458\u8981\u6216\u98CE\u9669\u4E8B\u5B9E\u4E0D\u4E00\u81F4");
|
|
@@ -8116,6 +8268,32 @@ function assertGuardedAssessment(assessment, argv) {
|
|
|
8116
8268
|
validateSupportedCommandShape(assessment.reasonCode, argv);
|
|
8117
8269
|
}
|
|
8118
8270
|
function validateSupportedCommandShape(reasonCode, argv) {
|
|
8271
|
+
if (reasonCode === "credential-reset") {
|
|
8272
|
+
if (argv[0] !== "user" || argv[1] !== "reset-password") {
|
|
8273
|
+
throw invalid4("credential-reset \u53EA\u652F\u6301 user reset-password");
|
|
8274
|
+
}
|
|
8275
|
+
const userId = optionalFlagValue(argv, "--id");
|
|
8276
|
+
const username = optionalFlagValue(argv, "--username");
|
|
8277
|
+
if (Boolean(userId) === Boolean(username)) {
|
|
8278
|
+
throw invalid4("user reset-password \u5FC5\u987B\u4E14\u53EA\u80FD\u5305\u542B --id \u6216 --username");
|
|
8279
|
+
}
|
|
8280
|
+
if (!argv.includes("--password-stdin")) {
|
|
8281
|
+
throw invalid4("user reset-password \u5FC5\u987B\u5305\u542B\u72EC\u7ACB\u7684 --password-stdin");
|
|
8282
|
+
}
|
|
8283
|
+
if (argv.some(
|
|
8284
|
+
(value) => [
|
|
8285
|
+
"--password",
|
|
8286
|
+
"--new-password",
|
|
8287
|
+
"--client-secret",
|
|
8288
|
+
"--pat",
|
|
8289
|
+
"--new-password-stdin",
|
|
8290
|
+
"--pat-stdin"
|
|
8291
|
+
].includes(value.split("=", 1)[0] ?? "")
|
|
8292
|
+
) || argv.some((value) => value.startsWith("--password-stdin="))) {
|
|
8293
|
+
throw invalid4("user reset-password \u4E0D\u5141\u8BB8\u5728 argv \u4E2D\u643A\u5E26\u660E\u6587\u51ED\u636E");
|
|
8294
|
+
}
|
|
8295
|
+
return;
|
|
8296
|
+
}
|
|
8119
8297
|
if (reasonCode === "record-create") {
|
|
8120
8298
|
requireFlagValue(argv, "--data", "create \u5FC5\u987B\u5305\u542B --data <JSON>");
|
|
8121
8299
|
return;
|
|
@@ -8140,6 +8318,19 @@ function validateSupportedCommandShape(reasonCode, argv) {
|
|
|
8140
8318
|
}
|
|
8141
8319
|
}
|
|
8142
8320
|
}
|
|
8321
|
+
function optionalFlagValue(argv, flag) {
|
|
8322
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
8323
|
+
const value = argv[index];
|
|
8324
|
+
if (value === flag) {
|
|
8325
|
+
const next = argv[index + 1];
|
|
8326
|
+
return next && !next.startsWith("-") ? next : void 0;
|
|
8327
|
+
}
|
|
8328
|
+
if (value?.startsWith(`${flag}=`) && value.length > flag.length + 1) {
|
|
8329
|
+
return value.slice(flag.length + 1);
|
|
8330
|
+
}
|
|
8331
|
+
}
|
|
8332
|
+
return void 0;
|
|
8333
|
+
}
|
|
8143
8334
|
function requireFlagValue(argv, flag, message) {
|
|
8144
8335
|
for (let index = 0; index < argv.length; index += 1) {
|
|
8145
8336
|
const value = argv[index];
|
|
@@ -8318,6 +8509,65 @@ function invalid4(message, cause) {
|
|
|
8318
8509
|
return new CliError20({ code: CliErrorCode19.INVALID_ARGUMENT, message, cause });
|
|
8319
8510
|
}
|
|
8320
8511
|
|
|
8512
|
+
// src/commands/user.ts
|
|
8513
|
+
init_auth_guard();
|
|
8514
|
+
init_exit();
|
|
8515
|
+
import {
|
|
8516
|
+
HcmClient as HcmClient18,
|
|
8517
|
+
adminResetPassword,
|
|
8518
|
+
formatObject as formatObject19,
|
|
8519
|
+
fromAxiosError as fromAxiosError17,
|
|
8520
|
+
CliError as CliError21,
|
|
8521
|
+
CliErrorCode as CliErrorCode20
|
|
8522
|
+
} from "@hcmai/sdk";
|
|
8523
|
+
function buildAdminResetPasswordRequest(args, password) {
|
|
8524
|
+
const hasId = Boolean(args.id);
|
|
8525
|
+
const hasUsername = Boolean(args.username);
|
|
8526
|
+
if (hasId === hasUsername) {
|
|
8527
|
+
throw new CliError21({
|
|
8528
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8529
|
+
message: "--id <uuid> \u4E0E --username <user> \u5FC5\u987B\u4E14\u53EA\u80FD\u63D0\u4F9B\u4E00\u4E2A"
|
|
8530
|
+
});
|
|
8531
|
+
}
|
|
8532
|
+
if (!password) {
|
|
8533
|
+
throw new CliError21({
|
|
8534
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8535
|
+
message: "\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A"
|
|
8536
|
+
});
|
|
8537
|
+
}
|
|
8538
|
+
return {
|
|
8539
|
+
...args.id ? { userId: args.id } : {},
|
|
8540
|
+
...args.username ? { username: args.username } : {},
|
|
8541
|
+
newPassword: password,
|
|
8542
|
+
confirmPassword: password,
|
|
8543
|
+
forceChangeOnNextLogin: args.forceChange !== false
|
|
8544
|
+
};
|
|
8545
|
+
}
|
|
8546
|
+
async function userResetPasswordCommand(args) {
|
|
8547
|
+
try {
|
|
8548
|
+
const password = args.passwordStdin ? await readSecretFromStdin() : await promptPasswordTwice();
|
|
8549
|
+
const request = buildAdminResetPasswordRequest(args, password);
|
|
8550
|
+
const client3 = HcmClient18.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
8551
|
+
const result2 = await adminResetPassword(client3.raw(), request);
|
|
8552
|
+
process.stdout.write(formatObject19(result2, { format: args.output ?? "json" }) + "\n");
|
|
8553
|
+
} catch (cause) {
|
|
8554
|
+
const err = cause;
|
|
8555
|
+
if (err?.isAxiosError) exitWithError(fromAxiosError17(err, args.env));
|
|
8556
|
+
exitWithError(cause);
|
|
8557
|
+
}
|
|
8558
|
+
}
|
|
8559
|
+
async function promptPasswordTwice() {
|
|
8560
|
+
const password = await promptSecret("\u65B0\u5BC6\u7801: ");
|
|
8561
|
+
const confirmation = await promptSecret("\u518D\u6B21\u8F93\u5165\u65B0\u5BC6\u7801: ");
|
|
8562
|
+
if (password !== confirmation) {
|
|
8563
|
+
throw new CliError21({
|
|
8564
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8565
|
+
message: "\u4E24\u6B21\u8F93\u5165\u7684\u65B0\u5BC6\u7801\u4E0D\u4E00\u81F4"
|
|
8566
|
+
});
|
|
8567
|
+
}
|
|
8568
|
+
return password;
|
|
8569
|
+
}
|
|
8570
|
+
|
|
8321
8571
|
// src/startup.ts
|
|
8322
8572
|
function needsLegacyProfileMigration(argv) {
|
|
8323
8573
|
const args = argv.slice(2);
|
|
@@ -8355,8 +8605,10 @@ var identity = program.command("identity").description("\u7BA1\u7406 HCM \u8EAB\
|
|
|
8355
8605
|
identity.command("list").description("\u5217\u51FA identity\uFF08\u9ED8\u8BA4\u5217\u5F53\u524D env\uFF0C--env all \u5217\u5168\u90E8\uFF09").option("--env <name>", '\u8FC7\u6EE4 env\uFF1B\u4F20 "all" \u5217\u5168\u90E8', void 0).action((opts) => identityList(opts));
|
|
8356
8606
|
identity.command("use <name>").description("\u628A identity \u8BBE\u4E3A\u5176 env \u7684 default identity").action((name) => identityUse(name));
|
|
8357
8607
|
identity.command("remove <name>").description("\u5220\u9664 identity\uFF08\u6E05 token + \u82E5\u662F env default \u5219\u6E05\u7A7A\uFF09").action((name) => identityRemove(name));
|
|
8608
|
+
var user = program.command("user").description("\u7BA1\u7406\u79DF\u6237\u7528\u6237\u7684\u4E13\u7528\u51ED\u636E\u6D41\u7A0B");
|
|
8609
|
+
user.command("reset-password").description("\u7531 admin.system \u5B89\u5168\u91CD\u7F6E\u7528\u6237\u5BC6\u7801\uFF0C\u5E76\u4F7F\u65E2\u6709\u4F1A\u8BDD\u5931\u6548").option("--id <uuid>", "\u76EE\u6807\u7528\u6237 ID\uFF08\u4E0E --username \u4E8C\u9009\u4E00\uFF09").option("--username <user>", "\u76EE\u6807\u7528\u6237\u540D\uFF08\u4E0E --id \u4E8C\u9009\u4E00\uFF09").option("--password-stdin", "\u4ECE\u6807\u51C6\u8F93\u5165\u8BFB\u53D6\u65B0\u5BC6\u7801\uFF08Agent/\u53D7\u63A7\u4EA4\u4ED8\u5FC5\u987B\u4F7F\u7528\uFF09").option("--no-force-change", "\u4E0B\u6B21\u767B\u5F55\u4E0D\u5F3A\u5236\u6539\u5BC6\uFF08\u4EC5\u9650\u5DF2\u6279\u51C6\u7684\u9694\u79BB\u6D4B\u8BD5\u73AF\u5883\uFF09").option("--env <name>", "\u4E34\u65F6\u5207\u73AF\u5883\uFF08\u8986\u76D6 activeEnv\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--as <identity>", "\u4E34\u65F6\u6362\u8EAB\u4EFD\uFF08\u5FC5\u987B\u5177\u5907 admin.system\uFF09").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((opts) => userResetPasswordCommand(opts));
|
|
8358
8610
|
var delivery = program.command("delivery").description("\u987E\u95EE\u4EA4\u4ED8\u547D\u4EE4\u7684\u98CE\u9669\u8BC4\u4F30\u4E0E\u4E00\u6B21\u6027\u53D7\u63A7\u6267\u884C\u5408\u540C");
|
|
8359
|
-
delivery.command("assess").description("\
|
|
8611
|
+
delivery.command("assess").description("\u8BC4\u4F30\u4E00\u6B21 HCM CLI argv\uFF1BAction \u98CE\u63A7\u58F0\u660E\u8BFB\u53D6\u81EA\u76EE\u6807 Core\uFF0C\u7528 -- \u5206\u9694\u88AB\u8BC4\u4F30\u547D\u4EE4").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").allowUnknownOption(true).argument("<command...>", "\u88AB\u8BC4\u4F30\u7684 HCM \u5B50\u547D\u4EE4\u4E0E\u53C2\u6570\uFF0C\u4E0D\u5305\u542B hcm \u672C\u8EAB").action((command, opts) => deliveryAssessCommand(command, opts));
|
|
8360
8612
|
delivery.command("prepare").description("\u628A\u53D7\u652F\u6301\u7684 R2 argv \u4E0E\u9501\u3001\u8FD0\u884C\u65F6\u548C\u53D8\u66F4/\u56DE\u6EDA\u8BF4\u660E\u7ED1\u5B9A\u4E3A\u77ED\u65F6\u6267\u884C\u8BA1\u5212").requiredOption("--change-ref <file>", "\u9879\u76EE work/ \u6216 decisions/ \u4E0B\u7684\u53D8\u66F4\u8BF4\u660E").requiredOption("--rollback-ref <file>", "\u9879\u76EE work/ \u6216 decisions/ \u4E0B\u7684\u56DE\u6EDA\u8BF4\u660E").requiredOption("--evidence-dir <dir>", "\u9879\u76EE evidence/ \u4E0B\u7684\u6536\u636E\u76EE\u5F55").option("--project <dir>", "HCM \u987E\u95EE\u9879\u76EE\u6839\u76EE\u5F55", ".").option("--ttl-seconds <n>", "\u6709\u6548\u671F\u79D2\u6570\uFF0860-3600\uFF09", "900").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").allowUnknownOption(true).argument("<command...>", "\u88AB\u7ED1\u5B9A\u7684 R2 HCM \u5B50\u547D\u4EE4\u4E0E\u53C2\u6570\uFF0C\u4E0D\u5305\u542B hcm \u672C\u8EAB").action((command, opts) => deliveryPrepareCommand(command, opts));
|
|
8361
8613
|
delivery.command("execute <planId>").description("\u9010\u6B21\u6279\u51C6\u540E\u6D88\u8D39\u77ED\u65F6\u8BA1\u5212\uFF0C\u5E76\u6267\u884C\u4E00\u6B21\u4E0E\u8BA1\u5212\u5B8C\u5168\u76F8\u540C\u7684 R2 argv").option("--project <dir>", "HCM \u987E\u95EE\u9879\u76EE\u6839\u76EE\u5F55", ".").option("--output <fmt>", "\u6536\u636E\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").allowUnknownOption(true).argument("<command...>", "\u4E0E prepare \u5B8C\u5168\u76F8\u540C\u7684 R2 HCM \u5B50\u547D\u4EE4\u4E0E\u53C2\u6570").action((planId, command, opts) => deliveryExecuteCommand(planId, command, opts));
|
|
8362
8614
|
program.command("query <Model>").description("\u67E5\u8BE2 Model \u5217\u8868\u6570\u636E\uFF08\u901A\u8FC7 ModelQueryDsl JSON \u8868\u8FBE\u8FC7\u6EE4/\u6392\u5E8F/\u5206\u9875\uFF09").option(
|