@hcmai/cli 0.3.1 → 0.3.3
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 +341 -162
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -112,7 +112,7 @@ __export(attachment_args_exports, {
|
|
|
112
112
|
extractInlineFilePaths: () => extractInlineFilePaths,
|
|
113
113
|
isBareFilePath: () => isBareFilePath
|
|
114
114
|
});
|
|
115
|
-
import * as
|
|
115
|
+
import * as fs2 from "fs";
|
|
116
116
|
import * as os from "os";
|
|
117
117
|
import * as path from "path";
|
|
118
118
|
function extractAtFileTokens(text) {
|
|
@@ -154,7 +154,7 @@ function expandHome(p) {
|
|
|
154
154
|
}
|
|
155
155
|
function isExistingFile(p) {
|
|
156
156
|
try {
|
|
157
|
-
return
|
|
157
|
+
return fs2.statSync(p).isFile();
|
|
158
158
|
} catch {
|
|
159
159
|
return false;
|
|
160
160
|
}
|
|
@@ -1303,7 +1303,7 @@ var init_types = __esm({
|
|
|
1303
1303
|
|
|
1304
1304
|
// src/repl/App.tsx
|
|
1305
1305
|
import { useCallback, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
1306
|
-
import * as
|
|
1306
|
+
import * as fs3 from "fs/promises";
|
|
1307
1307
|
import { Box as Box3, Static, Text as Text3, useApp, useInput as useInput2 } from "ink";
|
|
1308
1308
|
import TextInput from "ink-text-input";
|
|
1309
1309
|
import SelectInput from "ink-select-input";
|
|
@@ -1350,7 +1350,7 @@ function ReplApp(props) {
|
|
|
1350
1350
|
const histIdxRef = useRef2(-1);
|
|
1351
1351
|
const draftRef = useRef2("");
|
|
1352
1352
|
useEffect2(() => {
|
|
1353
|
-
void
|
|
1353
|
+
void fs3.readFile(replHistoryFile(props.env), "utf-8").then((c) => {
|
|
1354
1354
|
historyRef.current = c.split("\n").filter(Boolean);
|
|
1355
1355
|
}).catch(() => {
|
|
1356
1356
|
});
|
|
@@ -1537,7 +1537,7 @@ function ReplApp(props) {
|
|
|
1537
1537
|
}
|
|
1538
1538
|
historyRef.current.push(line);
|
|
1539
1539
|
histIdxRef.current = -1;
|
|
1540
|
-
void
|
|
1540
|
+
void fs3.appendFile(replHistoryFile(props.env), line.replace(/\n/g, " ") + "\n").catch(() => {
|
|
1541
1541
|
});
|
|
1542
1542
|
void (async () => {
|
|
1543
1543
|
const at = extractAtFileTokens(line);
|
|
@@ -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
|
)
|
|
@@ -2398,6 +2403,7 @@ async function envList() {
|
|
|
2398
2403
|
active: name === g.activeEnv ? "*" : " ",
|
|
2399
2404
|
name,
|
|
2400
2405
|
endpoint: cfg.endpoint,
|
|
2406
|
+
frontend: cfg.frontend ?? "(none)",
|
|
2401
2407
|
tenant: cfg.tenantId ?? "1",
|
|
2402
2408
|
identity: cfg.defaultIdentity ?? "(none)"
|
|
2403
2409
|
};
|
|
@@ -2417,7 +2423,8 @@ async function envCurrent() {
|
|
|
2417
2423
|
return;
|
|
2418
2424
|
}
|
|
2419
2425
|
const idName = cfg.defaultIdentity ?? "(none)";
|
|
2420
|
-
|
|
2426
|
+
const frontend = cfg.frontend ? ` frontend=${cfg.frontend}` : "";
|
|
2427
|
+
exitOk(`\u2192 ${g.activeEnv} ${cfg.endpoint}${frontend} tenant=${cfg.tenantId ?? "1"} identity=${idName}`);
|
|
2421
2428
|
} catch (e) {
|
|
2422
2429
|
exitWithError(e);
|
|
2423
2430
|
}
|
|
@@ -2437,7 +2444,11 @@ async function envAdd(name, args) {
|
|
|
2437
2444
|
message: `env '${name}' already exists. Use --force to overwrite.`
|
|
2438
2445
|
});
|
|
2439
2446
|
}
|
|
2440
|
-
await saveEnv2(name, {
|
|
2447
|
+
await saveEnv2(name, {
|
|
2448
|
+
endpoint: args.endpoint,
|
|
2449
|
+
frontend: args.frontend,
|
|
2450
|
+
tenantId: args.tenant ?? "1"
|
|
2451
|
+
});
|
|
2441
2452
|
const allEnvs = await listEnvs();
|
|
2442
2453
|
const g = await loadGlobalConfig2();
|
|
2443
2454
|
const activeExists = allEnvs.includes(g.activeEnv);
|
|
@@ -2539,7 +2550,7 @@ async function envShow(args) {
|
|
|
2539
2550
|
}
|
|
2540
2551
|
async function envEdit(field, value, args) {
|
|
2541
2552
|
try {
|
|
2542
|
-
const ALLOWED = /* @__PURE__ */ new Set(["endpoint", "tenantId", "defaultIdentity", "defaultAgent"]);
|
|
2553
|
+
const ALLOWED = /* @__PURE__ */ new Set(["endpoint", "frontend", "tenantId", "defaultIdentity", "defaultAgent"]);
|
|
2543
2554
|
if (!ALLOWED.has(field)) {
|
|
2544
2555
|
throw new CliError3({
|
|
2545
2556
|
code: CliErrorCode2.INVALID_ARGUMENT,
|
|
@@ -2674,21 +2685,75 @@ import {
|
|
|
2674
2685
|
HcmClient as HcmClient2,
|
|
2675
2686
|
formatObject,
|
|
2676
2687
|
fromAxiosError as fromAxiosError2,
|
|
2677
|
-
CliError as
|
|
2678
|
-
CliErrorCode as
|
|
2688
|
+
CliError as CliError8,
|
|
2689
|
+
CliErrorCode as CliErrorCode7
|
|
2679
2690
|
} from "@hcmai/sdk";
|
|
2691
|
+
|
|
2692
|
+
// src/utils/json-input.ts
|
|
2693
|
+
import * as fs from "fs/promises";
|
|
2694
|
+
import { CliError as CliError7, CliErrorCode as CliErrorCode6 } from "@hcmai/sdk";
|
|
2695
|
+
async function readJsonObjectInput(options) {
|
|
2696
|
+
const { inline, file, inlineFlag, fileFlag, required = true } = options;
|
|
2697
|
+
if (inline && file) {
|
|
2698
|
+
throw new CliError7({
|
|
2699
|
+
code: CliErrorCode6.INVALID_ARGUMENT,
|
|
2700
|
+
message: `${inlineFlag} \u4E0E ${fileFlag} \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528`
|
|
2701
|
+
});
|
|
2702
|
+
}
|
|
2703
|
+
if (!inline && !file) {
|
|
2704
|
+
if (!required) return void 0;
|
|
2705
|
+
throw new CliError7({
|
|
2706
|
+
code: CliErrorCode6.MISSING_FLAG,
|
|
2707
|
+
message: `${inlineFlag} <JSON> \u6216 ${fileFlag} <path> \u5FC5\u586B`
|
|
2708
|
+
});
|
|
2709
|
+
}
|
|
2710
|
+
let raw;
|
|
2711
|
+
let sourceFlag;
|
|
2712
|
+
if (file) {
|
|
2713
|
+
sourceFlag = fileFlag;
|
|
2714
|
+
try {
|
|
2715
|
+
raw = await fs.readFile(file, "utf-8");
|
|
2716
|
+
} catch (error) {
|
|
2717
|
+
throw new CliError7({
|
|
2718
|
+
code: CliErrorCode6.INVALID_ARGUMENT,
|
|
2719
|
+
message: `${fileFlag}: \u65E0\u6CD5\u8BFB\u53D6 ${file}: ${error.message}`
|
|
2720
|
+
});
|
|
2721
|
+
}
|
|
2722
|
+
} else {
|
|
2723
|
+
sourceFlag = inlineFlag;
|
|
2724
|
+
raw = inline;
|
|
2725
|
+
}
|
|
2726
|
+
let parsed;
|
|
2727
|
+
try {
|
|
2728
|
+
parsed = JSON.parse(raw);
|
|
2729
|
+
} catch (error) {
|
|
2730
|
+
throw new CliError7({
|
|
2731
|
+
code: CliErrorCode6.INVALID_JSON,
|
|
2732
|
+
message: `${sourceFlag}: ${error.message}`
|
|
2733
|
+
});
|
|
2734
|
+
}
|
|
2735
|
+
if (parsed === null || Array.isArray(parsed) || typeof parsed !== "object") {
|
|
2736
|
+
throw new CliError7({
|
|
2737
|
+
code: CliErrorCode6.INVALID_JSON,
|
|
2738
|
+
message: `${sourceFlag}: \u9876\u5C42\u5FC5\u987B\u662F JSON \u5BF9\u8C61`
|
|
2739
|
+
});
|
|
2740
|
+
}
|
|
2741
|
+
return parsed;
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
// src/commands/action.ts
|
|
2680
2745
|
async function actionCommand(spec, args) {
|
|
2681
2746
|
try {
|
|
2682
2747
|
const [model, action] = spec.split(".");
|
|
2683
2748
|
if (!model || !action) {
|
|
2684
|
-
throw new
|
|
2685
|
-
code:
|
|
2749
|
+
throw new CliError8({
|
|
2750
|
+
code: CliErrorCode7.INVALID_ARGUMENT,
|
|
2686
2751
|
message: "expected <Model>.<Action> (e.g. Employee.regularize)"
|
|
2687
2752
|
});
|
|
2688
2753
|
}
|
|
2689
2754
|
if (args.id && args.ids) {
|
|
2690
|
-
throw new
|
|
2691
|
-
code:
|
|
2755
|
+
throw new CliError8({
|
|
2756
|
+
code: CliErrorCode7.INVALID_ARGUMENT,
|
|
2692
2757
|
message: "--id and --ids are mutually exclusive"
|
|
2693
2758
|
});
|
|
2694
2759
|
}
|
|
@@ -2698,16 +2763,14 @@ async function actionCommand(spec, args) {
|
|
|
2698
2763
|
if (scope) input.scope = scope;
|
|
2699
2764
|
if (args.id) input.id = args.id;
|
|
2700
2765
|
if (args.ids) input.ids = args.ids.split(",").map((s) => s.trim());
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
}
|
|
2710
|
-
}
|
|
2766
|
+
const params = await readJsonObjectInput({
|
|
2767
|
+
inline: args.params,
|
|
2768
|
+
file: args.paramsFile,
|
|
2769
|
+
inlineFlag: "--params",
|
|
2770
|
+
fileFlag: "--params-file",
|
|
2771
|
+
required: false
|
|
2772
|
+
});
|
|
2773
|
+
if (params) input.params = params;
|
|
2711
2774
|
const client3 = HcmClient2.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
2712
2775
|
const result2 = await client3.action(model, action, input);
|
|
2713
2776
|
const fmt = args.output ?? "json";
|
|
@@ -2732,16 +2795,16 @@ async function actionCommand(spec, args) {
|
|
|
2732
2795
|
function normalizeMethod(value) {
|
|
2733
2796
|
const raw = (value ?? "POST").toUpperCase();
|
|
2734
2797
|
if (raw === "GET" || raw === "POST" || raw === "PUT" || raw === "DELETE") return raw;
|
|
2735
|
-
throw new
|
|
2736
|
-
code:
|
|
2798
|
+
throw new CliError8({
|
|
2799
|
+
code: CliErrorCode7.INVALID_ARGUMENT,
|
|
2737
2800
|
message: `--method \u53D6\u503C GET | POST | PUT | DELETE\uFF0C\u6536\u5230 "${value}"`
|
|
2738
2801
|
});
|
|
2739
2802
|
}
|
|
2740
2803
|
function normalizeScope(value) {
|
|
2741
2804
|
if (value === void 0) return void 0;
|
|
2742
2805
|
if (value === "class" || value === "object") return value;
|
|
2743
|
-
throw new
|
|
2744
|
-
code:
|
|
2806
|
+
throw new CliError8({
|
|
2807
|
+
code: CliErrorCode7.INVALID_ARGUMENT,
|
|
2745
2808
|
message: `--scope \u53D6\u503C class | object\uFF0C\u6536\u5230 "${value}"`
|
|
2746
2809
|
});
|
|
2747
2810
|
}
|
|
@@ -2749,28 +2812,19 @@ function normalizeScope(value) {
|
|
|
2749
2812
|
// src/commands/create.ts
|
|
2750
2813
|
init_exit();
|
|
2751
2814
|
init_auth_guard();
|
|
2752
|
-
import {
|
|
2753
|
-
HcmClient as HcmClient3,
|
|
2754
|
-
formatObject as formatObject2,
|
|
2755
|
-
fromAxiosError as fromAxiosError3,
|
|
2756
|
-
CliError as CliError8,
|
|
2757
|
-
CliErrorCode as CliErrorCode7
|
|
2758
|
-
} from "@hcmai/sdk";
|
|
2815
|
+
import { HcmClient as HcmClient3, formatObject as formatObject2, fromAxiosError as fromAxiosError3 } from "@hcmai/sdk";
|
|
2759
2816
|
async function createCommand(model, args) {
|
|
2760
2817
|
try {
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
} catch (e) {
|
|
2768
|
-
throw new CliError8({ code: CliErrorCode7.INVALID_JSON, message: `--data: ${e.message}` });
|
|
2769
|
-
}
|
|
2818
|
+
const data = await readJsonObjectInput({
|
|
2819
|
+
inline: args.data,
|
|
2820
|
+
file: args.dataFile,
|
|
2821
|
+
inlineFlag: "--data",
|
|
2822
|
+
fileFlag: "--data-file"
|
|
2823
|
+
});
|
|
2770
2824
|
const client3 = HcmClient3.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
2771
2825
|
const res = await client3.create(model, data);
|
|
2772
2826
|
const fmt = args.output ?? "json";
|
|
2773
|
-
process.stdout.write("\u2705 created\n");
|
|
2827
|
+
if (fmt !== "json") process.stdout.write("\u2705 created\n");
|
|
2774
2828
|
process.stdout.write(formatObject2(res, { format: fmt }) + "\n");
|
|
2775
2829
|
process.exit(0);
|
|
2776
2830
|
} catch (e) {
|
|
@@ -2795,18 +2849,12 @@ async function updateCommand(model, args) {
|
|
|
2795
2849
|
if (!args.id) {
|
|
2796
2850
|
throw new CliError9({ code: CliErrorCode8.MISSING_FLAG, message: "--id <id> \u5FC5\u586B" });
|
|
2797
2851
|
}
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
} catch (e) {
|
|
2805
|
-
throw new CliError9({
|
|
2806
|
-
code: CliErrorCode8.INVALID_JSON,
|
|
2807
|
-
message: `--data: ${e.message}`
|
|
2808
|
-
});
|
|
2809
|
-
}
|
|
2852
|
+
const data = await readJsonObjectInput({
|
|
2853
|
+
inline: args.data,
|
|
2854
|
+
file: args.dataFile,
|
|
2855
|
+
inlineFlag: "--data",
|
|
2856
|
+
fileFlag: "--data-file"
|
|
2857
|
+
});
|
|
2810
2858
|
const client3 = HcmClient4.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
2811
2859
|
const result2 = await client3.update(model, args.id, data);
|
|
2812
2860
|
const fmt = args.output ?? "json";
|
|
@@ -2989,7 +3037,7 @@ async function deleteCommand(model, args) {
|
|
|
2989
3037
|
const client3 = HcmClient6.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
2990
3038
|
const res = await client3.remove(model, args.id);
|
|
2991
3039
|
const fmt = args.output ?? "json";
|
|
2992
|
-
process.stdout.write("\u2705 deleted\n");
|
|
3040
|
+
if (fmt !== "json") process.stdout.write("\u2705 deleted\n");
|
|
2993
3041
|
process.stdout.write(formatObject6(res, { format: fmt }) + "\n");
|
|
2994
3042
|
process.exit(0);
|
|
2995
3043
|
} catch (e) {
|
|
@@ -3061,7 +3109,11 @@ async function importCommand(path7, args) {
|
|
|
3061
3109
|
// src/commands/describe.ts
|
|
3062
3110
|
init_exit();
|
|
3063
3111
|
init_auth_guard();
|
|
3064
|
-
import {
|
|
3112
|
+
import {
|
|
3113
|
+
HcmClient as HcmClient8,
|
|
3114
|
+
formatObject as formatObject8,
|
|
3115
|
+
fromAxiosError as fromAxiosError9
|
|
3116
|
+
} from "@hcmai/sdk";
|
|
3065
3117
|
async function describeCommand(model, args) {
|
|
3066
3118
|
try {
|
|
3067
3119
|
const client3 = HcmClient8.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
@@ -3071,25 +3123,7 @@ async function describeCommand(model, args) {
|
|
|
3071
3123
|
process.stdout.write(formatObject8(desc, { format: fmt }) + "\n");
|
|
3072
3124
|
process.exit(0);
|
|
3073
3125
|
}
|
|
3074
|
-
|
|
3075
|
-
if (desc.labels.zh_CN) lines.push(`zh_CN: ${desc.labels.zh_CN}`);
|
|
3076
|
-
if (desc.labels.en) lines.push(`en: ${desc.labels.en}`);
|
|
3077
|
-
lines.push(`fields (${desc.fields.length}):`);
|
|
3078
|
-
for (const f of desc.fields) {
|
|
3079
|
-
const req = f.required ? " required" : " ";
|
|
3080
|
-
const lbl = args.verbose ? ` ${f.label ?? ""} ${f.description ?? ""}` : ` ${f.label ?? ""}`;
|
|
3081
|
-
lines.push(` ${f.name.padEnd(20)} ${f.type.padEnd(10)} ${req}${lbl}`);
|
|
3082
|
-
}
|
|
3083
|
-
lines.push(`actions (${desc.actions.length}):`);
|
|
3084
|
-
for (const a of desc.actions) {
|
|
3085
|
-
lines.push(` ${a.name.padEnd(20)} ${a.label ?? ""}`);
|
|
3086
|
-
}
|
|
3087
|
-
if (desc.relations.length) {
|
|
3088
|
-
lines.push(
|
|
3089
|
-
`relations: ${desc.relations.map((r) => `${r.key}(via ${r.via})`).join(", ")}`
|
|
3090
|
-
);
|
|
3091
|
-
}
|
|
3092
|
-
process.stdout.write(lines.join("\n") + "\n");
|
|
3126
|
+
process.stdout.write(formatDescriptionTable(desc, !!args.verbose) + "\n");
|
|
3093
3127
|
process.exit(0);
|
|
3094
3128
|
} catch (e) {
|
|
3095
3129
|
const err = e;
|
|
@@ -3099,6 +3133,28 @@ async function describeCommand(model, args) {
|
|
|
3099
3133
|
exitWithError(e);
|
|
3100
3134
|
}
|
|
3101
3135
|
}
|
|
3136
|
+
function formatDescriptionTable(desc, verbose = false) {
|
|
3137
|
+
const lines = [`=== ${desc.model} ===`];
|
|
3138
|
+
if (desc.labels.zh_CN) lines.push(`zh_CN: ${desc.labels.zh_CN}`);
|
|
3139
|
+
if (desc.labels.en) lines.push(`en: ${desc.labels.en}`);
|
|
3140
|
+
lines.push(`fields (${desc.fields.length}):`);
|
|
3141
|
+
for (const f of desc.fields) {
|
|
3142
|
+
const req = f.required ? " required" : " ";
|
|
3143
|
+
const lbl = verbose ? ` ${f.label ?? ""} ${f.description ?? ""}` : ` ${f.label ?? ""}`;
|
|
3144
|
+
lines.push(` ${f.name.padEnd(20)} ${f.type.padEnd(10)} ${req}${lbl}`);
|
|
3145
|
+
}
|
|
3146
|
+
lines.push(`actions (${desc.actions.length}):`);
|
|
3147
|
+
for (const a of desc.actions) {
|
|
3148
|
+
const call = [a.scope, a.httpMethod].filter(Boolean).join(" ");
|
|
3149
|
+
const params = a.params?.length ? ` params: ${a.params.map((p) => `${p.name}:${p.type}`).join(", ")}` : "";
|
|
3150
|
+
const description = verbose && a.description ? ` ${a.description}` : "";
|
|
3151
|
+
lines.push(` ${a.name.padEnd(20)} ${call.padEnd(12)} ${a.label ?? ""}${params}${description}`);
|
|
3152
|
+
}
|
|
3153
|
+
if (desc.relations.length) {
|
|
3154
|
+
lines.push(`relations: ${desc.relations.map((r) => `${r.key}(via ${r.via})`).join(", ")}`);
|
|
3155
|
+
}
|
|
3156
|
+
return lines.join("\n");
|
|
3157
|
+
}
|
|
3102
3158
|
|
|
3103
3159
|
// src/commands/chat.ts
|
|
3104
3160
|
init_exit();
|
|
@@ -3128,7 +3184,7 @@ import {
|
|
|
3128
3184
|
buildSteer
|
|
3129
3185
|
} from "@hcmai/sdk";
|
|
3130
3186
|
import chalk2 from "chalk";
|
|
3131
|
-
import * as
|
|
3187
|
+
import * as fs4 from "fs/promises";
|
|
3132
3188
|
function parseInjectOn(s) {
|
|
3133
3189
|
const fail5 = (detail) => {
|
|
3134
3190
|
throw new CliError13({
|
|
@@ -3404,7 +3460,7 @@ async function chatCommand(prompt, args) {
|
|
|
3404
3460
|
return runInkRepl2(args);
|
|
3405
3461
|
}
|
|
3406
3462
|
if (args.promptFile) {
|
|
3407
|
-
prompt = await
|
|
3463
|
+
prompt = await fs4.readFile(args.promptFile, "utf-8");
|
|
3408
3464
|
}
|
|
3409
3465
|
if (prompt === void 0 || !prompt && !regenerateMode) {
|
|
3410
3466
|
throw new CliError13({
|
|
@@ -4254,7 +4310,7 @@ import {
|
|
|
4254
4310
|
|
|
4255
4311
|
// src/commands/skills-sync.ts
|
|
4256
4312
|
import { createHash } from "crypto";
|
|
4257
|
-
import { promises as
|
|
4313
|
+
import { promises as fs5 } from "fs";
|
|
4258
4314
|
import path2 from "path";
|
|
4259
4315
|
import {
|
|
4260
4316
|
CliError as CliError14,
|
|
@@ -4424,8 +4480,8 @@ async function syncWorkBuddyProject(input) {
|
|
|
4424
4480
|
return result(false, input, project, skillsDir, lockPath, [], []);
|
|
4425
4481
|
}
|
|
4426
4482
|
const obsolete = [...oldOwned].filter((file) => !desiredByFile.has(file));
|
|
4427
|
-
await
|
|
4428
|
-
const staging = await
|
|
4483
|
+
await fs5.mkdir(metaDir, { recursive: true });
|
|
4484
|
+
const staging = await fs5.mkdtemp(path2.join(metaDir, ".staging-"));
|
|
4429
4485
|
const stagedFiles = path2.join(staging, "new");
|
|
4430
4486
|
const backups = path2.join(staging, "backup");
|
|
4431
4487
|
const stagedLock = path2.join(staging, "chiron.lock.json");
|
|
@@ -4434,28 +4490,28 @@ async function syncWorkBuddyProject(input) {
|
|
|
4434
4490
|
try {
|
|
4435
4491
|
for (const [file, preparedFile2] of desiredByFile) {
|
|
4436
4492
|
const staged = path2.join(stagedFiles, file);
|
|
4437
|
-
await
|
|
4438
|
-
await
|
|
4493
|
+
await fs5.mkdir(path2.dirname(staged), { recursive: true });
|
|
4494
|
+
await fs5.writeFile(
|
|
4439
4495
|
staged,
|
|
4440
4496
|
preparedFile2.content,
|
|
4441
4497
|
preparedFile2.mode === void 0 ? void 0 : { mode: preparedFile2.mode }
|
|
4442
4498
|
);
|
|
4443
4499
|
}
|
|
4444
|
-
await
|
|
4500
|
+
await fs5.writeFile(stagedLock, `${JSON.stringify(newLock, null, 2)}
|
|
4445
4501
|
`, "utf8");
|
|
4446
4502
|
const affected = [.../* @__PURE__ */ new Set([...desiredFiles, ...obsolete])];
|
|
4447
4503
|
for (const file of affected) {
|
|
4448
4504
|
const target = path2.join(project, file);
|
|
4449
4505
|
if (!await exists(target)) continue;
|
|
4450
4506
|
const backup = path2.join(backups, file);
|
|
4451
|
-
await
|
|
4452
|
-
await
|
|
4507
|
+
await fs5.mkdir(path2.dirname(backup), { recursive: true });
|
|
4508
|
+
await fs5.copyFile(target, backup);
|
|
4453
4509
|
}
|
|
4454
4510
|
const oldLockExisted = await exists(lockPath);
|
|
4455
4511
|
if (oldLockExisted) {
|
|
4456
4512
|
const backupLock = path2.join(backups, ".hcm-delivery", "chiron.lock.json");
|
|
4457
|
-
await
|
|
4458
|
-
await
|
|
4513
|
+
await fs5.mkdir(path2.dirname(backupLock), { recursive: true });
|
|
4514
|
+
await fs5.copyFile(lockPath, backupLock);
|
|
4459
4515
|
}
|
|
4460
4516
|
const journal = {
|
|
4461
4517
|
schemaVersion: 1,
|
|
@@ -4463,25 +4519,25 @@ async function syncWorkBuddyProject(input) {
|
|
|
4463
4519
|
affectedFiles: affected,
|
|
4464
4520
|
oldLockExisted
|
|
4465
4521
|
};
|
|
4466
|
-
await
|
|
4522
|
+
await fs5.writeFile(journalPath, `${JSON.stringify(journal, null, 2)}
|
|
4467
4523
|
`, "utf8");
|
|
4468
4524
|
journalReady = true;
|
|
4469
4525
|
for (const file of desiredFiles) {
|
|
4470
4526
|
const target = path2.join(project, file);
|
|
4471
|
-
await
|
|
4472
|
-
await
|
|
4473
|
-
await
|
|
4474
|
-
}
|
|
4475
|
-
for (const file of obsolete) await
|
|
4476
|
-
await
|
|
4477
|
-
await
|
|
4478
|
-
await
|
|
4527
|
+
await fs5.mkdir(path2.dirname(target), { recursive: true });
|
|
4528
|
+
await fs5.rm(target, { force: true });
|
|
4529
|
+
await fs5.rename(path2.join(stagedFiles, file), target);
|
|
4530
|
+
}
|
|
4531
|
+
for (const file of obsolete) await fs5.unlink(path2.join(project, file)).catch(ignoreMissing);
|
|
4532
|
+
await fs5.rm(lockPath, { force: true });
|
|
4533
|
+
await fs5.rename(stagedLock, lockPath);
|
|
4534
|
+
await fs5.unlink(journalPath);
|
|
4479
4535
|
journalReady = false;
|
|
4480
4536
|
} catch (cause) {
|
|
4481
4537
|
if (journalReady) await recoverStaging(project, staging, lockPath);
|
|
4482
4538
|
throw cause;
|
|
4483
4539
|
} finally {
|
|
4484
|
-
await
|
|
4540
|
+
await fs5.rm(staging, { recursive: true, force: true });
|
|
4485
4541
|
}
|
|
4486
4542
|
return result(
|
|
4487
4543
|
true,
|
|
@@ -4496,7 +4552,7 @@ async function syncWorkBuddyProject(input) {
|
|
|
4496
4552
|
async function recoverInterruptedSyncs(project, metaDir, lockPath) {
|
|
4497
4553
|
let entries;
|
|
4498
4554
|
try {
|
|
4499
|
-
entries = await
|
|
4555
|
+
entries = await fs5.readdir(metaDir, { withFileTypes: true });
|
|
4500
4556
|
} catch (cause) {
|
|
4501
4557
|
if (cause.code === "ENOENT") return;
|
|
4502
4558
|
throw cause;
|
|
@@ -4507,32 +4563,32 @@ async function recoverInterruptedSyncs(project, metaDir, lockPath) {
|
|
|
4507
4563
|
if (await exists(path2.join(staging, "journal.json"))) {
|
|
4508
4564
|
await recoverStaging(project, staging, lockPath);
|
|
4509
4565
|
}
|
|
4510
|
-
await
|
|
4566
|
+
await fs5.rm(staging, { recursive: true, force: true });
|
|
4511
4567
|
}
|
|
4512
4568
|
}
|
|
4513
4569
|
async function recoverStaging(project, staging, lockPath) {
|
|
4514
4570
|
const journalPath = path2.join(staging, "journal.json");
|
|
4515
|
-
const journal = parseJournal(await
|
|
4571
|
+
const journal = parseJournal(await fs5.readFile(journalPath, "utf8"), project);
|
|
4516
4572
|
const backups = path2.join(staging, "backup");
|
|
4517
4573
|
for (const file of journal.affectedFiles) {
|
|
4518
4574
|
const target = path2.join(project, file);
|
|
4519
4575
|
const backup = path2.join(backups, file);
|
|
4520
4576
|
if (await exists(backup)) {
|
|
4521
|
-
await
|
|
4522
|
-
await
|
|
4523
|
-
await
|
|
4577
|
+
await fs5.mkdir(path2.dirname(target), { recursive: true });
|
|
4578
|
+
await fs5.rm(target, { force: true });
|
|
4579
|
+
await fs5.rename(backup, target);
|
|
4524
4580
|
} else {
|
|
4525
|
-
await
|
|
4581
|
+
await fs5.rm(target, { force: true });
|
|
4526
4582
|
}
|
|
4527
4583
|
}
|
|
4528
4584
|
const backupLock = path2.join(backups, ".hcm-delivery", "chiron.lock.json");
|
|
4529
4585
|
if (journal.oldLockExisted) {
|
|
4530
4586
|
if (!await exists(backupLock)) throw invalid(`\u540C\u6B65\u6062\u590D\u7F3A\u5C11\u65E7\u9501\u5907\u4EFD\uFF1A${backupLock}`);
|
|
4531
|
-
await
|
|
4532
|
-
await
|
|
4533
|
-
await
|
|
4587
|
+
await fs5.mkdir(path2.dirname(lockPath), { recursive: true });
|
|
4588
|
+
await fs5.rm(lockPath, { force: true });
|
|
4589
|
+
await fs5.rename(backupLock, lockPath);
|
|
4534
4590
|
} else {
|
|
4535
|
-
await
|
|
4591
|
+
await fs5.rm(lockPath, { force: true });
|
|
4536
4592
|
}
|
|
4537
4593
|
}
|
|
4538
4594
|
function parseJournal(content, project) {
|
|
@@ -4775,7 +4831,7 @@ function stableJson2(value) {
|
|
|
4775
4831
|
}
|
|
4776
4832
|
async function readOptional(file) {
|
|
4777
4833
|
try {
|
|
4778
|
-
return await
|
|
4834
|
+
return await fs5.readFile(file, "utf8");
|
|
4779
4835
|
} catch (cause) {
|
|
4780
4836
|
if (cause.code === "ENOENT") return void 0;
|
|
4781
4837
|
throw cause;
|
|
@@ -4783,7 +4839,7 @@ async function readOptional(file) {
|
|
|
4783
4839
|
}
|
|
4784
4840
|
async function readOptionalBytes(file) {
|
|
4785
4841
|
try {
|
|
4786
|
-
return await
|
|
4842
|
+
return await fs5.readFile(file);
|
|
4787
4843
|
} catch (cause) {
|
|
4788
4844
|
if (cause.code === "ENOENT") return void 0;
|
|
4789
4845
|
throw cause;
|
|
@@ -4791,7 +4847,7 @@ async function readOptionalBytes(file) {
|
|
|
4791
4847
|
}
|
|
4792
4848
|
async function exists(file) {
|
|
4793
4849
|
try {
|
|
4794
|
-
await
|
|
4850
|
+
await fs5.access(file);
|
|
4795
4851
|
return true;
|
|
4796
4852
|
} catch (cause) {
|
|
4797
4853
|
if (cause.code === "ENOENT") return false;
|
|
@@ -4816,7 +4872,7 @@ function lockDigests(lock) {
|
|
|
4816
4872
|
}
|
|
4817
4873
|
async function fileModeMatches(file, expected) {
|
|
4818
4874
|
if (expected === void 0 || process.platform === "win32") return true;
|
|
4819
|
-
const stat = await
|
|
4875
|
+
const stat = await fs5.stat(file);
|
|
4820
4876
|
return (stat.mode & 511) === expected;
|
|
4821
4877
|
}
|
|
4822
4878
|
function validDigest(value) {
|
|
@@ -4832,7 +4888,7 @@ function invalid(message) {
|
|
|
4832
4888
|
// src/commands/skills-runtime.ts
|
|
4833
4889
|
import { execFile } from "child_process";
|
|
4834
4890
|
import { createHash as createHash2 } from "crypto";
|
|
4835
|
-
import { createReadStream, promises as
|
|
4891
|
+
import { createReadStream, promises as fs6 } from "fs";
|
|
4836
4892
|
import path3 from "path";
|
|
4837
4893
|
import { promisify } from "util";
|
|
4838
4894
|
import { CliError as CliError15, CliErrorCode as CliErrorCode14 } from "@hcmai/sdk";
|
|
@@ -4910,8 +4966,8 @@ async function resolveLaunch(candidate, nodeExecutable) {
|
|
|
4910
4966
|
}
|
|
4911
4967
|
async function realFile(file, label) {
|
|
4912
4968
|
try {
|
|
4913
|
-
const resolved = await
|
|
4914
|
-
const stat = await
|
|
4969
|
+
const resolved = await fs6.realpath(file);
|
|
4970
|
+
const stat = await fs6.stat(resolved);
|
|
4915
4971
|
if (!stat.isFile()) throw new Error("not a regular file");
|
|
4916
4972
|
return resolved;
|
|
4917
4973
|
} catch (cause) {
|
|
@@ -4924,20 +4980,20 @@ async function realFile(file, label) {
|
|
|
4924
4980
|
}
|
|
4925
4981
|
async function comparablePath(file) {
|
|
4926
4982
|
const absolute = path3.resolve(file);
|
|
4927
|
-
return
|
|
4983
|
+
return fs6.realpath(absolute).catch(() => absolute);
|
|
4928
4984
|
}
|
|
4929
4985
|
async function launchIdentity(launch) {
|
|
4930
4986
|
const files = launch.kind === "node-entry" ? [launch.executable, launch.entry] : [launch.executable];
|
|
4931
4987
|
const identities = await Promise.all(
|
|
4932
4988
|
files.map(async (file) => {
|
|
4933
|
-
const stat = await
|
|
4989
|
+
const stat = await fs6.stat(file, { bigint: true });
|
|
4934
4990
|
return [file, stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].map(String).join("\0");
|
|
4935
4991
|
})
|
|
4936
4992
|
);
|
|
4937
4993
|
return identities.join("\n");
|
|
4938
4994
|
}
|
|
4939
4995
|
async function readPrefix(file, bytes) {
|
|
4940
|
-
const handle = await
|
|
4996
|
+
const handle = await fs6.open(file, "r");
|
|
4941
4997
|
try {
|
|
4942
4998
|
const buffer = Buffer.alloc(bytes);
|
|
4943
4999
|
const result2 = await handle.read(buffer, 0, bytes, 0);
|
|
@@ -6158,7 +6214,7 @@ async function metaDeleteCommand(path7, args) {
|
|
|
6158
6214
|
init_exit();
|
|
6159
6215
|
init_auth_guard();
|
|
6160
6216
|
import * as crypto from "crypto";
|
|
6161
|
-
import * as
|
|
6217
|
+
import * as fs7 from "fs/promises";
|
|
6162
6218
|
import * as path5 from "path";
|
|
6163
6219
|
import {
|
|
6164
6220
|
buildMiniPreviewTargets,
|
|
@@ -6294,7 +6350,7 @@ async function workspaceBindCommand(workspaceKey, args) {
|
|
|
6294
6350
|
tenantId: args.tenant ?? client3?.tenantId,
|
|
6295
6351
|
endpoint: args.endpoint ?? client3?.endpoint
|
|
6296
6352
|
});
|
|
6297
|
-
await
|
|
6353
|
+
await fs7.mkdir(rootDir, { recursive: true });
|
|
6298
6354
|
await writeWorkspaceContext(rootDir, context);
|
|
6299
6355
|
writeWorkspaceBindResult(context, rootDir, args.output ?? "table");
|
|
6300
6356
|
process.exit(0);
|
|
@@ -6329,7 +6385,7 @@ async function workspaceCreateCommand(workspaceKey, args) {
|
|
|
6329
6385
|
tenantId: client3.tenantId,
|
|
6330
6386
|
endpoint: client3.endpoint
|
|
6331
6387
|
});
|
|
6332
|
-
await
|
|
6388
|
+
await fs7.mkdir(rootDir, { recursive: true });
|
|
6333
6389
|
await writeWorkspaceContext(rootDir, context);
|
|
6334
6390
|
writeWorkspaceCreateResult(
|
|
6335
6391
|
{
|
|
@@ -6366,7 +6422,7 @@ async function workspacePullCommand(args) {
|
|
|
6366
6422
|
tenantId: client3.tenantId ?? existing?.tenantId,
|
|
6367
6423
|
endpoint: client3.endpoint ?? existing?.endpoint
|
|
6368
6424
|
});
|
|
6369
|
-
await
|
|
6425
|
+
await fs7.mkdir(rootDir, { recursive: true });
|
|
6370
6426
|
await writeWorkspaceContext(rootDir, context);
|
|
6371
6427
|
const files = await listWorkspaceFiles(client3.raw(), workspaceKey, { pageSize: 5e3 });
|
|
6372
6428
|
const miniApps = detectRemoteMiniApps(files.data);
|
|
@@ -6698,7 +6754,7 @@ function buildWorkspaceContext(args) {
|
|
|
6698
6754
|
async function readWorkspaceContext(rootDir) {
|
|
6699
6755
|
try {
|
|
6700
6756
|
const parsed = JSON.parse(
|
|
6701
|
-
await
|
|
6757
|
+
await fs7.readFile(path5.join(rootDir, WORKSPACE_CONTEXT_FILE), "utf-8")
|
|
6702
6758
|
);
|
|
6703
6759
|
if (parsed.kind !== WORKSPACE_CONTEXT_KIND || parsed.version !== WORKSPACE_CONTEXT_VERSION) {
|
|
6704
6760
|
throw new Error(`${WORKSPACE_CONTEXT_FILE} is not an HCM workspace context`);
|
|
@@ -6727,25 +6783,25 @@ async function requireWorkspaceContext(rootDir) {
|
|
|
6727
6783
|
return context;
|
|
6728
6784
|
}
|
|
6729
6785
|
async function writeWorkspaceContext(rootDir, context) {
|
|
6730
|
-
await
|
|
6786
|
+
await fs7.writeFile(
|
|
6731
6787
|
path5.join(rootDir, WORKSPACE_CONTEXT_FILE),
|
|
6732
6788
|
JSON.stringify(context, null, 2) + "\n"
|
|
6733
6789
|
);
|
|
6734
6790
|
}
|
|
6735
6791
|
async function writeTextFile(file, content, force) {
|
|
6736
6792
|
try {
|
|
6737
|
-
await
|
|
6793
|
+
await fs7.access(file);
|
|
6738
6794
|
if (!force) throw new Error(`${file} already exists; use --force to overwrite`);
|
|
6739
6795
|
} catch (e) {
|
|
6740
6796
|
if (e.code !== "ENOENT") throw e;
|
|
6741
6797
|
}
|
|
6742
|
-
await
|
|
6743
|
-
await
|
|
6798
|
+
await fs7.mkdir(path5.dirname(file), { recursive: true });
|
|
6799
|
+
await fs7.writeFile(file, content);
|
|
6744
6800
|
}
|
|
6745
6801
|
async function readWorkspaceRawManifest(rootDir, context) {
|
|
6746
6802
|
try {
|
|
6747
6803
|
const parsed = JSON.parse(
|
|
6748
|
-
await
|
|
6804
|
+
await fs7.readFile(path5.join(rootDir, WORKSPACE_STATE_DIR, WORKSPACE_PULL_MANIFEST_FILE), "utf-8")
|
|
6749
6805
|
);
|
|
6750
6806
|
if (parsed.version !== WORKSPACE_CONTEXT_VERSION || parsed.workspaceKey !== context.workspaceKey) {
|
|
6751
6807
|
throw new Error(`${WORKSPACE_PULL_MANIFEST_FILE} does not match workspace ${context.workspaceKey}`);
|
|
@@ -6764,7 +6820,7 @@ async function readWorkspaceRawManifest(rootDir, context) {
|
|
|
6764
6820
|
}
|
|
6765
6821
|
async function writeWorkspaceRawState(rootDir, context, files, remoteByLocalPath) {
|
|
6766
6822
|
const stateDir = path5.join(rootDir, WORKSPACE_STATE_DIR);
|
|
6767
|
-
await
|
|
6823
|
+
await fs7.mkdir(stateDir, { recursive: true });
|
|
6768
6824
|
const snapshots = files.map((file) => ({
|
|
6769
6825
|
localPath: file.localPath,
|
|
6770
6826
|
remotePath: file.localPath,
|
|
@@ -6773,7 +6829,7 @@ async function writeWorkspaceRawState(rootDir, context, files, remoteByLocalPath
|
|
|
6773
6829
|
size: file.size,
|
|
6774
6830
|
lastModified: remoteByLocalPath.get(file.localPath)?.lastModified
|
|
6775
6831
|
}));
|
|
6776
|
-
await
|
|
6832
|
+
await fs7.writeFile(
|
|
6777
6833
|
path5.join(stateDir, WORKSPACE_PULL_MANIFEST_FILE),
|
|
6778
6834
|
JSON.stringify(
|
|
6779
6835
|
{
|
|
@@ -6799,7 +6855,7 @@ async function walkWorkspaceRawFiles(rootDir, relativeDir, files) {
|
|
|
6799
6855
|
const absoluteDir = path5.join(rootDir, relativeDir);
|
|
6800
6856
|
let entries;
|
|
6801
6857
|
try {
|
|
6802
|
-
entries = await
|
|
6858
|
+
entries = await fs7.readdir(absoluteDir, { withFileTypes: true });
|
|
6803
6859
|
} catch (e) {
|
|
6804
6860
|
if (e.code === "ENOENT") return;
|
|
6805
6861
|
throw e;
|
|
@@ -6814,7 +6870,7 @@ async function walkWorkspaceRawFiles(rootDir, relativeDir, files) {
|
|
|
6814
6870
|
continue;
|
|
6815
6871
|
}
|
|
6816
6872
|
if (!entry.isFile()) continue;
|
|
6817
|
-
const content = await
|
|
6873
|
+
const content = await fs7.readFile(absolutePath, "utf-8");
|
|
6818
6874
|
files.push({
|
|
6819
6875
|
localPath,
|
|
6820
6876
|
absolutePath,
|
|
@@ -6991,7 +7047,7 @@ async function discoverMiniApps(rootDir) {
|
|
|
6991
7047
|
const appsRoot = path5.join(rootDir, MINI_APPS_DIR);
|
|
6992
7048
|
let entries;
|
|
6993
7049
|
try {
|
|
6994
|
-
entries = await
|
|
7050
|
+
entries = await fs7.readdir(appsRoot, { withFileTypes: true });
|
|
6995
7051
|
} catch (e) {
|
|
6996
7052
|
if (e.code === "ENOENT") return [];
|
|
6997
7053
|
throw e;
|
|
@@ -7530,7 +7586,8 @@ var GUARDED_EXECUTOR_REASON_CODES = /* @__PURE__ */ new Set([
|
|
|
7530
7586
|
"record-create",
|
|
7531
7587
|
"record-update",
|
|
7532
7588
|
"cache-mutation",
|
|
7533
|
-
"setting-write"
|
|
7589
|
+
"setting-write",
|
|
7590
|
+
"credential-reset"
|
|
7534
7591
|
]);
|
|
7535
7592
|
function assessDeliveryCommand(inputArgv) {
|
|
7536
7593
|
const argv = inputArgv[0] === "--" ? inputArgv.slice(1) : [...inputArgv];
|
|
@@ -7539,7 +7596,9 @@ function assessDeliveryCommand(inputArgv) {
|
|
|
7539
7596
|
const subcommand = argv[1] && !argv[1].startsWith("-") ? argv[1] : void 0;
|
|
7540
7597
|
const envAlias = flagValue(argv, "--env");
|
|
7541
7598
|
const identityAlias = flagValue(argv, "--as");
|
|
7542
|
-
const sensitiveFlags = [
|
|
7599
|
+
const sensitiveFlags = [
|
|
7600
|
+
...new Set([...PAYLOAD_FLAGS, ...CREDENTIAL_FLAGS].filter((flag) => hasFlag(argv, flag)))
|
|
7601
|
+
];
|
|
7543
7602
|
const target = summarizeTarget(argv);
|
|
7544
7603
|
let classification = classify(argv);
|
|
7545
7604
|
const invalidPayload = payloadError(argv);
|
|
@@ -7593,6 +7652,19 @@ function classify(argv) {
|
|
|
7593
7652
|
if (argv.some((arg) => APPROVAL_BYPASS_FLAGS.has(flagName(arg)))) {
|
|
7594
7653
|
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");
|
|
7595
7654
|
}
|
|
7655
|
+
if (name === "user" && subcommand === "reset-password") {
|
|
7656
|
+
const nonStdinCredential = argv.some((arg) => {
|
|
7657
|
+
const flag = flagName(arg);
|
|
7658
|
+
return CREDENTIAL_FLAGS.has(flag) && flag !== "--password-stdin";
|
|
7659
|
+
});
|
|
7660
|
+
if (nonStdinCredential || !argv.includes("--password-stdin")) {
|
|
7661
|
+
return forbidden(
|
|
7662
|
+
"credential-governance",
|
|
7663
|
+
"\u7528\u6237\u5BC6\u7801\u91CD\u7F6E\u53EA\u80FD\u901A\u8FC7 --password-stdin \u8FDB\u5165\u53D7\u63A7\u51ED\u636E\u6D41\u7A0B\u3002"
|
|
7664
|
+
);
|
|
7665
|
+
}
|
|
7666
|
+
return guarded("credential-write", "credential-reset");
|
|
7667
|
+
}
|
|
7596
7668
|
if (argv.some((arg) => CREDENTIAL_FLAGS.has(flagName(arg)))) {
|
|
7597
7669
|
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");
|
|
7598
7670
|
}
|
|
@@ -7714,7 +7786,14 @@ function summarizeTarget(argv) {
|
|
|
7714
7786
|
if (settingKeys.length > 0) target.settingKeys = settingKeys;
|
|
7715
7787
|
}
|
|
7716
7788
|
const id = flagValue(argv, "--id");
|
|
7717
|
-
if (
|
|
7789
|
+
if (name === "user" && subcommand === "reset-password") {
|
|
7790
|
+
if (id) target.userIdSha256 = sha2565(id);
|
|
7791
|
+
const username = flagValue(argv, "--username");
|
|
7792
|
+
if (username) target.usernameSha256 = sha2565(username);
|
|
7793
|
+
target.forceChangeOnNextLogin = !hasFlag(argv, "--no-force-change");
|
|
7794
|
+
} else if (id) {
|
|
7795
|
+
target.recordIdSha256 = sha2565(id);
|
|
7796
|
+
}
|
|
7718
7797
|
for (const flag of PAYLOAD_FLAGS) {
|
|
7719
7798
|
const raw = flagValue(argv, flag);
|
|
7720
7799
|
if (!raw) continue;
|
|
@@ -7813,7 +7892,7 @@ function isPlainObject(value) {
|
|
|
7813
7892
|
// src/commands/delivery-execution.ts
|
|
7814
7893
|
import { createHash as createHash6, randomBytes as secureRandomBytes } from "crypto";
|
|
7815
7894
|
import { spawn } from "child_process";
|
|
7816
|
-
import { createReadStream as createReadStream2, promises as
|
|
7895
|
+
import { createReadStream as createReadStream2, promises as fs8 } from "fs";
|
|
7817
7896
|
import path6 from "path";
|
|
7818
7897
|
import { CliError as CliError20, CliErrorCode as CliErrorCode19, formatObject as formatObject18 } from "@hcmai/sdk";
|
|
7819
7898
|
init_exit();
|
|
@@ -7857,7 +7936,7 @@ async function prepareDeliveryExecution(input) {
|
|
|
7857
7936
|
await safeManagedDirectory(project, ".hcm-delivery/execution-plans", plansDir);
|
|
7858
7937
|
const planFile = path6.join(plansDir, `${planId}.json`);
|
|
7859
7938
|
try {
|
|
7860
|
-
await
|
|
7939
|
+
await fs8.writeFile(planFile, `${JSON.stringify(plan, null, 2)}
|
|
7861
7940
|
`, {
|
|
7862
7941
|
encoding: "utf8",
|
|
7863
7942
|
mode: 384,
|
|
@@ -7911,7 +7990,7 @@ async function executeDeliveryPlan(input) {
|
|
|
7911
7990
|
await safeManagedDirectory(project, ".hcm-delivery/execution-claims", claimsDir);
|
|
7912
7991
|
const claimFile = path6.join(claimsDir, `${plan.planId}.json`);
|
|
7913
7992
|
try {
|
|
7914
|
-
await
|
|
7993
|
+
await fs8.writeFile(
|
|
7915
7994
|
claimFile,
|
|
7916
7995
|
`${JSON.stringify({ schemaVersion: 1, planId: plan.planId, claimedAt: now.toISOString() }, null, 2)}
|
|
7917
7996
|
`,
|
|
@@ -8031,7 +8110,7 @@ async function bindEvidenceDirectory(project, reference) {
|
|
|
8031
8110
|
}
|
|
8032
8111
|
const absolute = path6.join(project, relative2);
|
|
8033
8112
|
await assertNoSymlinkComponents(project, relative2);
|
|
8034
|
-
const stat = await
|
|
8113
|
+
const stat = await fs8.stat(absolute).catch((cause) => {
|
|
8035
8114
|
throw invalid4(`evidence \u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${relative2}`, cause);
|
|
8036
8115
|
});
|
|
8037
8116
|
if (!stat.isDirectory()) throw invalid4(`evidence \u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${relative2}`);
|
|
@@ -8065,6 +8144,32 @@ function assertGuardedAssessment(assessment, argv) {
|
|
|
8065
8144
|
validateSupportedCommandShape(assessment.reasonCode, argv);
|
|
8066
8145
|
}
|
|
8067
8146
|
function validateSupportedCommandShape(reasonCode, argv) {
|
|
8147
|
+
if (reasonCode === "credential-reset") {
|
|
8148
|
+
if (argv[0] !== "user" || argv[1] !== "reset-password") {
|
|
8149
|
+
throw invalid4("credential-reset \u53EA\u652F\u6301 user reset-password");
|
|
8150
|
+
}
|
|
8151
|
+
const userId = optionalFlagValue(argv, "--id");
|
|
8152
|
+
const username = optionalFlagValue(argv, "--username");
|
|
8153
|
+
if (Boolean(userId) === Boolean(username)) {
|
|
8154
|
+
throw invalid4("user reset-password \u5FC5\u987B\u4E14\u53EA\u80FD\u5305\u542B --id \u6216 --username");
|
|
8155
|
+
}
|
|
8156
|
+
if (!argv.includes("--password-stdin")) {
|
|
8157
|
+
throw invalid4("user reset-password \u5FC5\u987B\u5305\u542B\u72EC\u7ACB\u7684 --password-stdin");
|
|
8158
|
+
}
|
|
8159
|
+
if (argv.some(
|
|
8160
|
+
(value) => [
|
|
8161
|
+
"--password",
|
|
8162
|
+
"--new-password",
|
|
8163
|
+
"--client-secret",
|
|
8164
|
+
"--pat",
|
|
8165
|
+
"--new-password-stdin",
|
|
8166
|
+
"--pat-stdin"
|
|
8167
|
+
].includes(value.split("=", 1)[0] ?? "")
|
|
8168
|
+
) || argv.some((value) => value.startsWith("--password-stdin="))) {
|
|
8169
|
+
throw invalid4("user reset-password \u4E0D\u5141\u8BB8\u5728 argv \u4E2D\u643A\u5E26\u660E\u6587\u51ED\u636E");
|
|
8170
|
+
}
|
|
8171
|
+
return;
|
|
8172
|
+
}
|
|
8068
8173
|
if (reasonCode === "record-create") {
|
|
8069
8174
|
requireFlagValue(argv, "--data", "create \u5FC5\u987B\u5305\u542B --data <JSON>");
|
|
8070
8175
|
return;
|
|
@@ -8089,6 +8194,19 @@ function validateSupportedCommandShape(reasonCode, argv) {
|
|
|
8089
8194
|
}
|
|
8090
8195
|
}
|
|
8091
8196
|
}
|
|
8197
|
+
function optionalFlagValue(argv, flag) {
|
|
8198
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
8199
|
+
const value = argv[index];
|
|
8200
|
+
if (value === flag) {
|
|
8201
|
+
const next = argv[index + 1];
|
|
8202
|
+
return next && !next.startsWith("-") ? next : void 0;
|
|
8203
|
+
}
|
|
8204
|
+
if (value?.startsWith(`${flag}=`) && value.length > flag.length + 1) {
|
|
8205
|
+
return value.slice(flag.length + 1);
|
|
8206
|
+
}
|
|
8207
|
+
}
|
|
8208
|
+
return void 0;
|
|
8209
|
+
}
|
|
8092
8210
|
function requireFlagValue(argv, flag, message) {
|
|
8093
8211
|
for (let index = 0; index < argv.length; index += 1) {
|
|
8094
8212
|
const value = argv[index];
|
|
@@ -8143,29 +8261,29 @@ async function runCurrentCliCommand(argv, cwd, streams) {
|
|
|
8143
8261
|
async function writeReceiptExclusive(target, receipt) {
|
|
8144
8262
|
const temp = `${target}.${process.pid}.${Date.now()}.tmp`;
|
|
8145
8263
|
try {
|
|
8146
|
-
await
|
|
8264
|
+
await fs8.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
|
|
8147
8265
|
`, {
|
|
8148
8266
|
encoding: "utf8",
|
|
8149
8267
|
mode: 384,
|
|
8150
8268
|
flag: "wx"
|
|
8151
8269
|
});
|
|
8152
|
-
await
|
|
8270
|
+
await fs8.link(temp, target);
|
|
8153
8271
|
} catch (cause) {
|
|
8154
8272
|
throw invalid4(`\u6267\u884C\u6536\u636E\u5199\u5165\u5931\u8D25\u6216\u5DF2\u5B58\u5728\uFF1A${path6.basename(target)}`, cause);
|
|
8155
8273
|
} finally {
|
|
8156
|
-
await
|
|
8274
|
+
await fs8.unlink(temp).catch(() => void 0);
|
|
8157
8275
|
}
|
|
8158
8276
|
}
|
|
8159
8277
|
async function safeManagedDirectory(project, relative2, absolute) {
|
|
8160
8278
|
await assertNoSymlinkComponents(project, path6.dirname(relative2));
|
|
8161
|
-
const existing = await
|
|
8279
|
+
const existing = await fs8.lstat(absolute).catch(() => void 0);
|
|
8162
8280
|
if (existing?.isSymbolicLink()) throw invalid4(`\u53D7\u7BA1\u76EE\u5F55\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
8163
8281
|
if (existing && !existing.isDirectory()) throw invalid4(`\u53D7\u7BA1\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${relative2}`);
|
|
8164
|
-
if (!existing) await
|
|
8165
|
-
await
|
|
8282
|
+
if (!existing) await fs8.mkdir(absolute, { mode: 448 });
|
|
8283
|
+
await fs8.chmod(absolute, 448);
|
|
8166
8284
|
}
|
|
8167
8285
|
async function pathExists(file) {
|
|
8168
|
-
return
|
|
8286
|
+
return fs8.lstat(file).then(
|
|
8169
8287
|
() => true,
|
|
8170
8288
|
(cause) => {
|
|
8171
8289
|
if (cause.code === "ENOENT") return false;
|
|
@@ -8180,20 +8298,20 @@ async function readSafeFile(project, file, label) {
|
|
|
8180
8298
|
await assertNoSymlinkComponents(project, relative2);
|
|
8181
8299
|
let stat;
|
|
8182
8300
|
try {
|
|
8183
|
-
stat = await
|
|
8301
|
+
stat = await fs8.lstat(file);
|
|
8184
8302
|
} catch (cause) {
|
|
8185
8303
|
throw invalid4(`${label}\u4E0D\u53EF\u7528\uFF1A${relative2}`, cause);
|
|
8186
8304
|
}
|
|
8187
8305
|
if (stat.isSymbolicLink()) throw invalid4(`${label}\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
8188
8306
|
if (!stat.isFile()) throw invalid4(`${label}\u4E0D\u662F\u666E\u901A\u6587\u4EF6\uFF1A${relative2}`);
|
|
8189
|
-
return
|
|
8307
|
+
return fs8.readFile(file);
|
|
8190
8308
|
}
|
|
8191
8309
|
async function assertNoSymlinkComponents(project, relative2) {
|
|
8192
8310
|
const parts = relative2.split("/").filter(Boolean);
|
|
8193
8311
|
let current = project;
|
|
8194
8312
|
for (const part of parts) {
|
|
8195
8313
|
current = path6.join(current, part);
|
|
8196
|
-
const stat = await
|
|
8314
|
+
const stat = await fs8.lstat(current).catch(() => void 0);
|
|
8197
8315
|
if (stat?.isSymbolicLink()) throw invalid4(`\u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
8198
8316
|
if (!stat) break;
|
|
8199
8317
|
}
|
|
@@ -8202,11 +8320,11 @@ async function realProject(requested) {
|
|
|
8202
8320
|
const absolute = path6.resolve(requested);
|
|
8203
8321
|
let project;
|
|
8204
8322
|
try {
|
|
8205
|
-
project = await
|
|
8323
|
+
project = await fs8.realpath(absolute);
|
|
8206
8324
|
} catch (cause) {
|
|
8207
8325
|
throw invalid4(`\u9879\u76EE\u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${absolute}`, cause);
|
|
8208
8326
|
}
|
|
8209
|
-
const stat = await
|
|
8327
|
+
const stat = await fs8.stat(project);
|
|
8210
8328
|
if (!stat.isDirectory()) throw invalid4(`\u9879\u76EE\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${absolute}`);
|
|
8211
8329
|
return project;
|
|
8212
8330
|
}
|
|
@@ -8267,6 +8385,65 @@ function invalid4(message, cause) {
|
|
|
8267
8385
|
return new CliError20({ code: CliErrorCode19.INVALID_ARGUMENT, message, cause });
|
|
8268
8386
|
}
|
|
8269
8387
|
|
|
8388
|
+
// src/commands/user.ts
|
|
8389
|
+
init_auth_guard();
|
|
8390
|
+
init_exit();
|
|
8391
|
+
import {
|
|
8392
|
+
HcmClient as HcmClient17,
|
|
8393
|
+
adminResetPassword,
|
|
8394
|
+
formatObject as formatObject19,
|
|
8395
|
+
fromAxiosError as fromAxiosError17,
|
|
8396
|
+
CliError as CliError21,
|
|
8397
|
+
CliErrorCode as CliErrorCode20
|
|
8398
|
+
} from "@hcmai/sdk";
|
|
8399
|
+
function buildAdminResetPasswordRequest(args, password) {
|
|
8400
|
+
const hasId = Boolean(args.id);
|
|
8401
|
+
const hasUsername = Boolean(args.username);
|
|
8402
|
+
if (hasId === hasUsername) {
|
|
8403
|
+
throw new CliError21({
|
|
8404
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8405
|
+
message: "--id <uuid> \u4E0E --username <user> \u5FC5\u987B\u4E14\u53EA\u80FD\u63D0\u4F9B\u4E00\u4E2A"
|
|
8406
|
+
});
|
|
8407
|
+
}
|
|
8408
|
+
if (!password) {
|
|
8409
|
+
throw new CliError21({
|
|
8410
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8411
|
+
message: "\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A"
|
|
8412
|
+
});
|
|
8413
|
+
}
|
|
8414
|
+
return {
|
|
8415
|
+
...args.id ? { userId: args.id } : {},
|
|
8416
|
+
...args.username ? { username: args.username } : {},
|
|
8417
|
+
newPassword: password,
|
|
8418
|
+
confirmPassword: password,
|
|
8419
|
+
forceChangeOnNextLogin: args.forceChange !== false
|
|
8420
|
+
};
|
|
8421
|
+
}
|
|
8422
|
+
async function userResetPasswordCommand(args) {
|
|
8423
|
+
try {
|
|
8424
|
+
const password = args.passwordStdin ? await readSecretFromStdin() : await promptPasswordTwice();
|
|
8425
|
+
const request = buildAdminResetPasswordRequest(args, password);
|
|
8426
|
+
const client3 = HcmClient17.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
8427
|
+
const result2 = await adminResetPassword(client3.raw(), request);
|
|
8428
|
+
process.stdout.write(formatObject19(result2, { format: args.output ?? "json" }) + "\n");
|
|
8429
|
+
} catch (cause) {
|
|
8430
|
+
const err = cause;
|
|
8431
|
+
if (err?.isAxiosError) exitWithError(fromAxiosError17(err, args.env));
|
|
8432
|
+
exitWithError(cause);
|
|
8433
|
+
}
|
|
8434
|
+
}
|
|
8435
|
+
async function promptPasswordTwice() {
|
|
8436
|
+
const password = await promptSecret("\u65B0\u5BC6\u7801: ");
|
|
8437
|
+
const confirmation = await promptSecret("\u518D\u6B21\u8F93\u5165\u65B0\u5BC6\u7801: ");
|
|
8438
|
+
if (password !== confirmation) {
|
|
8439
|
+
throw new CliError21({
|
|
8440
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8441
|
+
message: "\u4E24\u6B21\u8F93\u5165\u7684\u65B0\u5BC6\u7801\u4E0D\u4E00\u81F4"
|
|
8442
|
+
});
|
|
8443
|
+
}
|
|
8444
|
+
return password;
|
|
8445
|
+
}
|
|
8446
|
+
|
|
8270
8447
|
// src/startup.ts
|
|
8271
8448
|
function needsLegacyProfileMigration(argv) {
|
|
8272
8449
|
const args = argv.slice(2);
|
|
@@ -8295,15 +8472,17 @@ config.command("get <key>").description("\u8BFB\u53D6\u5168\u5C40 defaults").act
|
|
|
8295
8472
|
var env = program.command("env").description("\u7BA1\u7406 HCM \u73AF\u5883\uFF08\u591A\u540E\u7AEF\u8FDE\u63A5\u914D\u7F6E\uFF09");
|
|
8296
8473
|
env.command("list").description("\u5217\u51FA\u5168\u90E8 env").action(() => envList());
|
|
8297
8474
|
env.command("current").description("\u663E\u793A\u5F53\u524D\u6FC0\u6D3B\u7684 env").action(() => envCurrent());
|
|
8298
|
-
env.command("add <name>").description("\u65B0\u589E env").option("--endpoint <url>", "HCM \u540E\u7AEF URL\uFF08\u5FC5\u586B\uFF09").option("--tenant <id>", "\u9ED8\u8BA4 tenant id", "1").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684\u540C\u540D env").action((name, opts) => envAdd(name, opts));
|
|
8475
|
+
env.command("add <name>").description("\u65B0\u589E env").option("--endpoint <url>", "HCM \u540E\u7AEF URL\uFF08\u5FC5\u586B\uFF09").option("--tenant <id>", "\u9ED8\u8BA4 tenant id", "1").option("--frontend <url>", "\u5BF9\u5E94\u524D\u7AEF URL\uFF0C\u4F8B\u5982 http://127.0.0.1:5176").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684\u540C\u540D env").action((name, opts) => envAdd(name, opts));
|
|
8299
8476
|
env.command("use <name>").description("\u5207\u5230\u6307\u5B9A env").option("--no-ping", "\u8DF3\u8FC7 endpoint \u5065\u5EB7\u68C0\u67E5").action((name, opts) => envUse(name, opts));
|
|
8300
8477
|
env.command("remove <name>").description("\u5220\u9664 env\uFF08\u7EA7\u8054\u6E05\u9664\u8BE5 env \u7684\u5168\u90E8 identity \u548C token\uFF09").option("--force", "\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A").action((name, opts) => envRemove(name, opts));
|
|
8301
8478
|
env.command("show [name]").description("\u663E\u793A env \u8BE6\u60C5\uFF08\u542B\u8BE5 env \u4E0B\u7684 identity \u5217\u8868\uFF09").action((name) => envShow({ name }));
|
|
8302
|
-
env.command("edit <field> <value>").description("\u7F16\u8F91 env \u5B57\u6BB5\uFF08endpoint / tenantId / defaultIdentity / defaultAgent\uFF09").option("--env <name>", "\u76EE\u6807 env \u540D\uFF08\u9ED8\u8BA4\u5F53\u524D activeEnv\uFF09").action((field, value, opts) => envEdit(field, value, opts));
|
|
8479
|
+
env.command("edit <field> <value>").description("\u7F16\u8F91 env \u5B57\u6BB5\uFF08endpoint / frontend / tenantId / defaultIdentity / defaultAgent\uFF09").option("--env <name>", "\u76EE\u6807 env \u540D\uFF08\u9ED8\u8BA4\u5F53\u524D activeEnv\uFF09").action((field, value, opts) => envEdit(field, value, opts));
|
|
8303
8480
|
var identity = program.command("identity").description("\u7BA1\u7406 HCM \u8EAB\u4EFD\u51ED\u636E\uFF08env \u4E0B\u7684 identity\uFF09");
|
|
8304
8481
|
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));
|
|
8305
8482
|
identity.command("use <name>").description("\u628A identity \u8BBE\u4E3A\u5176 env \u7684 default identity").action((name) => identityUse(name));
|
|
8306
8483
|
identity.command("remove <name>").description("\u5220\u9664 identity\uFF08\u6E05 token + \u82E5\u662F env default \u5219\u6E05\u7A7A\uFF09").action((name) => identityRemove(name));
|
|
8484
|
+
var user = program.command("user").description("\u7BA1\u7406\u79DF\u6237\u7528\u6237\u7684\u4E13\u7528\u51ED\u636E\u6D41\u7A0B");
|
|
8485
|
+
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));
|
|
8307
8486
|
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");
|
|
8308
8487
|
delivery.command("assess").description("\u7EAF\u672C\u5730\u8BC4\u4F30\u4E00\u6B21 HCM CLI argv\uFF1B\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));
|
|
8309
8488
|
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));
|
|
@@ -8312,8 +8491,8 @@ program.command("query <Model>").description("\u67E5\u8BE2 Model \u5217\u8868\u6
|
|
|
8312
8491
|
"--filter <JSON>",
|
|
8313
8492
|
`\u8FC7\u6EE4 AST\uFF08ModelQueryDsl\uFF09\uFF1A\u53F6\u5B50 '{"field":"status","op":"eq","value":"ACTIVE"}'\uFF0C\u591A\u6761\u4EF6\u7528 '{"and":[\u53F6\u5B50,\u2026]}'\u3002\u26A0\uFE0F \u4E0D\u63A5\u53D7 {"\u5B57\u6BB5":"\u503C"} \u7B80\u5199\uFF0Cschema \u5C42\u4F1A\u62D2`
|
|
8314
8493
|
).option("--sort <JSON>", `\u6392\u5E8F\u6761\u4EF6 JSON\uFF0C\u4F8B\u5982 '[{"field":"hireDate","direction":"desc"}]'`).option("--fields <list>", "\u8FD4\u56DE\u5B57\u6BB5\u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\uFF09\uFF0C\u4F8B\u5982 name,code,email").option("--keyword <text>", "\u5168\u6587\u68C0\u7D22\u5173\u952E\u5B57").option("--limit <n>", "\u6BCF\u9875\u5927\u5C0F", "20").option("--offset <n>", "\u504F\u79FB\u91CF\uFF08\u6309 limit \u81EA\u52A8\u6362\u7B97 page\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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--profile <name>", "[deprecated] \u7528 --env \u66FF\u4EE3").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((m, opts) => queryCommand(m, opts));
|
|
8315
|
-
program.command("action <Model.Action>").description("\u8C03\u7528 Model \u4E0A\u7684 Action\uFF08\u4E1A\u52A1\u65B9\u6CD5\uFF09\uFF0C\u4F8B\u5982 Employee.regularize").option("--id <id>", "\u76EE\u6807\u5B9E\u4F53 ID\uFF08object Action \u5FC5\u586B\uFF09").option("--ids <csv>", "\u6279\u91CF ID\uFF08\u9017\u53F7\u5206\u9694\uFF0Cbulk Action \u7528\uFF09").option("--method <method>", "HTTP \u65B9\u6CD5\uFF1AGET | POST | PUT | DELETE", "POST").option("--scope <scope>", "\u5F3A\u5236 Action scope\uFF1Aclass | object\uFF08\u9ED8\u8BA4\uFF1A\u6709 --id \u4E3A object\uFF0C\u5426\u5219 class\uFF09").option("--params <JSON>", `Action \u5165\u53C2 JSON\uFF0C\u4F8B\u5982 '{"effectDate":"2026-06-01"}'`).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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--profile <name>", "[deprecated] \u7528 --env \u66FF\u4EE3").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((spec, opts) => actionCommand(spec, opts));
|
|
8316
|
-
program.command("create <Model>").description("\u521B\u5EFA\u4E00\u6761 Model \u8BB0\u5F55\uFF08\u8D70\u540E\u7AEF\u5B8C\u6574\u6821\u9A8C\uFF09").option("--data <JSON>", `\u8BB0\u5F55\u5B57\u6BB5 JSON\uFF0C\u4F8B\u5982 '{"code":"ORG_SALES","name":"\u9500\u552E\u90E8"}'`).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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--profile <name>", "[deprecated] \u7528 --env \u66FF\u4EE3").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((m, opts) => createCommand(m, opts));
|
|
8494
|
+
program.command("action <Model.Action>").description("\u8C03\u7528 Model \u4E0A\u7684 Action\uFF08\u4E1A\u52A1\u65B9\u6CD5\uFF09\uFF0C\u4F8B\u5982 Employee.regularize").option("--id <id>", "\u76EE\u6807\u5B9E\u4F53 ID\uFF08object Action \u5FC5\u586B\uFF09").option("--ids <csv>", "\u6279\u91CF ID\uFF08\u9017\u53F7\u5206\u9694\uFF0Cbulk Action \u7528\uFF09").option("--method <method>", "HTTP \u65B9\u6CD5\uFF1AGET | POST | PUT | DELETE", "POST").option("--scope <scope>", "\u5F3A\u5236 Action scope\uFF1Aclass | object\uFF08\u9ED8\u8BA4\uFF1A\u6709 --id \u4E3A object\uFF0C\u5426\u5219 class\uFF09").option("--params <JSON>", `Action \u5165\u53C2 JSON\uFF0C\u4F8B\u5982 '{"effectDate":"2026-06-01"}'`).option("--params-file <path>", "\u4ECE UTF-8 JSON \u6587\u4EF6\u8BFB\u53D6 Action \u5165\u53C2\uFF08\u4E0E --params \u4E92\u65A5\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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--profile <name>", "[deprecated] \u7528 --env \u66FF\u4EE3").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((spec, opts) => actionCommand(spec, opts));
|
|
8495
|
+
program.command("create <Model>").description("\u521B\u5EFA\u4E00\u6761 Model \u8BB0\u5F55\uFF08\u8D70\u540E\u7AEF\u5B8C\u6574\u6821\u9A8C\uFF09").option("--data <JSON>", `\u8BB0\u5F55\u5B57\u6BB5 JSON\uFF0C\u4F8B\u5982 '{"code":"ORG_SALES","name":"\u9500\u552E\u90E8"}'`).option("--data-file <path>", "\u4ECE UTF-8 JSON \u6587\u4EF6\u8BFB\u53D6\u8BB0\u5F55\u5B57\u6BB5\uFF08\u4E0E --data \u4E92\u65A5\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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--profile <name>", "[deprecated] \u7528 --env \u66FF\u4EE3").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((m, opts) => createCommand(m, opts));
|
|
8317
8496
|
program.command("delete <Model>").description("\u5220\u9664\u4E00\u6761 Model \u8BB0\u5F55\uFF08\u8D70\u540E\u7AEF\u5B8C\u6574\u6821\u9A8C\uFF1B\u90E8\u5206 Model \u4F1A\u6267\u884C\u4E1A\u52A1\u64A4\u9500\uFF09").option("--id <id>", "\u76EE\u6807\u5B9E\u4F53 ID\uFF08\u5FC5\u586B\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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--profile <name>", "[deprecated] \u7528 --env \u66FF\u4EE3").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((m, opts) => deleteCommand(m, opts));
|
|
8318
8497
|
program.command("import <path>").description("\u6CE8\u5165 DataPackage YAML \u6570\u636E\u96C6\uFF08\u76EE\u5F55\u6216\u5355\u6587\u4EF6\uFF0C\u8D70\u540E\u7AEF\u5B8C\u6574\u6821\u9A8C\uFF09").option("--dry-run", "\u53EA\u8DD1\u5BA2\u6237\u7AEF\u9759\u6001\u6821\u9A8C\uFF0C\u4E0D\u843D\u5E93\uFF08\u89C1 spec \xA78 \u9650\u5236\uFF09").option("--update-only", "\u5DF2\u5B58\u5728\uFF08\u6309 key_field\uFF09\u5219 PUT \u66F4\u65B0\uFF0C\u5426\u5219 create").option("--on-error <mode>", "stop | continue\uFF08\u9ED8\u8BA4 continue\uFF09", "continue").option("--report <path>", "\u5199 JSON \u6CE8\u5165\u62A5\u544A\uFF08\u9010\u884C\u7ED3\u679C + key\u2192id \u6620\u5C04\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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--profile <name>", "[deprecated] \u7528 --env \u66FF\u4EE3").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((p, opts) => importCommand(p, opts));
|
|
8319
8498
|
program.command("describe <Model>").description("\u67E5\u770B Model \u5143\u6570\u636E\uFF08\u5B57\u6BB5\u3001\u5173\u7CFB\u3001Action \u5217\u8868\uFF09").option("-v, --verbose", "\u663E\u793A\u5B57\u6BB5\u63CF\u8FF0\u4E0E enum \u53D6\u503C").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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--profile <name>", "[deprecated] \u7528 --env \u66FF\u4EE3").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((m, opts) => describeCommand(m, opts));
|
|
@@ -8373,7 +8552,7 @@ skills.command("show <id>").description("\u6253\u5370\u6280\u80FD\u539F\u6587\uF
|
|
|
8373
8552
|
skills.command("install [id]").description("\u8FDE\u540C requires \u524D\u7F6E\u6280\u80FD\u4E0E\u53C2\u8003\u6587\u4EF6\u88C5\u5230 agent \u6280\u80FD\u76EE\u5F55\uFF1B--all \u88C5\u6574\u4E2A\u6280\u80FD\u5E93").option("--all", "\u88C5\u6574\u4E2A\u6280\u80FD\u5E93\uFF0C\u5E76\u8BB0\u4E3A\u300C\u8DDF\u968F\u5168\u96C6\u300D\uFF08\u5F80\u540E update \u4F1A\u81EA\u52A8\u8865\u4E0A\u4EA7\u54C1\u65B0\u589E\u7684\u6280\u80FD\uFF09").option("--target <agent>", "\u88C5\u7ED9\u54EA\u4E2A agent\uFF1Aclaude\uFF08.claude/skills/\uFF09| codex\uFF08hcm-skills/ + AGENTS.md\uFF09| auto", "auto").option("--global", "\u88C5\u5230\u7528\u6237\u7EA7\u76EE\u5F55\u800C\u975E\u5F53\u524D\u9879\u76EE").option("--dir <path>", "\u88C5\u5230\u6307\u5B9A\u76EE\u5F55").option("--from <dir>", "\u4ECE\u672C\u5730\u76EE\u5F55\u88C5\uFF08\u73B0\u573A\u6539\u8FC7\u7684\u7248\u672C\uFF09\uFF0C\u4E0D\u8D70\u7F51\u7EDC").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684\u540C\u540D\u6280\u80FD").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6 activeEnv \u7684 endpoint\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((id, opts) => skillsInstallCommand(id, opts));
|
|
8374
8553
|
skills.command("sync <id>").description("\u4ECE\u76EE\u6807\u5B9E\u4F8B\u540C\u6B65 Skill \u95ED\u5305\u5230 WorkBuddy \u9879\u76EE\u5E76\u5199 chiron.lock").requiredOption("--target <agent>", "\u76EE\u6807 Agent \u5BBF\u4E3B\uFF1B\u5F53\u524D\u652F\u6301 workbuddy").requiredOption("--project <path>", "WorkBuddy \u9879\u76EE\u6839\u76EE\u5F55").option("--cli <path>", "\u663E\u5F0F\u6307\u5B9A\u8981\u9501\u5B9A\u5230\u9879\u76EE\u7684 HCM CLI\uFF1B\u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u8FD9\u4EFD CLI").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6 activeEnv \u7684 endpoint\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((id, opts) => skillsSyncCommand(id, opts));
|
|
8375
8554
|
skills.command("update").description("\u628A\u88C5\u8FC7\u7684\u6280\u80FD\u5347\u5230\u76EE\u6807\u73AF\u5883\u8FD9\u4E00\u7248\uFF08\u4EA7\u54C1\u5347\u7EA7\u540E\u8DD1\u5B83\uFF09").option("--all", "\u8FDE\u4EA7\u54C1\u65B0\u589E\u7684\u6280\u80FD\u4E00\u8D77\u88C5\u4E0A\uFF0C\u5E76\u8BB0\u4E3A\u300C\u8DDF\u968F\u5168\u96C6\u300D").option("--check", "\u53EA\u770B\u4F1A\u53D8\u4EC0\u4E48\uFF0C\u4E0D\u5199\u76D8").option("--target <agent>", "claude | codex | auto\uFF08\u9ED8\u8BA4\u6309\u5DF2\u5B89\u88C5\u76EE\u5F55\u63A2\uFF09", "auto").option("--global", "\u5347\u7EA7\u7528\u6237\u7EA7\u76EE\u5F55\u91CC\u7684\u6280\u80FD").option("--dir <path>", "\u5347\u7EA7\u6307\u5B9A\u76EE\u5F55\u91CC\u7684\u6280\u80FD").option("--force", "\u8FDE\u672C\u5730\u6539\u8FC7\u7684\u6280\u80FD\u4E00\u8D77\u8986\u76D6\u6210\u4EA7\u54C1\u8FD9\u4E00\u7248").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6\u5B89\u88C5\u65F6\u8BB0\u5F55\u7684\u5730\u5740\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((opts) => skillsUpdateCommand(opts));
|
|
8376
|
-
program.command("update <Model>").description("\u66F4\u65B0\u4E00\u6761 Model \u8BB0\u5F55\uFF08\u8D70\u540E\u7AEF\u5B8C\u6574\u6821\u9A8C\uFF09").requiredOption("--id <id>", "\u8BB0\u5F55 ID").
|
|
8555
|
+
program.command("update <Model>").description("\u66F4\u65B0\u4E00\u6761 Model \u8BB0\u5F55\uFF08\u8D70\u540E\u7AEF\u5B8C\u6574\u6821\u9A8C\uFF09").requiredOption("--id <id>", "\u8BB0\u5F55 ID").option("--data <JSON>", `\u8981\u66F4\u65B0\u7684\u5B57\u6BB5 JSON\uFF0C\u4F8B\u5982 '{"name":"\u65B0\u540D\u79F0"}'`).option("--data-file <path>", "\u4ECE UTF-8 JSON \u6587\u4EF6\u8BFB\u53D6\u66F4\u65B0\u5B57\u6BB5\uFF08\u4E0E --data \u4E92\u65A5\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\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((model, opts) => updateCommand(model, opts));
|
|
8377
8556
|
program.command("version").description("\u67E5\u540E\u7AEF\u7248\u672C\uFF08commit / tag / \u6784\u5EFA\u65F6\u95F4\uFF09\u2014\u2014\u514D\u8BA4\u8BC1\uFF0C\u65E0\u9700\u5148 login").option("--endpoint <url>", "\u540E\u7AEF\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6 activeEnv \u7684 endpoint\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((opts) => versionCommand(opts));
|
|
8378
8557
|
var setting = program.command("setting").description("\u79DF\u6237\u7CFB\u7EDF\u53C2\u6570\uFF08\u767B\u5F55\u7B56\u7565 / \u5BC6\u7801\u7B56\u7565 / \u529F\u80FD\u5F00\u5173 / \u96C6\u6210\u53C2\u6570\uFF09");
|
|
8379
8558
|
setting.command("get <domain>").description("\u8BFB\u67D0\u57DF\u53C2\u6570\uFF08\u5B9A\u4E49 + \u79DF\u6237\u8986\u76D6\u503C\u5408\u5E76\uFF0C\u7F3A\u5931\u56DE\u843D\u9ED8\u8BA4\u503C\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").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((d, opts) => settingGetCommand(d, opts));
|