@hcmai/cli 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +234 -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);
|
|
@@ -2398,6 +2398,7 @@ async function envList() {
|
|
|
2398
2398
|
active: name === g.activeEnv ? "*" : " ",
|
|
2399
2399
|
name,
|
|
2400
2400
|
endpoint: cfg.endpoint,
|
|
2401
|
+
frontend: cfg.frontend ?? "(none)",
|
|
2401
2402
|
tenant: cfg.tenantId ?? "1",
|
|
2402
2403
|
identity: cfg.defaultIdentity ?? "(none)"
|
|
2403
2404
|
};
|
|
@@ -2417,7 +2418,8 @@ async function envCurrent() {
|
|
|
2417
2418
|
return;
|
|
2418
2419
|
}
|
|
2419
2420
|
const idName = cfg.defaultIdentity ?? "(none)";
|
|
2420
|
-
|
|
2421
|
+
const frontend = cfg.frontend ? ` frontend=${cfg.frontend}` : "";
|
|
2422
|
+
exitOk(`\u2192 ${g.activeEnv} ${cfg.endpoint}${frontend} tenant=${cfg.tenantId ?? "1"} identity=${idName}`);
|
|
2421
2423
|
} catch (e) {
|
|
2422
2424
|
exitWithError(e);
|
|
2423
2425
|
}
|
|
@@ -2437,7 +2439,11 @@ async function envAdd(name, args) {
|
|
|
2437
2439
|
message: `env '${name}' already exists. Use --force to overwrite.`
|
|
2438
2440
|
});
|
|
2439
2441
|
}
|
|
2440
|
-
await saveEnv2(name, {
|
|
2442
|
+
await saveEnv2(name, {
|
|
2443
|
+
endpoint: args.endpoint,
|
|
2444
|
+
frontend: args.frontend,
|
|
2445
|
+
tenantId: args.tenant ?? "1"
|
|
2446
|
+
});
|
|
2441
2447
|
const allEnvs = await listEnvs();
|
|
2442
2448
|
const g = await loadGlobalConfig2();
|
|
2443
2449
|
const activeExists = allEnvs.includes(g.activeEnv);
|
|
@@ -2539,7 +2545,7 @@ async function envShow(args) {
|
|
|
2539
2545
|
}
|
|
2540
2546
|
async function envEdit(field, value, args) {
|
|
2541
2547
|
try {
|
|
2542
|
-
const ALLOWED = /* @__PURE__ */ new Set(["endpoint", "tenantId", "defaultIdentity", "defaultAgent"]);
|
|
2548
|
+
const ALLOWED = /* @__PURE__ */ new Set(["endpoint", "frontend", "tenantId", "defaultIdentity", "defaultAgent"]);
|
|
2543
2549
|
if (!ALLOWED.has(field)) {
|
|
2544
2550
|
throw new CliError3({
|
|
2545
2551
|
code: CliErrorCode2.INVALID_ARGUMENT,
|
|
@@ -2674,21 +2680,75 @@ import {
|
|
|
2674
2680
|
HcmClient as HcmClient2,
|
|
2675
2681
|
formatObject,
|
|
2676
2682
|
fromAxiosError as fromAxiosError2,
|
|
2677
|
-
CliError as
|
|
2678
|
-
CliErrorCode as
|
|
2683
|
+
CliError as CliError8,
|
|
2684
|
+
CliErrorCode as CliErrorCode7
|
|
2679
2685
|
} from "@hcmai/sdk";
|
|
2686
|
+
|
|
2687
|
+
// src/utils/json-input.ts
|
|
2688
|
+
import * as fs from "fs/promises";
|
|
2689
|
+
import { CliError as CliError7, CliErrorCode as CliErrorCode6 } from "@hcmai/sdk";
|
|
2690
|
+
async function readJsonObjectInput(options) {
|
|
2691
|
+
const { inline, file, inlineFlag, fileFlag, required = true } = options;
|
|
2692
|
+
if (inline && file) {
|
|
2693
|
+
throw new CliError7({
|
|
2694
|
+
code: CliErrorCode6.INVALID_ARGUMENT,
|
|
2695
|
+
message: `${inlineFlag} \u4E0E ${fileFlag} \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528`
|
|
2696
|
+
});
|
|
2697
|
+
}
|
|
2698
|
+
if (!inline && !file) {
|
|
2699
|
+
if (!required) return void 0;
|
|
2700
|
+
throw new CliError7({
|
|
2701
|
+
code: CliErrorCode6.MISSING_FLAG,
|
|
2702
|
+
message: `${inlineFlag} <JSON> \u6216 ${fileFlag} <path> \u5FC5\u586B`
|
|
2703
|
+
});
|
|
2704
|
+
}
|
|
2705
|
+
let raw;
|
|
2706
|
+
let sourceFlag;
|
|
2707
|
+
if (file) {
|
|
2708
|
+
sourceFlag = fileFlag;
|
|
2709
|
+
try {
|
|
2710
|
+
raw = await fs.readFile(file, "utf-8");
|
|
2711
|
+
} catch (error) {
|
|
2712
|
+
throw new CliError7({
|
|
2713
|
+
code: CliErrorCode6.INVALID_ARGUMENT,
|
|
2714
|
+
message: `${fileFlag}: \u65E0\u6CD5\u8BFB\u53D6 ${file}: ${error.message}`
|
|
2715
|
+
});
|
|
2716
|
+
}
|
|
2717
|
+
} else {
|
|
2718
|
+
sourceFlag = inlineFlag;
|
|
2719
|
+
raw = inline;
|
|
2720
|
+
}
|
|
2721
|
+
let parsed;
|
|
2722
|
+
try {
|
|
2723
|
+
parsed = JSON.parse(raw);
|
|
2724
|
+
} catch (error) {
|
|
2725
|
+
throw new CliError7({
|
|
2726
|
+
code: CliErrorCode6.INVALID_JSON,
|
|
2727
|
+
message: `${sourceFlag}: ${error.message}`
|
|
2728
|
+
});
|
|
2729
|
+
}
|
|
2730
|
+
if (parsed === null || Array.isArray(parsed) || typeof parsed !== "object") {
|
|
2731
|
+
throw new CliError7({
|
|
2732
|
+
code: CliErrorCode6.INVALID_JSON,
|
|
2733
|
+
message: `${sourceFlag}: \u9876\u5C42\u5FC5\u987B\u662F JSON \u5BF9\u8C61`
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2736
|
+
return parsed;
|
|
2737
|
+
}
|
|
2738
|
+
|
|
2739
|
+
// src/commands/action.ts
|
|
2680
2740
|
async function actionCommand(spec, args) {
|
|
2681
2741
|
try {
|
|
2682
2742
|
const [model, action] = spec.split(".");
|
|
2683
2743
|
if (!model || !action) {
|
|
2684
|
-
throw new
|
|
2685
|
-
code:
|
|
2744
|
+
throw new CliError8({
|
|
2745
|
+
code: CliErrorCode7.INVALID_ARGUMENT,
|
|
2686
2746
|
message: "expected <Model>.<Action> (e.g. Employee.regularize)"
|
|
2687
2747
|
});
|
|
2688
2748
|
}
|
|
2689
2749
|
if (args.id && args.ids) {
|
|
2690
|
-
throw new
|
|
2691
|
-
code:
|
|
2750
|
+
throw new CliError8({
|
|
2751
|
+
code: CliErrorCode7.INVALID_ARGUMENT,
|
|
2692
2752
|
message: "--id and --ids are mutually exclusive"
|
|
2693
2753
|
});
|
|
2694
2754
|
}
|
|
@@ -2698,16 +2758,14 @@ async function actionCommand(spec, args) {
|
|
|
2698
2758
|
if (scope) input.scope = scope;
|
|
2699
2759
|
if (args.id) input.id = args.id;
|
|
2700
2760
|
if (args.ids) input.ids = args.ids.split(",").map((s) => s.trim());
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
}
|
|
2710
|
-
}
|
|
2761
|
+
const params = await readJsonObjectInput({
|
|
2762
|
+
inline: args.params,
|
|
2763
|
+
file: args.paramsFile,
|
|
2764
|
+
inlineFlag: "--params",
|
|
2765
|
+
fileFlag: "--params-file",
|
|
2766
|
+
required: false
|
|
2767
|
+
});
|
|
2768
|
+
if (params) input.params = params;
|
|
2711
2769
|
const client3 = HcmClient2.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
2712
2770
|
const result2 = await client3.action(model, action, input);
|
|
2713
2771
|
const fmt = args.output ?? "json";
|
|
@@ -2732,16 +2790,16 @@ async function actionCommand(spec, args) {
|
|
|
2732
2790
|
function normalizeMethod(value) {
|
|
2733
2791
|
const raw = (value ?? "POST").toUpperCase();
|
|
2734
2792
|
if (raw === "GET" || raw === "POST" || raw === "PUT" || raw === "DELETE") return raw;
|
|
2735
|
-
throw new
|
|
2736
|
-
code:
|
|
2793
|
+
throw new CliError8({
|
|
2794
|
+
code: CliErrorCode7.INVALID_ARGUMENT,
|
|
2737
2795
|
message: `--method \u53D6\u503C GET | POST | PUT | DELETE\uFF0C\u6536\u5230 "${value}"`
|
|
2738
2796
|
});
|
|
2739
2797
|
}
|
|
2740
2798
|
function normalizeScope(value) {
|
|
2741
2799
|
if (value === void 0) return void 0;
|
|
2742
2800
|
if (value === "class" || value === "object") return value;
|
|
2743
|
-
throw new
|
|
2744
|
-
code:
|
|
2801
|
+
throw new CliError8({
|
|
2802
|
+
code: CliErrorCode7.INVALID_ARGUMENT,
|
|
2745
2803
|
message: `--scope \u53D6\u503C class | object\uFF0C\u6536\u5230 "${value}"`
|
|
2746
2804
|
});
|
|
2747
2805
|
}
|
|
@@ -2749,28 +2807,19 @@ function normalizeScope(value) {
|
|
|
2749
2807
|
// src/commands/create.ts
|
|
2750
2808
|
init_exit();
|
|
2751
2809
|
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";
|
|
2810
|
+
import { HcmClient as HcmClient3, formatObject as formatObject2, fromAxiosError as fromAxiosError3 } from "@hcmai/sdk";
|
|
2759
2811
|
async function createCommand(model, args) {
|
|
2760
2812
|
try {
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
} catch (e) {
|
|
2768
|
-
throw new CliError8({ code: CliErrorCode7.INVALID_JSON, message: `--data: ${e.message}` });
|
|
2769
|
-
}
|
|
2813
|
+
const data = await readJsonObjectInput({
|
|
2814
|
+
inline: args.data,
|
|
2815
|
+
file: args.dataFile,
|
|
2816
|
+
inlineFlag: "--data",
|
|
2817
|
+
fileFlag: "--data-file"
|
|
2818
|
+
});
|
|
2770
2819
|
const client3 = HcmClient3.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
2771
2820
|
const res = await client3.create(model, data);
|
|
2772
2821
|
const fmt = args.output ?? "json";
|
|
2773
|
-
process.stdout.write("\u2705 created\n");
|
|
2822
|
+
if (fmt !== "json") process.stdout.write("\u2705 created\n");
|
|
2774
2823
|
process.stdout.write(formatObject2(res, { format: fmt }) + "\n");
|
|
2775
2824
|
process.exit(0);
|
|
2776
2825
|
} catch (e) {
|
|
@@ -2795,18 +2844,12 @@ async function updateCommand(model, args) {
|
|
|
2795
2844
|
if (!args.id) {
|
|
2796
2845
|
throw new CliError9({ code: CliErrorCode8.MISSING_FLAG, message: "--id <id> \u5FC5\u586B" });
|
|
2797
2846
|
}
|
|
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
|
-
}
|
|
2847
|
+
const data = await readJsonObjectInput({
|
|
2848
|
+
inline: args.data,
|
|
2849
|
+
file: args.dataFile,
|
|
2850
|
+
inlineFlag: "--data",
|
|
2851
|
+
fileFlag: "--data-file"
|
|
2852
|
+
});
|
|
2810
2853
|
const client3 = HcmClient4.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
2811
2854
|
const result2 = await client3.update(model, args.id, data);
|
|
2812
2855
|
const fmt = args.output ?? "json";
|
|
@@ -2989,7 +3032,7 @@ async function deleteCommand(model, args) {
|
|
|
2989
3032
|
const client3 = HcmClient6.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
2990
3033
|
const res = await client3.remove(model, args.id);
|
|
2991
3034
|
const fmt = args.output ?? "json";
|
|
2992
|
-
process.stdout.write("\u2705 deleted\n");
|
|
3035
|
+
if (fmt !== "json") process.stdout.write("\u2705 deleted\n");
|
|
2993
3036
|
process.stdout.write(formatObject6(res, { format: fmt }) + "\n");
|
|
2994
3037
|
process.exit(0);
|
|
2995
3038
|
} catch (e) {
|
|
@@ -3061,7 +3104,11 @@ async function importCommand(path7, args) {
|
|
|
3061
3104
|
// src/commands/describe.ts
|
|
3062
3105
|
init_exit();
|
|
3063
3106
|
init_auth_guard();
|
|
3064
|
-
import {
|
|
3107
|
+
import {
|
|
3108
|
+
HcmClient as HcmClient8,
|
|
3109
|
+
formatObject as formatObject8,
|
|
3110
|
+
fromAxiosError as fromAxiosError9
|
|
3111
|
+
} from "@hcmai/sdk";
|
|
3065
3112
|
async function describeCommand(model, args) {
|
|
3066
3113
|
try {
|
|
3067
3114
|
const client3 = HcmClient8.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
@@ -3071,25 +3118,7 @@ async function describeCommand(model, args) {
|
|
|
3071
3118
|
process.stdout.write(formatObject8(desc, { format: fmt }) + "\n");
|
|
3072
3119
|
process.exit(0);
|
|
3073
3120
|
}
|
|
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");
|
|
3121
|
+
process.stdout.write(formatDescriptionTable(desc, !!args.verbose) + "\n");
|
|
3093
3122
|
process.exit(0);
|
|
3094
3123
|
} catch (e) {
|
|
3095
3124
|
const err = e;
|
|
@@ -3099,6 +3128,28 @@ async function describeCommand(model, args) {
|
|
|
3099
3128
|
exitWithError(e);
|
|
3100
3129
|
}
|
|
3101
3130
|
}
|
|
3131
|
+
function formatDescriptionTable(desc, verbose = false) {
|
|
3132
|
+
const lines = [`=== ${desc.model} ===`];
|
|
3133
|
+
if (desc.labels.zh_CN) lines.push(`zh_CN: ${desc.labels.zh_CN}`);
|
|
3134
|
+
if (desc.labels.en) lines.push(`en: ${desc.labels.en}`);
|
|
3135
|
+
lines.push(`fields (${desc.fields.length}):`);
|
|
3136
|
+
for (const f of desc.fields) {
|
|
3137
|
+
const req = f.required ? " required" : " ";
|
|
3138
|
+
const lbl = verbose ? ` ${f.label ?? ""} ${f.description ?? ""}` : ` ${f.label ?? ""}`;
|
|
3139
|
+
lines.push(` ${f.name.padEnd(20)} ${f.type.padEnd(10)} ${req}${lbl}`);
|
|
3140
|
+
}
|
|
3141
|
+
lines.push(`actions (${desc.actions.length}):`);
|
|
3142
|
+
for (const a of desc.actions) {
|
|
3143
|
+
const call = [a.scope, a.httpMethod].filter(Boolean).join(" ");
|
|
3144
|
+
const params = a.params?.length ? ` params: ${a.params.map((p) => `${p.name}:${p.type}`).join(", ")}` : "";
|
|
3145
|
+
const description = verbose && a.description ? ` ${a.description}` : "";
|
|
3146
|
+
lines.push(` ${a.name.padEnd(20)} ${call.padEnd(12)} ${a.label ?? ""}${params}${description}`);
|
|
3147
|
+
}
|
|
3148
|
+
if (desc.relations.length) {
|
|
3149
|
+
lines.push(`relations: ${desc.relations.map((r) => `${r.key}(via ${r.via})`).join(", ")}`);
|
|
3150
|
+
}
|
|
3151
|
+
return lines.join("\n");
|
|
3152
|
+
}
|
|
3102
3153
|
|
|
3103
3154
|
// src/commands/chat.ts
|
|
3104
3155
|
init_exit();
|
|
@@ -3128,7 +3179,7 @@ import {
|
|
|
3128
3179
|
buildSteer
|
|
3129
3180
|
} from "@hcmai/sdk";
|
|
3130
3181
|
import chalk2 from "chalk";
|
|
3131
|
-
import * as
|
|
3182
|
+
import * as fs4 from "fs/promises";
|
|
3132
3183
|
function parseInjectOn(s) {
|
|
3133
3184
|
const fail5 = (detail) => {
|
|
3134
3185
|
throw new CliError13({
|
|
@@ -3404,7 +3455,7 @@ async function chatCommand(prompt, args) {
|
|
|
3404
3455
|
return runInkRepl2(args);
|
|
3405
3456
|
}
|
|
3406
3457
|
if (args.promptFile) {
|
|
3407
|
-
prompt = await
|
|
3458
|
+
prompt = await fs4.readFile(args.promptFile, "utf-8");
|
|
3408
3459
|
}
|
|
3409
3460
|
if (prompt === void 0 || !prompt && !regenerateMode) {
|
|
3410
3461
|
throw new CliError13({
|
|
@@ -4235,7 +4286,7 @@ import {
|
|
|
4235
4286
|
resolveChironBase,
|
|
4236
4287
|
assertSafeSkillId as assertSafeSkillId2,
|
|
4237
4288
|
assertSafeReferencePath,
|
|
4238
|
-
normalizeReferences,
|
|
4289
|
+
normalizeReferences as normalizeReferences2,
|
|
4239
4290
|
parseSkillRequirements,
|
|
4240
4291
|
parseSkillFrontmatter,
|
|
4241
4292
|
resolveSkillInstallOrder as resolveSkillInstallOrder2,
|
|
@@ -4254,16 +4305,17 @@ import {
|
|
|
4254
4305
|
|
|
4255
4306
|
// src/commands/skills-sync.ts
|
|
4256
4307
|
import { createHash } from "crypto";
|
|
4257
|
-
import { promises as
|
|
4308
|
+
import { promises as fs5 } from "fs";
|
|
4258
4309
|
import path2 from "path";
|
|
4259
4310
|
import {
|
|
4260
4311
|
CliError as CliError14,
|
|
4261
4312
|
CliErrorCode as CliErrorCode13,
|
|
4262
4313
|
assertSafeSkillFilePath,
|
|
4263
4314
|
assertSafeSkillId,
|
|
4315
|
+
normalizeReferences,
|
|
4264
4316
|
resolveSkillInstallOrder
|
|
4265
4317
|
} from "@hcmai/sdk";
|
|
4266
|
-
async function prepareSkillDocuments(catalog, requestedSkill, fetchMarkdown, fetchFile) {
|
|
4318
|
+
async function prepareSkillDocuments(catalog, requestedSkill, fetchMarkdown, fetchFile, fetchReference) {
|
|
4267
4319
|
const order = resolveSkillInstallOrder(catalog, requestedSkill);
|
|
4268
4320
|
for (const skill of order) {
|
|
4269
4321
|
if (skill.actionSurface !== "cli") {
|
|
@@ -4276,13 +4328,32 @@ async function prepareSkillDocuments(catalog, requestedSkill, fetchMarkdown, fet
|
|
|
4276
4328
|
if (skill.files === void 0) {
|
|
4277
4329
|
const markdown2 = await fetchMarkdown(skill.id);
|
|
4278
4330
|
const content = Buffer.from(markdown2, "utf8");
|
|
4331
|
+
const references = normalizeReferences(skill.references, skill.id);
|
|
4332
|
+
if (references.length > 0 && !fetchReference) {
|
|
4333
|
+
throw invalid(`\u6280\u80FD ${skill.id} \u58F0\u660E\u4E86 references\uFF0C\u4F46\u8C03\u7528\u65B9\u6CA1\u6709\u53C2\u8003\u6587\u4EF6\u4E0B\u8F7D\u80FD\u529B`);
|
|
4334
|
+
}
|
|
4335
|
+
const referenceFiles = await Promise.all(
|
|
4336
|
+
references.map(async (relativePath) => {
|
|
4337
|
+
const targetPath = `references/${relativePath}`;
|
|
4338
|
+
assertSafeSkillFilePath(targetPath);
|
|
4339
|
+
const fetched = await fetchReference(skill.id, relativePath);
|
|
4340
|
+
const referenceContent = Buffer.isBuffer(fetched) ? Buffer.from(fetched) : Buffer.from(fetched, "utf8");
|
|
4341
|
+
return {
|
|
4342
|
+
path: targetPath,
|
|
4343
|
+
content: referenceContent,
|
|
4344
|
+
bytes: referenceContent.length,
|
|
4345
|
+
sha256: sha256(referenceContent)
|
|
4346
|
+
};
|
|
4347
|
+
})
|
|
4348
|
+
);
|
|
4279
4349
|
files = [
|
|
4280
4350
|
{
|
|
4281
4351
|
path: "SKILL.md",
|
|
4282
4352
|
content,
|
|
4283
4353
|
bytes: content.length,
|
|
4284
4354
|
sha256: sha256(content)
|
|
4285
|
-
}
|
|
4355
|
+
},
|
|
4356
|
+
...referenceFiles
|
|
4286
4357
|
];
|
|
4287
4358
|
} else {
|
|
4288
4359
|
if (!Array.isArray(skill.files) || skill.files.length === 0) {
|
|
@@ -4404,8 +4475,8 @@ async function syncWorkBuddyProject(input) {
|
|
|
4404
4475
|
return result(false, input, project, skillsDir, lockPath, [], []);
|
|
4405
4476
|
}
|
|
4406
4477
|
const obsolete = [...oldOwned].filter((file) => !desiredByFile.has(file));
|
|
4407
|
-
await
|
|
4408
|
-
const staging = await
|
|
4478
|
+
await fs5.mkdir(metaDir, { recursive: true });
|
|
4479
|
+
const staging = await fs5.mkdtemp(path2.join(metaDir, ".staging-"));
|
|
4409
4480
|
const stagedFiles = path2.join(staging, "new");
|
|
4410
4481
|
const backups = path2.join(staging, "backup");
|
|
4411
4482
|
const stagedLock = path2.join(staging, "chiron.lock.json");
|
|
@@ -4414,28 +4485,28 @@ async function syncWorkBuddyProject(input) {
|
|
|
4414
4485
|
try {
|
|
4415
4486
|
for (const [file, preparedFile2] of desiredByFile) {
|
|
4416
4487
|
const staged = path2.join(stagedFiles, file);
|
|
4417
|
-
await
|
|
4418
|
-
await
|
|
4488
|
+
await fs5.mkdir(path2.dirname(staged), { recursive: true });
|
|
4489
|
+
await fs5.writeFile(
|
|
4419
4490
|
staged,
|
|
4420
4491
|
preparedFile2.content,
|
|
4421
4492
|
preparedFile2.mode === void 0 ? void 0 : { mode: preparedFile2.mode }
|
|
4422
4493
|
);
|
|
4423
4494
|
}
|
|
4424
|
-
await
|
|
4495
|
+
await fs5.writeFile(stagedLock, `${JSON.stringify(newLock, null, 2)}
|
|
4425
4496
|
`, "utf8");
|
|
4426
4497
|
const affected = [.../* @__PURE__ */ new Set([...desiredFiles, ...obsolete])];
|
|
4427
4498
|
for (const file of affected) {
|
|
4428
4499
|
const target = path2.join(project, file);
|
|
4429
4500
|
if (!await exists(target)) continue;
|
|
4430
4501
|
const backup = path2.join(backups, file);
|
|
4431
|
-
await
|
|
4432
|
-
await
|
|
4502
|
+
await fs5.mkdir(path2.dirname(backup), { recursive: true });
|
|
4503
|
+
await fs5.copyFile(target, backup);
|
|
4433
4504
|
}
|
|
4434
4505
|
const oldLockExisted = await exists(lockPath);
|
|
4435
4506
|
if (oldLockExisted) {
|
|
4436
4507
|
const backupLock = path2.join(backups, ".hcm-delivery", "chiron.lock.json");
|
|
4437
|
-
await
|
|
4438
|
-
await
|
|
4508
|
+
await fs5.mkdir(path2.dirname(backupLock), { recursive: true });
|
|
4509
|
+
await fs5.copyFile(lockPath, backupLock);
|
|
4439
4510
|
}
|
|
4440
4511
|
const journal = {
|
|
4441
4512
|
schemaVersion: 1,
|
|
@@ -4443,25 +4514,25 @@ async function syncWorkBuddyProject(input) {
|
|
|
4443
4514
|
affectedFiles: affected,
|
|
4444
4515
|
oldLockExisted
|
|
4445
4516
|
};
|
|
4446
|
-
await
|
|
4517
|
+
await fs5.writeFile(journalPath, `${JSON.stringify(journal, null, 2)}
|
|
4447
4518
|
`, "utf8");
|
|
4448
4519
|
journalReady = true;
|
|
4449
4520
|
for (const file of desiredFiles) {
|
|
4450
4521
|
const target = path2.join(project, file);
|
|
4451
|
-
await
|
|
4452
|
-
await
|
|
4453
|
-
await
|
|
4454
|
-
}
|
|
4455
|
-
for (const file of obsolete) await
|
|
4456
|
-
await
|
|
4457
|
-
await
|
|
4458
|
-
await
|
|
4522
|
+
await fs5.mkdir(path2.dirname(target), { recursive: true });
|
|
4523
|
+
await fs5.rm(target, { force: true });
|
|
4524
|
+
await fs5.rename(path2.join(stagedFiles, file), target);
|
|
4525
|
+
}
|
|
4526
|
+
for (const file of obsolete) await fs5.unlink(path2.join(project, file)).catch(ignoreMissing);
|
|
4527
|
+
await fs5.rm(lockPath, { force: true });
|
|
4528
|
+
await fs5.rename(stagedLock, lockPath);
|
|
4529
|
+
await fs5.unlink(journalPath);
|
|
4459
4530
|
journalReady = false;
|
|
4460
4531
|
} catch (cause) {
|
|
4461
4532
|
if (journalReady) await recoverStaging(project, staging, lockPath);
|
|
4462
4533
|
throw cause;
|
|
4463
4534
|
} finally {
|
|
4464
|
-
await
|
|
4535
|
+
await fs5.rm(staging, { recursive: true, force: true });
|
|
4465
4536
|
}
|
|
4466
4537
|
return result(
|
|
4467
4538
|
true,
|
|
@@ -4476,7 +4547,7 @@ async function syncWorkBuddyProject(input) {
|
|
|
4476
4547
|
async function recoverInterruptedSyncs(project, metaDir, lockPath) {
|
|
4477
4548
|
let entries;
|
|
4478
4549
|
try {
|
|
4479
|
-
entries = await
|
|
4550
|
+
entries = await fs5.readdir(metaDir, { withFileTypes: true });
|
|
4480
4551
|
} catch (cause) {
|
|
4481
4552
|
if (cause.code === "ENOENT") return;
|
|
4482
4553
|
throw cause;
|
|
@@ -4487,32 +4558,32 @@ async function recoverInterruptedSyncs(project, metaDir, lockPath) {
|
|
|
4487
4558
|
if (await exists(path2.join(staging, "journal.json"))) {
|
|
4488
4559
|
await recoverStaging(project, staging, lockPath);
|
|
4489
4560
|
}
|
|
4490
|
-
await
|
|
4561
|
+
await fs5.rm(staging, { recursive: true, force: true });
|
|
4491
4562
|
}
|
|
4492
4563
|
}
|
|
4493
4564
|
async function recoverStaging(project, staging, lockPath) {
|
|
4494
4565
|
const journalPath = path2.join(staging, "journal.json");
|
|
4495
|
-
const journal = parseJournal(await
|
|
4566
|
+
const journal = parseJournal(await fs5.readFile(journalPath, "utf8"), project);
|
|
4496
4567
|
const backups = path2.join(staging, "backup");
|
|
4497
4568
|
for (const file of journal.affectedFiles) {
|
|
4498
4569
|
const target = path2.join(project, file);
|
|
4499
4570
|
const backup = path2.join(backups, file);
|
|
4500
4571
|
if (await exists(backup)) {
|
|
4501
|
-
await
|
|
4502
|
-
await
|
|
4503
|
-
await
|
|
4572
|
+
await fs5.mkdir(path2.dirname(target), { recursive: true });
|
|
4573
|
+
await fs5.rm(target, { force: true });
|
|
4574
|
+
await fs5.rename(backup, target);
|
|
4504
4575
|
} else {
|
|
4505
|
-
await
|
|
4576
|
+
await fs5.rm(target, { force: true });
|
|
4506
4577
|
}
|
|
4507
4578
|
}
|
|
4508
4579
|
const backupLock = path2.join(backups, ".hcm-delivery", "chiron.lock.json");
|
|
4509
4580
|
if (journal.oldLockExisted) {
|
|
4510
4581
|
if (!await exists(backupLock)) throw invalid(`\u540C\u6B65\u6062\u590D\u7F3A\u5C11\u65E7\u9501\u5907\u4EFD\uFF1A${backupLock}`);
|
|
4511
|
-
await
|
|
4512
|
-
await
|
|
4513
|
-
await
|
|
4582
|
+
await fs5.mkdir(path2.dirname(lockPath), { recursive: true });
|
|
4583
|
+
await fs5.rm(lockPath, { force: true });
|
|
4584
|
+
await fs5.rename(backupLock, lockPath);
|
|
4514
4585
|
} else {
|
|
4515
|
-
await
|
|
4586
|
+
await fs5.rm(lockPath, { force: true });
|
|
4516
4587
|
}
|
|
4517
4588
|
}
|
|
4518
4589
|
function parseJournal(content, project) {
|
|
@@ -4755,7 +4826,7 @@ function stableJson2(value) {
|
|
|
4755
4826
|
}
|
|
4756
4827
|
async function readOptional(file) {
|
|
4757
4828
|
try {
|
|
4758
|
-
return await
|
|
4829
|
+
return await fs5.readFile(file, "utf8");
|
|
4759
4830
|
} catch (cause) {
|
|
4760
4831
|
if (cause.code === "ENOENT") return void 0;
|
|
4761
4832
|
throw cause;
|
|
@@ -4763,7 +4834,7 @@ async function readOptional(file) {
|
|
|
4763
4834
|
}
|
|
4764
4835
|
async function readOptionalBytes(file) {
|
|
4765
4836
|
try {
|
|
4766
|
-
return await
|
|
4837
|
+
return await fs5.readFile(file);
|
|
4767
4838
|
} catch (cause) {
|
|
4768
4839
|
if (cause.code === "ENOENT") return void 0;
|
|
4769
4840
|
throw cause;
|
|
@@ -4771,7 +4842,7 @@ async function readOptionalBytes(file) {
|
|
|
4771
4842
|
}
|
|
4772
4843
|
async function exists(file) {
|
|
4773
4844
|
try {
|
|
4774
|
-
await
|
|
4845
|
+
await fs5.access(file);
|
|
4775
4846
|
return true;
|
|
4776
4847
|
} catch (cause) {
|
|
4777
4848
|
if (cause.code === "ENOENT") return false;
|
|
@@ -4796,7 +4867,7 @@ function lockDigests(lock) {
|
|
|
4796
4867
|
}
|
|
4797
4868
|
async function fileModeMatches(file, expected) {
|
|
4798
4869
|
if (expected === void 0 || process.platform === "win32") return true;
|
|
4799
|
-
const stat = await
|
|
4870
|
+
const stat = await fs5.stat(file);
|
|
4800
4871
|
return (stat.mode & 511) === expected;
|
|
4801
4872
|
}
|
|
4802
4873
|
function validDigest(value) {
|
|
@@ -4812,7 +4883,7 @@ function invalid(message) {
|
|
|
4812
4883
|
// src/commands/skills-runtime.ts
|
|
4813
4884
|
import { execFile } from "child_process";
|
|
4814
4885
|
import { createHash as createHash2 } from "crypto";
|
|
4815
|
-
import { createReadStream, promises as
|
|
4886
|
+
import { createReadStream, promises as fs6 } from "fs";
|
|
4816
4887
|
import path3 from "path";
|
|
4817
4888
|
import { promisify } from "util";
|
|
4818
4889
|
import { CliError as CliError15, CliErrorCode as CliErrorCode14 } from "@hcmai/sdk";
|
|
@@ -4890,8 +4961,8 @@ async function resolveLaunch(candidate, nodeExecutable) {
|
|
|
4890
4961
|
}
|
|
4891
4962
|
async function realFile(file, label) {
|
|
4892
4963
|
try {
|
|
4893
|
-
const resolved = await
|
|
4894
|
-
const stat = await
|
|
4964
|
+
const resolved = await fs6.realpath(file);
|
|
4965
|
+
const stat = await fs6.stat(resolved);
|
|
4895
4966
|
if (!stat.isFile()) throw new Error("not a regular file");
|
|
4896
4967
|
return resolved;
|
|
4897
4968
|
} catch (cause) {
|
|
@@ -4904,20 +4975,20 @@ async function realFile(file, label) {
|
|
|
4904
4975
|
}
|
|
4905
4976
|
async function comparablePath(file) {
|
|
4906
4977
|
const absolute = path3.resolve(file);
|
|
4907
|
-
return
|
|
4978
|
+
return fs6.realpath(absolute).catch(() => absolute);
|
|
4908
4979
|
}
|
|
4909
4980
|
async function launchIdentity(launch) {
|
|
4910
4981
|
const files = launch.kind === "node-entry" ? [launch.executable, launch.entry] : [launch.executable];
|
|
4911
4982
|
const identities = await Promise.all(
|
|
4912
4983
|
files.map(async (file) => {
|
|
4913
|
-
const stat = await
|
|
4984
|
+
const stat = await fs6.stat(file, { bigint: true });
|
|
4914
4985
|
return [file, stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].map(String).join("\0");
|
|
4915
4986
|
})
|
|
4916
4987
|
);
|
|
4917
4988
|
return identities.join("\n");
|
|
4918
4989
|
}
|
|
4919
4990
|
async function readPrefix(file, bytes) {
|
|
4920
|
-
const handle = await
|
|
4991
|
+
const handle = await fs6.open(file, "r");
|
|
4921
4992
|
try {
|
|
4922
4993
|
const buffer = Buffer.alloc(bytes);
|
|
4923
4994
|
const result2 = await handle.read(buffer, 0, bytes, 0);
|
|
@@ -5307,7 +5378,8 @@ async function skillsSyncCommand(id, args) {
|
|
|
5307
5378
|
catalog,
|
|
5308
5379
|
id,
|
|
5309
5380
|
async (skillId) => fetchSkillMarkdown(http, skillId, base),
|
|
5310
|
-
async (skillId, relativePath) => fetchSkillFile(http, skillId, relativePath, base)
|
|
5381
|
+
async (skillId, relativePath) => fetchSkillFile(http, skillId, relativePath, base),
|
|
5382
|
+
async (skillId, relativePath) => fetchSkillReference(http, skillId, relativePath, base)
|
|
5311
5383
|
);
|
|
5312
5384
|
const result2 = await syncWorkBuddyProject({
|
|
5313
5385
|
project,
|
|
@@ -5460,7 +5532,7 @@ async function listLocalSkillIds(root) {
|
|
|
5460
5532
|
return ids.sort();
|
|
5461
5533
|
}
|
|
5462
5534
|
async function fetchSkillDocument(http, skill, endpoint, base) {
|
|
5463
|
-
const relatives =
|
|
5535
|
+
const relatives = normalizeReferences2(skill.references, skill.id);
|
|
5464
5536
|
const references = await Promise.all(relatives.map(async (relative2) => ({
|
|
5465
5537
|
path: relative2,
|
|
5466
5538
|
content: await fetchSkillReference(http, skill.id, relative2, base)
|
|
@@ -6137,7 +6209,7 @@ async function metaDeleteCommand(path7, args) {
|
|
|
6137
6209
|
init_exit();
|
|
6138
6210
|
init_auth_guard();
|
|
6139
6211
|
import * as crypto from "crypto";
|
|
6140
|
-
import * as
|
|
6212
|
+
import * as fs7 from "fs/promises";
|
|
6141
6213
|
import * as path5 from "path";
|
|
6142
6214
|
import {
|
|
6143
6215
|
buildMiniPreviewTargets,
|
|
@@ -6273,7 +6345,7 @@ async function workspaceBindCommand(workspaceKey, args) {
|
|
|
6273
6345
|
tenantId: args.tenant ?? client3?.tenantId,
|
|
6274
6346
|
endpoint: args.endpoint ?? client3?.endpoint
|
|
6275
6347
|
});
|
|
6276
|
-
await
|
|
6348
|
+
await fs7.mkdir(rootDir, { recursive: true });
|
|
6277
6349
|
await writeWorkspaceContext(rootDir, context);
|
|
6278
6350
|
writeWorkspaceBindResult(context, rootDir, args.output ?? "table");
|
|
6279
6351
|
process.exit(0);
|
|
@@ -6308,7 +6380,7 @@ async function workspaceCreateCommand(workspaceKey, args) {
|
|
|
6308
6380
|
tenantId: client3.tenantId,
|
|
6309
6381
|
endpoint: client3.endpoint
|
|
6310
6382
|
});
|
|
6311
|
-
await
|
|
6383
|
+
await fs7.mkdir(rootDir, { recursive: true });
|
|
6312
6384
|
await writeWorkspaceContext(rootDir, context);
|
|
6313
6385
|
writeWorkspaceCreateResult(
|
|
6314
6386
|
{
|
|
@@ -6345,7 +6417,7 @@ async function workspacePullCommand(args) {
|
|
|
6345
6417
|
tenantId: client3.tenantId ?? existing?.tenantId,
|
|
6346
6418
|
endpoint: client3.endpoint ?? existing?.endpoint
|
|
6347
6419
|
});
|
|
6348
|
-
await
|
|
6420
|
+
await fs7.mkdir(rootDir, { recursive: true });
|
|
6349
6421
|
await writeWorkspaceContext(rootDir, context);
|
|
6350
6422
|
const files = await listWorkspaceFiles(client3.raw(), workspaceKey, { pageSize: 5e3 });
|
|
6351
6423
|
const miniApps = detectRemoteMiniApps(files.data);
|
|
@@ -6677,7 +6749,7 @@ function buildWorkspaceContext(args) {
|
|
|
6677
6749
|
async function readWorkspaceContext(rootDir) {
|
|
6678
6750
|
try {
|
|
6679
6751
|
const parsed = JSON.parse(
|
|
6680
|
-
await
|
|
6752
|
+
await fs7.readFile(path5.join(rootDir, WORKSPACE_CONTEXT_FILE), "utf-8")
|
|
6681
6753
|
);
|
|
6682
6754
|
if (parsed.kind !== WORKSPACE_CONTEXT_KIND || parsed.version !== WORKSPACE_CONTEXT_VERSION) {
|
|
6683
6755
|
throw new Error(`${WORKSPACE_CONTEXT_FILE} is not an HCM workspace context`);
|
|
@@ -6706,25 +6778,25 @@ async function requireWorkspaceContext(rootDir) {
|
|
|
6706
6778
|
return context;
|
|
6707
6779
|
}
|
|
6708
6780
|
async function writeWorkspaceContext(rootDir, context) {
|
|
6709
|
-
await
|
|
6781
|
+
await fs7.writeFile(
|
|
6710
6782
|
path5.join(rootDir, WORKSPACE_CONTEXT_FILE),
|
|
6711
6783
|
JSON.stringify(context, null, 2) + "\n"
|
|
6712
6784
|
);
|
|
6713
6785
|
}
|
|
6714
6786
|
async function writeTextFile(file, content, force) {
|
|
6715
6787
|
try {
|
|
6716
|
-
await
|
|
6788
|
+
await fs7.access(file);
|
|
6717
6789
|
if (!force) throw new Error(`${file} already exists; use --force to overwrite`);
|
|
6718
6790
|
} catch (e) {
|
|
6719
6791
|
if (e.code !== "ENOENT") throw e;
|
|
6720
6792
|
}
|
|
6721
|
-
await
|
|
6722
|
-
await
|
|
6793
|
+
await fs7.mkdir(path5.dirname(file), { recursive: true });
|
|
6794
|
+
await fs7.writeFile(file, content);
|
|
6723
6795
|
}
|
|
6724
6796
|
async function readWorkspaceRawManifest(rootDir, context) {
|
|
6725
6797
|
try {
|
|
6726
6798
|
const parsed = JSON.parse(
|
|
6727
|
-
await
|
|
6799
|
+
await fs7.readFile(path5.join(rootDir, WORKSPACE_STATE_DIR, WORKSPACE_PULL_MANIFEST_FILE), "utf-8")
|
|
6728
6800
|
);
|
|
6729
6801
|
if (parsed.version !== WORKSPACE_CONTEXT_VERSION || parsed.workspaceKey !== context.workspaceKey) {
|
|
6730
6802
|
throw new Error(`${WORKSPACE_PULL_MANIFEST_FILE} does not match workspace ${context.workspaceKey}`);
|
|
@@ -6743,7 +6815,7 @@ async function readWorkspaceRawManifest(rootDir, context) {
|
|
|
6743
6815
|
}
|
|
6744
6816
|
async function writeWorkspaceRawState(rootDir, context, files, remoteByLocalPath) {
|
|
6745
6817
|
const stateDir = path5.join(rootDir, WORKSPACE_STATE_DIR);
|
|
6746
|
-
await
|
|
6818
|
+
await fs7.mkdir(stateDir, { recursive: true });
|
|
6747
6819
|
const snapshots = files.map((file) => ({
|
|
6748
6820
|
localPath: file.localPath,
|
|
6749
6821
|
remotePath: file.localPath,
|
|
@@ -6752,7 +6824,7 @@ async function writeWorkspaceRawState(rootDir, context, files, remoteByLocalPath
|
|
|
6752
6824
|
size: file.size,
|
|
6753
6825
|
lastModified: remoteByLocalPath.get(file.localPath)?.lastModified
|
|
6754
6826
|
}));
|
|
6755
|
-
await
|
|
6827
|
+
await fs7.writeFile(
|
|
6756
6828
|
path5.join(stateDir, WORKSPACE_PULL_MANIFEST_FILE),
|
|
6757
6829
|
JSON.stringify(
|
|
6758
6830
|
{
|
|
@@ -6778,7 +6850,7 @@ async function walkWorkspaceRawFiles(rootDir, relativeDir, files) {
|
|
|
6778
6850
|
const absoluteDir = path5.join(rootDir, relativeDir);
|
|
6779
6851
|
let entries;
|
|
6780
6852
|
try {
|
|
6781
|
-
entries = await
|
|
6853
|
+
entries = await fs7.readdir(absoluteDir, { withFileTypes: true });
|
|
6782
6854
|
} catch (e) {
|
|
6783
6855
|
if (e.code === "ENOENT") return;
|
|
6784
6856
|
throw e;
|
|
@@ -6793,7 +6865,7 @@ async function walkWorkspaceRawFiles(rootDir, relativeDir, files) {
|
|
|
6793
6865
|
continue;
|
|
6794
6866
|
}
|
|
6795
6867
|
if (!entry.isFile()) continue;
|
|
6796
|
-
const content = await
|
|
6868
|
+
const content = await fs7.readFile(absolutePath, "utf-8");
|
|
6797
6869
|
files.push({
|
|
6798
6870
|
localPath,
|
|
6799
6871
|
absolutePath,
|
|
@@ -6970,7 +7042,7 @@ async function discoverMiniApps(rootDir) {
|
|
|
6970
7042
|
const appsRoot = path5.join(rootDir, MINI_APPS_DIR);
|
|
6971
7043
|
let entries;
|
|
6972
7044
|
try {
|
|
6973
|
-
entries = await
|
|
7045
|
+
entries = await fs7.readdir(appsRoot, { withFileTypes: true });
|
|
6974
7046
|
} catch (e) {
|
|
6975
7047
|
if (e.code === "ENOENT") return [];
|
|
6976
7048
|
throw e;
|
|
@@ -7792,7 +7864,7 @@ function isPlainObject(value) {
|
|
|
7792
7864
|
// src/commands/delivery-execution.ts
|
|
7793
7865
|
import { createHash as createHash6, randomBytes as secureRandomBytes } from "crypto";
|
|
7794
7866
|
import { spawn } from "child_process";
|
|
7795
|
-
import { createReadStream as createReadStream2, promises as
|
|
7867
|
+
import { createReadStream as createReadStream2, promises as fs8 } from "fs";
|
|
7796
7868
|
import path6 from "path";
|
|
7797
7869
|
import { CliError as CliError20, CliErrorCode as CliErrorCode19, formatObject as formatObject18 } from "@hcmai/sdk";
|
|
7798
7870
|
init_exit();
|
|
@@ -7836,7 +7908,7 @@ async function prepareDeliveryExecution(input) {
|
|
|
7836
7908
|
await safeManagedDirectory(project, ".hcm-delivery/execution-plans", plansDir);
|
|
7837
7909
|
const planFile = path6.join(plansDir, `${planId}.json`);
|
|
7838
7910
|
try {
|
|
7839
|
-
await
|
|
7911
|
+
await fs8.writeFile(planFile, `${JSON.stringify(plan, null, 2)}
|
|
7840
7912
|
`, {
|
|
7841
7913
|
encoding: "utf8",
|
|
7842
7914
|
mode: 384,
|
|
@@ -7890,7 +7962,7 @@ async function executeDeliveryPlan(input) {
|
|
|
7890
7962
|
await safeManagedDirectory(project, ".hcm-delivery/execution-claims", claimsDir);
|
|
7891
7963
|
const claimFile = path6.join(claimsDir, `${plan.planId}.json`);
|
|
7892
7964
|
try {
|
|
7893
|
-
await
|
|
7965
|
+
await fs8.writeFile(
|
|
7894
7966
|
claimFile,
|
|
7895
7967
|
`${JSON.stringify({ schemaVersion: 1, planId: plan.planId, claimedAt: now.toISOString() }, null, 2)}
|
|
7896
7968
|
`,
|
|
@@ -8010,7 +8082,7 @@ async function bindEvidenceDirectory(project, reference) {
|
|
|
8010
8082
|
}
|
|
8011
8083
|
const absolute = path6.join(project, relative2);
|
|
8012
8084
|
await assertNoSymlinkComponents(project, relative2);
|
|
8013
|
-
const stat = await
|
|
8085
|
+
const stat = await fs8.stat(absolute).catch((cause) => {
|
|
8014
8086
|
throw invalid4(`evidence \u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${relative2}`, cause);
|
|
8015
8087
|
});
|
|
8016
8088
|
if (!stat.isDirectory()) throw invalid4(`evidence \u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${relative2}`);
|
|
@@ -8122,29 +8194,29 @@ async function runCurrentCliCommand(argv, cwd, streams) {
|
|
|
8122
8194
|
async function writeReceiptExclusive(target, receipt) {
|
|
8123
8195
|
const temp = `${target}.${process.pid}.${Date.now()}.tmp`;
|
|
8124
8196
|
try {
|
|
8125
|
-
await
|
|
8197
|
+
await fs8.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
|
|
8126
8198
|
`, {
|
|
8127
8199
|
encoding: "utf8",
|
|
8128
8200
|
mode: 384,
|
|
8129
8201
|
flag: "wx"
|
|
8130
8202
|
});
|
|
8131
|
-
await
|
|
8203
|
+
await fs8.link(temp, target);
|
|
8132
8204
|
} catch (cause) {
|
|
8133
8205
|
throw invalid4(`\u6267\u884C\u6536\u636E\u5199\u5165\u5931\u8D25\u6216\u5DF2\u5B58\u5728\uFF1A${path6.basename(target)}`, cause);
|
|
8134
8206
|
} finally {
|
|
8135
|
-
await
|
|
8207
|
+
await fs8.unlink(temp).catch(() => void 0);
|
|
8136
8208
|
}
|
|
8137
8209
|
}
|
|
8138
8210
|
async function safeManagedDirectory(project, relative2, absolute) {
|
|
8139
8211
|
await assertNoSymlinkComponents(project, path6.dirname(relative2));
|
|
8140
|
-
const existing = await
|
|
8212
|
+
const existing = await fs8.lstat(absolute).catch(() => void 0);
|
|
8141
8213
|
if (existing?.isSymbolicLink()) throw invalid4(`\u53D7\u7BA1\u76EE\u5F55\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
8142
8214
|
if (existing && !existing.isDirectory()) throw invalid4(`\u53D7\u7BA1\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${relative2}`);
|
|
8143
|
-
if (!existing) await
|
|
8144
|
-
await
|
|
8215
|
+
if (!existing) await fs8.mkdir(absolute, { mode: 448 });
|
|
8216
|
+
await fs8.chmod(absolute, 448);
|
|
8145
8217
|
}
|
|
8146
8218
|
async function pathExists(file) {
|
|
8147
|
-
return
|
|
8219
|
+
return fs8.lstat(file).then(
|
|
8148
8220
|
() => true,
|
|
8149
8221
|
(cause) => {
|
|
8150
8222
|
if (cause.code === "ENOENT") return false;
|
|
@@ -8159,20 +8231,20 @@ async function readSafeFile(project, file, label) {
|
|
|
8159
8231
|
await assertNoSymlinkComponents(project, relative2);
|
|
8160
8232
|
let stat;
|
|
8161
8233
|
try {
|
|
8162
|
-
stat = await
|
|
8234
|
+
stat = await fs8.lstat(file);
|
|
8163
8235
|
} catch (cause) {
|
|
8164
8236
|
throw invalid4(`${label}\u4E0D\u53EF\u7528\uFF1A${relative2}`, cause);
|
|
8165
8237
|
}
|
|
8166
8238
|
if (stat.isSymbolicLink()) throw invalid4(`${label}\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
8167
8239
|
if (!stat.isFile()) throw invalid4(`${label}\u4E0D\u662F\u666E\u901A\u6587\u4EF6\uFF1A${relative2}`);
|
|
8168
|
-
return
|
|
8240
|
+
return fs8.readFile(file);
|
|
8169
8241
|
}
|
|
8170
8242
|
async function assertNoSymlinkComponents(project, relative2) {
|
|
8171
8243
|
const parts = relative2.split("/").filter(Boolean);
|
|
8172
8244
|
let current = project;
|
|
8173
8245
|
for (const part of parts) {
|
|
8174
8246
|
current = path6.join(current, part);
|
|
8175
|
-
const stat = await
|
|
8247
|
+
const stat = await fs8.lstat(current).catch(() => void 0);
|
|
8176
8248
|
if (stat?.isSymbolicLink()) throw invalid4(`\u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
8177
8249
|
if (!stat) break;
|
|
8178
8250
|
}
|
|
@@ -8181,11 +8253,11 @@ async function realProject(requested) {
|
|
|
8181
8253
|
const absolute = path6.resolve(requested);
|
|
8182
8254
|
let project;
|
|
8183
8255
|
try {
|
|
8184
|
-
project = await
|
|
8256
|
+
project = await fs8.realpath(absolute);
|
|
8185
8257
|
} catch (cause) {
|
|
8186
8258
|
throw invalid4(`\u9879\u76EE\u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${absolute}`, cause);
|
|
8187
8259
|
}
|
|
8188
|
-
const stat = await
|
|
8260
|
+
const stat = await fs8.stat(project);
|
|
8189
8261
|
if (!stat.isDirectory()) throw invalid4(`\u9879\u76EE\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${absolute}`);
|
|
8190
8262
|
return project;
|
|
8191
8263
|
}
|
|
@@ -8274,11 +8346,11 @@ config.command("get <key>").description("\u8BFB\u53D6\u5168\u5C40 defaults").act
|
|
|
8274
8346
|
var env = program.command("env").description("\u7BA1\u7406 HCM \u73AF\u5883\uFF08\u591A\u540E\u7AEF\u8FDE\u63A5\u914D\u7F6E\uFF09");
|
|
8275
8347
|
env.command("list").description("\u5217\u51FA\u5168\u90E8 env").action(() => envList());
|
|
8276
8348
|
env.command("current").description("\u663E\u793A\u5F53\u524D\u6FC0\u6D3B\u7684 env").action(() => envCurrent());
|
|
8277
|
-
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));
|
|
8349
|
+
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));
|
|
8278
8350
|
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));
|
|
8279
8351
|
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));
|
|
8280
8352
|
env.command("show [name]").description("\u663E\u793A env \u8BE6\u60C5\uFF08\u542B\u8BE5 env \u4E0B\u7684 identity \u5217\u8868\uFF09").action((name) => envShow({ name }));
|
|
8281
|
-
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));
|
|
8353
|
+
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));
|
|
8282
8354
|
var identity = program.command("identity").description("\u7BA1\u7406 HCM \u8EAB\u4EFD\u51ED\u636E\uFF08env \u4E0B\u7684 identity\uFF09");
|
|
8283
8355
|
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));
|
|
8284
8356
|
identity.command("use <name>").description("\u628A identity \u8BBE\u4E3A\u5176 env \u7684 default identity").action((name) => identityUse(name));
|
|
@@ -8291,8 +8363,8 @@ program.command("query <Model>").description("\u67E5\u8BE2 Model \u5217\u8868\u6
|
|
|
8291
8363
|
"--filter <JSON>",
|
|
8292
8364
|
`\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`
|
|
8293
8365
|
).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));
|
|
8294
|
-
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));
|
|
8295
|
-
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));
|
|
8366
|
+
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));
|
|
8367
|
+
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));
|
|
8296
8368
|
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));
|
|
8297
8369
|
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));
|
|
8298
8370
|
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));
|
|
@@ -8352,7 +8424,7 @@ skills.command("show <id>").description("\u6253\u5370\u6280\u80FD\u539F\u6587\uF
|
|
|
8352
8424
|
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));
|
|
8353
8425
|
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));
|
|
8354
8426
|
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));
|
|
8355
|
-
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").
|
|
8427
|
+
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));
|
|
8356
8428
|
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));
|
|
8357
8429
|
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");
|
|
8358
8430
|
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));
|