@hcmai/cli 0.3.1 → 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/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 fs from "fs";
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 fs.statSync(p).isFile();
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 fs2 from "fs/promises";
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 fs2.readFile(replHistoryFile(props.env), "utf-8").then((c) => {
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 fs2.appendFile(replHistoryFile(props.env), line.replace(/\n/g, " ") + "\n").catch(() => {
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
- exitOk(`\u2192 ${g.activeEnv} ${cfg.endpoint} tenant=${cfg.tenantId ?? "1"} identity=${idName}`);
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, { endpoint: args.endpoint, tenantId: args.tenant ?? "1" });
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 CliError7,
2678
- CliErrorCode as CliErrorCode6
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 CliError7({
2685
- code: CliErrorCode6.INVALID_ARGUMENT,
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 CliError7({
2691
- code: CliErrorCode6.INVALID_ARGUMENT,
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
- if (args.params) {
2702
- try {
2703
- input.params = JSON.parse(args.params);
2704
- } catch (e) {
2705
- throw new CliError7({
2706
- code: CliErrorCode6.INVALID_JSON,
2707
- message: `--params: ${e.message}`
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 CliError7({
2736
- code: CliErrorCode6.INVALID_ARGUMENT,
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 CliError7({
2744
- code: CliErrorCode6.INVALID_ARGUMENT,
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
- if (!args.data) {
2762
- throw new CliError8({ code: CliErrorCode7.MISSING_FLAG, message: "--data <JSON> \u5FC5\u586B" });
2763
- }
2764
- let data;
2765
- try {
2766
- data = JSON.parse(args.data);
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
- if (!args.data) {
2799
- throw new CliError9({ code: CliErrorCode8.MISSING_FLAG, message: "--data <JSON> \u5FC5\u586B" });
2800
- }
2801
- let data;
2802
- try {
2803
- data = JSON.parse(args.data);
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 { HcmClient as HcmClient8, formatObject as formatObject8, fromAxiosError as fromAxiosError9 } from "@hcmai/sdk";
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
- const lines = [`=== ${desc.model} ===`];
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 fs3 from "fs/promises";
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 fs3.readFile(args.promptFile, "utf-8");
3458
+ prompt = await fs4.readFile(args.promptFile, "utf-8");
3408
3459
  }
3409
3460
  if (prompt === void 0 || !prompt && !regenerateMode) {
3410
3461
  throw new CliError13({
@@ -4254,7 +4305,7 @@ import {
4254
4305
 
4255
4306
  // src/commands/skills-sync.ts
4256
4307
  import { createHash } from "crypto";
4257
- import { promises as fs4 } from "fs";
4308
+ import { promises as fs5 } from "fs";
4258
4309
  import path2 from "path";
4259
4310
  import {
4260
4311
  CliError as CliError14,
@@ -4424,8 +4475,8 @@ async function syncWorkBuddyProject(input) {
4424
4475
  return result(false, input, project, skillsDir, lockPath, [], []);
4425
4476
  }
4426
4477
  const obsolete = [...oldOwned].filter((file) => !desiredByFile.has(file));
4427
- await fs4.mkdir(metaDir, { recursive: true });
4428
- const staging = await fs4.mkdtemp(path2.join(metaDir, ".staging-"));
4478
+ await fs5.mkdir(metaDir, { recursive: true });
4479
+ const staging = await fs5.mkdtemp(path2.join(metaDir, ".staging-"));
4429
4480
  const stagedFiles = path2.join(staging, "new");
4430
4481
  const backups = path2.join(staging, "backup");
4431
4482
  const stagedLock = path2.join(staging, "chiron.lock.json");
@@ -4434,28 +4485,28 @@ async function syncWorkBuddyProject(input) {
4434
4485
  try {
4435
4486
  for (const [file, preparedFile2] of desiredByFile) {
4436
4487
  const staged = path2.join(stagedFiles, file);
4437
- await fs4.mkdir(path2.dirname(staged), { recursive: true });
4438
- await fs4.writeFile(
4488
+ await fs5.mkdir(path2.dirname(staged), { recursive: true });
4489
+ await fs5.writeFile(
4439
4490
  staged,
4440
4491
  preparedFile2.content,
4441
4492
  preparedFile2.mode === void 0 ? void 0 : { mode: preparedFile2.mode }
4442
4493
  );
4443
4494
  }
4444
- await fs4.writeFile(stagedLock, `${JSON.stringify(newLock, null, 2)}
4495
+ await fs5.writeFile(stagedLock, `${JSON.stringify(newLock, null, 2)}
4445
4496
  `, "utf8");
4446
4497
  const affected = [.../* @__PURE__ */ new Set([...desiredFiles, ...obsolete])];
4447
4498
  for (const file of affected) {
4448
4499
  const target = path2.join(project, file);
4449
4500
  if (!await exists(target)) continue;
4450
4501
  const backup = path2.join(backups, file);
4451
- await fs4.mkdir(path2.dirname(backup), { recursive: true });
4452
- await fs4.copyFile(target, backup);
4502
+ await fs5.mkdir(path2.dirname(backup), { recursive: true });
4503
+ await fs5.copyFile(target, backup);
4453
4504
  }
4454
4505
  const oldLockExisted = await exists(lockPath);
4455
4506
  if (oldLockExisted) {
4456
4507
  const backupLock = path2.join(backups, ".hcm-delivery", "chiron.lock.json");
4457
- await fs4.mkdir(path2.dirname(backupLock), { recursive: true });
4458
- await fs4.copyFile(lockPath, backupLock);
4508
+ await fs5.mkdir(path2.dirname(backupLock), { recursive: true });
4509
+ await fs5.copyFile(lockPath, backupLock);
4459
4510
  }
4460
4511
  const journal = {
4461
4512
  schemaVersion: 1,
@@ -4463,25 +4514,25 @@ async function syncWorkBuddyProject(input) {
4463
4514
  affectedFiles: affected,
4464
4515
  oldLockExisted
4465
4516
  };
4466
- await fs4.writeFile(journalPath, `${JSON.stringify(journal, null, 2)}
4517
+ await fs5.writeFile(journalPath, `${JSON.stringify(journal, null, 2)}
4467
4518
  `, "utf8");
4468
4519
  journalReady = true;
4469
4520
  for (const file of desiredFiles) {
4470
4521
  const target = path2.join(project, file);
4471
- await fs4.mkdir(path2.dirname(target), { recursive: true });
4472
- await fs4.rm(target, { force: true });
4473
- await fs4.rename(path2.join(stagedFiles, file), target);
4474
- }
4475
- for (const file of obsolete) await fs4.unlink(path2.join(project, file)).catch(ignoreMissing);
4476
- await fs4.rm(lockPath, { force: true });
4477
- await fs4.rename(stagedLock, lockPath);
4478
- await fs4.unlink(journalPath);
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);
4479
4530
  journalReady = false;
4480
4531
  } catch (cause) {
4481
4532
  if (journalReady) await recoverStaging(project, staging, lockPath);
4482
4533
  throw cause;
4483
4534
  } finally {
4484
- await fs4.rm(staging, { recursive: true, force: true });
4535
+ await fs5.rm(staging, { recursive: true, force: true });
4485
4536
  }
4486
4537
  return result(
4487
4538
  true,
@@ -4496,7 +4547,7 @@ async function syncWorkBuddyProject(input) {
4496
4547
  async function recoverInterruptedSyncs(project, metaDir, lockPath) {
4497
4548
  let entries;
4498
4549
  try {
4499
- entries = await fs4.readdir(metaDir, { withFileTypes: true });
4550
+ entries = await fs5.readdir(metaDir, { withFileTypes: true });
4500
4551
  } catch (cause) {
4501
4552
  if (cause.code === "ENOENT") return;
4502
4553
  throw cause;
@@ -4507,32 +4558,32 @@ async function recoverInterruptedSyncs(project, metaDir, lockPath) {
4507
4558
  if (await exists(path2.join(staging, "journal.json"))) {
4508
4559
  await recoverStaging(project, staging, lockPath);
4509
4560
  }
4510
- await fs4.rm(staging, { recursive: true, force: true });
4561
+ await fs5.rm(staging, { recursive: true, force: true });
4511
4562
  }
4512
4563
  }
4513
4564
  async function recoverStaging(project, staging, lockPath) {
4514
4565
  const journalPath = path2.join(staging, "journal.json");
4515
- const journal = parseJournal(await fs4.readFile(journalPath, "utf8"), project);
4566
+ const journal = parseJournal(await fs5.readFile(journalPath, "utf8"), project);
4516
4567
  const backups = path2.join(staging, "backup");
4517
4568
  for (const file of journal.affectedFiles) {
4518
4569
  const target = path2.join(project, file);
4519
4570
  const backup = path2.join(backups, file);
4520
4571
  if (await exists(backup)) {
4521
- await fs4.mkdir(path2.dirname(target), { recursive: true });
4522
- await fs4.rm(target, { force: true });
4523
- await fs4.rename(backup, target);
4572
+ await fs5.mkdir(path2.dirname(target), { recursive: true });
4573
+ await fs5.rm(target, { force: true });
4574
+ await fs5.rename(backup, target);
4524
4575
  } else {
4525
- await fs4.rm(target, { force: true });
4576
+ await fs5.rm(target, { force: true });
4526
4577
  }
4527
4578
  }
4528
4579
  const backupLock = path2.join(backups, ".hcm-delivery", "chiron.lock.json");
4529
4580
  if (journal.oldLockExisted) {
4530
4581
  if (!await exists(backupLock)) throw invalid(`\u540C\u6B65\u6062\u590D\u7F3A\u5C11\u65E7\u9501\u5907\u4EFD\uFF1A${backupLock}`);
4531
- await fs4.mkdir(path2.dirname(lockPath), { recursive: true });
4532
- await fs4.rm(lockPath, { force: true });
4533
- await fs4.rename(backupLock, lockPath);
4582
+ await fs5.mkdir(path2.dirname(lockPath), { recursive: true });
4583
+ await fs5.rm(lockPath, { force: true });
4584
+ await fs5.rename(backupLock, lockPath);
4534
4585
  } else {
4535
- await fs4.rm(lockPath, { force: true });
4586
+ await fs5.rm(lockPath, { force: true });
4536
4587
  }
4537
4588
  }
4538
4589
  function parseJournal(content, project) {
@@ -4775,7 +4826,7 @@ function stableJson2(value) {
4775
4826
  }
4776
4827
  async function readOptional(file) {
4777
4828
  try {
4778
- return await fs4.readFile(file, "utf8");
4829
+ return await fs5.readFile(file, "utf8");
4779
4830
  } catch (cause) {
4780
4831
  if (cause.code === "ENOENT") return void 0;
4781
4832
  throw cause;
@@ -4783,7 +4834,7 @@ async function readOptional(file) {
4783
4834
  }
4784
4835
  async function readOptionalBytes(file) {
4785
4836
  try {
4786
- return await fs4.readFile(file);
4837
+ return await fs5.readFile(file);
4787
4838
  } catch (cause) {
4788
4839
  if (cause.code === "ENOENT") return void 0;
4789
4840
  throw cause;
@@ -4791,7 +4842,7 @@ async function readOptionalBytes(file) {
4791
4842
  }
4792
4843
  async function exists(file) {
4793
4844
  try {
4794
- await fs4.access(file);
4845
+ await fs5.access(file);
4795
4846
  return true;
4796
4847
  } catch (cause) {
4797
4848
  if (cause.code === "ENOENT") return false;
@@ -4816,7 +4867,7 @@ function lockDigests(lock) {
4816
4867
  }
4817
4868
  async function fileModeMatches(file, expected) {
4818
4869
  if (expected === void 0 || process.platform === "win32") return true;
4819
- const stat = await fs4.stat(file);
4870
+ const stat = await fs5.stat(file);
4820
4871
  return (stat.mode & 511) === expected;
4821
4872
  }
4822
4873
  function validDigest(value) {
@@ -4832,7 +4883,7 @@ function invalid(message) {
4832
4883
  // src/commands/skills-runtime.ts
4833
4884
  import { execFile } from "child_process";
4834
4885
  import { createHash as createHash2 } from "crypto";
4835
- import { createReadStream, promises as fs5 } from "fs";
4886
+ import { createReadStream, promises as fs6 } from "fs";
4836
4887
  import path3 from "path";
4837
4888
  import { promisify } from "util";
4838
4889
  import { CliError as CliError15, CliErrorCode as CliErrorCode14 } from "@hcmai/sdk";
@@ -4910,8 +4961,8 @@ async function resolveLaunch(candidate, nodeExecutable) {
4910
4961
  }
4911
4962
  async function realFile(file, label) {
4912
4963
  try {
4913
- const resolved = await fs5.realpath(file);
4914
- const stat = await fs5.stat(resolved);
4964
+ const resolved = await fs6.realpath(file);
4965
+ const stat = await fs6.stat(resolved);
4915
4966
  if (!stat.isFile()) throw new Error("not a regular file");
4916
4967
  return resolved;
4917
4968
  } catch (cause) {
@@ -4924,20 +4975,20 @@ async function realFile(file, label) {
4924
4975
  }
4925
4976
  async function comparablePath(file) {
4926
4977
  const absolute = path3.resolve(file);
4927
- return fs5.realpath(absolute).catch(() => absolute);
4978
+ return fs6.realpath(absolute).catch(() => absolute);
4928
4979
  }
4929
4980
  async function launchIdentity(launch) {
4930
4981
  const files = launch.kind === "node-entry" ? [launch.executable, launch.entry] : [launch.executable];
4931
4982
  const identities = await Promise.all(
4932
4983
  files.map(async (file) => {
4933
- const stat = await fs5.stat(file, { bigint: true });
4984
+ const stat = await fs6.stat(file, { bigint: true });
4934
4985
  return [file, stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].map(String).join("\0");
4935
4986
  })
4936
4987
  );
4937
4988
  return identities.join("\n");
4938
4989
  }
4939
4990
  async function readPrefix(file, bytes) {
4940
- const handle = await fs5.open(file, "r");
4991
+ const handle = await fs6.open(file, "r");
4941
4992
  try {
4942
4993
  const buffer = Buffer.alloc(bytes);
4943
4994
  const result2 = await handle.read(buffer, 0, bytes, 0);
@@ -6158,7 +6209,7 @@ async function metaDeleteCommand(path7, args) {
6158
6209
  init_exit();
6159
6210
  init_auth_guard();
6160
6211
  import * as crypto from "crypto";
6161
- import * as fs6 from "fs/promises";
6212
+ import * as fs7 from "fs/promises";
6162
6213
  import * as path5 from "path";
6163
6214
  import {
6164
6215
  buildMiniPreviewTargets,
@@ -6294,7 +6345,7 @@ async function workspaceBindCommand(workspaceKey, args) {
6294
6345
  tenantId: args.tenant ?? client3?.tenantId,
6295
6346
  endpoint: args.endpoint ?? client3?.endpoint
6296
6347
  });
6297
- await fs6.mkdir(rootDir, { recursive: true });
6348
+ await fs7.mkdir(rootDir, { recursive: true });
6298
6349
  await writeWorkspaceContext(rootDir, context);
6299
6350
  writeWorkspaceBindResult(context, rootDir, args.output ?? "table");
6300
6351
  process.exit(0);
@@ -6329,7 +6380,7 @@ async function workspaceCreateCommand(workspaceKey, args) {
6329
6380
  tenantId: client3.tenantId,
6330
6381
  endpoint: client3.endpoint
6331
6382
  });
6332
- await fs6.mkdir(rootDir, { recursive: true });
6383
+ await fs7.mkdir(rootDir, { recursive: true });
6333
6384
  await writeWorkspaceContext(rootDir, context);
6334
6385
  writeWorkspaceCreateResult(
6335
6386
  {
@@ -6366,7 +6417,7 @@ async function workspacePullCommand(args) {
6366
6417
  tenantId: client3.tenantId ?? existing?.tenantId,
6367
6418
  endpoint: client3.endpoint ?? existing?.endpoint
6368
6419
  });
6369
- await fs6.mkdir(rootDir, { recursive: true });
6420
+ await fs7.mkdir(rootDir, { recursive: true });
6370
6421
  await writeWorkspaceContext(rootDir, context);
6371
6422
  const files = await listWorkspaceFiles(client3.raw(), workspaceKey, { pageSize: 5e3 });
6372
6423
  const miniApps = detectRemoteMiniApps(files.data);
@@ -6698,7 +6749,7 @@ function buildWorkspaceContext(args) {
6698
6749
  async function readWorkspaceContext(rootDir) {
6699
6750
  try {
6700
6751
  const parsed = JSON.parse(
6701
- await fs6.readFile(path5.join(rootDir, WORKSPACE_CONTEXT_FILE), "utf-8")
6752
+ await fs7.readFile(path5.join(rootDir, WORKSPACE_CONTEXT_FILE), "utf-8")
6702
6753
  );
6703
6754
  if (parsed.kind !== WORKSPACE_CONTEXT_KIND || parsed.version !== WORKSPACE_CONTEXT_VERSION) {
6704
6755
  throw new Error(`${WORKSPACE_CONTEXT_FILE} is not an HCM workspace context`);
@@ -6727,25 +6778,25 @@ async function requireWorkspaceContext(rootDir) {
6727
6778
  return context;
6728
6779
  }
6729
6780
  async function writeWorkspaceContext(rootDir, context) {
6730
- await fs6.writeFile(
6781
+ await fs7.writeFile(
6731
6782
  path5.join(rootDir, WORKSPACE_CONTEXT_FILE),
6732
6783
  JSON.stringify(context, null, 2) + "\n"
6733
6784
  );
6734
6785
  }
6735
6786
  async function writeTextFile(file, content, force) {
6736
6787
  try {
6737
- await fs6.access(file);
6788
+ await fs7.access(file);
6738
6789
  if (!force) throw new Error(`${file} already exists; use --force to overwrite`);
6739
6790
  } catch (e) {
6740
6791
  if (e.code !== "ENOENT") throw e;
6741
6792
  }
6742
- await fs6.mkdir(path5.dirname(file), { recursive: true });
6743
- await fs6.writeFile(file, content);
6793
+ await fs7.mkdir(path5.dirname(file), { recursive: true });
6794
+ await fs7.writeFile(file, content);
6744
6795
  }
6745
6796
  async function readWorkspaceRawManifest(rootDir, context) {
6746
6797
  try {
6747
6798
  const parsed = JSON.parse(
6748
- await fs6.readFile(path5.join(rootDir, WORKSPACE_STATE_DIR, WORKSPACE_PULL_MANIFEST_FILE), "utf-8")
6799
+ await fs7.readFile(path5.join(rootDir, WORKSPACE_STATE_DIR, WORKSPACE_PULL_MANIFEST_FILE), "utf-8")
6749
6800
  );
6750
6801
  if (parsed.version !== WORKSPACE_CONTEXT_VERSION || parsed.workspaceKey !== context.workspaceKey) {
6751
6802
  throw new Error(`${WORKSPACE_PULL_MANIFEST_FILE} does not match workspace ${context.workspaceKey}`);
@@ -6764,7 +6815,7 @@ async function readWorkspaceRawManifest(rootDir, context) {
6764
6815
  }
6765
6816
  async function writeWorkspaceRawState(rootDir, context, files, remoteByLocalPath) {
6766
6817
  const stateDir = path5.join(rootDir, WORKSPACE_STATE_DIR);
6767
- await fs6.mkdir(stateDir, { recursive: true });
6818
+ await fs7.mkdir(stateDir, { recursive: true });
6768
6819
  const snapshots = files.map((file) => ({
6769
6820
  localPath: file.localPath,
6770
6821
  remotePath: file.localPath,
@@ -6773,7 +6824,7 @@ async function writeWorkspaceRawState(rootDir, context, files, remoteByLocalPath
6773
6824
  size: file.size,
6774
6825
  lastModified: remoteByLocalPath.get(file.localPath)?.lastModified
6775
6826
  }));
6776
- await fs6.writeFile(
6827
+ await fs7.writeFile(
6777
6828
  path5.join(stateDir, WORKSPACE_PULL_MANIFEST_FILE),
6778
6829
  JSON.stringify(
6779
6830
  {
@@ -6799,7 +6850,7 @@ async function walkWorkspaceRawFiles(rootDir, relativeDir, files) {
6799
6850
  const absoluteDir = path5.join(rootDir, relativeDir);
6800
6851
  let entries;
6801
6852
  try {
6802
- entries = await fs6.readdir(absoluteDir, { withFileTypes: true });
6853
+ entries = await fs7.readdir(absoluteDir, { withFileTypes: true });
6803
6854
  } catch (e) {
6804
6855
  if (e.code === "ENOENT") return;
6805
6856
  throw e;
@@ -6814,7 +6865,7 @@ async function walkWorkspaceRawFiles(rootDir, relativeDir, files) {
6814
6865
  continue;
6815
6866
  }
6816
6867
  if (!entry.isFile()) continue;
6817
- const content = await fs6.readFile(absolutePath, "utf-8");
6868
+ const content = await fs7.readFile(absolutePath, "utf-8");
6818
6869
  files.push({
6819
6870
  localPath,
6820
6871
  absolutePath,
@@ -6991,7 +7042,7 @@ async function discoverMiniApps(rootDir) {
6991
7042
  const appsRoot = path5.join(rootDir, MINI_APPS_DIR);
6992
7043
  let entries;
6993
7044
  try {
6994
- entries = await fs6.readdir(appsRoot, { withFileTypes: true });
7045
+ entries = await fs7.readdir(appsRoot, { withFileTypes: true });
6995
7046
  } catch (e) {
6996
7047
  if (e.code === "ENOENT") return [];
6997
7048
  throw e;
@@ -7813,7 +7864,7 @@ function isPlainObject(value) {
7813
7864
  // src/commands/delivery-execution.ts
7814
7865
  import { createHash as createHash6, randomBytes as secureRandomBytes } from "crypto";
7815
7866
  import { spawn } from "child_process";
7816
- import { createReadStream as createReadStream2, promises as fs7 } from "fs";
7867
+ import { createReadStream as createReadStream2, promises as fs8 } from "fs";
7817
7868
  import path6 from "path";
7818
7869
  import { CliError as CliError20, CliErrorCode as CliErrorCode19, formatObject as formatObject18 } from "@hcmai/sdk";
7819
7870
  init_exit();
@@ -7857,7 +7908,7 @@ async function prepareDeliveryExecution(input) {
7857
7908
  await safeManagedDirectory(project, ".hcm-delivery/execution-plans", plansDir);
7858
7909
  const planFile = path6.join(plansDir, `${planId}.json`);
7859
7910
  try {
7860
- await fs7.writeFile(planFile, `${JSON.stringify(plan, null, 2)}
7911
+ await fs8.writeFile(planFile, `${JSON.stringify(plan, null, 2)}
7861
7912
  `, {
7862
7913
  encoding: "utf8",
7863
7914
  mode: 384,
@@ -7911,7 +7962,7 @@ async function executeDeliveryPlan(input) {
7911
7962
  await safeManagedDirectory(project, ".hcm-delivery/execution-claims", claimsDir);
7912
7963
  const claimFile = path6.join(claimsDir, `${plan.planId}.json`);
7913
7964
  try {
7914
- await fs7.writeFile(
7965
+ await fs8.writeFile(
7915
7966
  claimFile,
7916
7967
  `${JSON.stringify({ schemaVersion: 1, planId: plan.planId, claimedAt: now.toISOString() }, null, 2)}
7917
7968
  `,
@@ -8031,7 +8082,7 @@ async function bindEvidenceDirectory(project, reference) {
8031
8082
  }
8032
8083
  const absolute = path6.join(project, relative2);
8033
8084
  await assertNoSymlinkComponents(project, relative2);
8034
- const stat = await fs7.stat(absolute).catch((cause) => {
8085
+ const stat = await fs8.stat(absolute).catch((cause) => {
8035
8086
  throw invalid4(`evidence \u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${relative2}`, cause);
8036
8087
  });
8037
8088
  if (!stat.isDirectory()) throw invalid4(`evidence \u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${relative2}`);
@@ -8143,29 +8194,29 @@ async function runCurrentCliCommand(argv, cwd, streams) {
8143
8194
  async function writeReceiptExclusive(target, receipt) {
8144
8195
  const temp = `${target}.${process.pid}.${Date.now()}.tmp`;
8145
8196
  try {
8146
- await fs7.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
8197
+ await fs8.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
8147
8198
  `, {
8148
8199
  encoding: "utf8",
8149
8200
  mode: 384,
8150
8201
  flag: "wx"
8151
8202
  });
8152
- await fs7.link(temp, target);
8203
+ await fs8.link(temp, target);
8153
8204
  } catch (cause) {
8154
8205
  throw invalid4(`\u6267\u884C\u6536\u636E\u5199\u5165\u5931\u8D25\u6216\u5DF2\u5B58\u5728\uFF1A${path6.basename(target)}`, cause);
8155
8206
  } finally {
8156
- await fs7.unlink(temp).catch(() => void 0);
8207
+ await fs8.unlink(temp).catch(() => void 0);
8157
8208
  }
8158
8209
  }
8159
8210
  async function safeManagedDirectory(project, relative2, absolute) {
8160
8211
  await assertNoSymlinkComponents(project, path6.dirname(relative2));
8161
- const existing = await fs7.lstat(absolute).catch(() => void 0);
8212
+ const existing = await fs8.lstat(absolute).catch(() => void 0);
8162
8213
  if (existing?.isSymbolicLink()) throw invalid4(`\u53D7\u7BA1\u76EE\u5F55\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
8163
8214
  if (existing && !existing.isDirectory()) throw invalid4(`\u53D7\u7BA1\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${relative2}`);
8164
- if (!existing) await fs7.mkdir(absolute, { mode: 448 });
8165
- await fs7.chmod(absolute, 448);
8215
+ if (!existing) await fs8.mkdir(absolute, { mode: 448 });
8216
+ await fs8.chmod(absolute, 448);
8166
8217
  }
8167
8218
  async function pathExists(file) {
8168
- return fs7.lstat(file).then(
8219
+ return fs8.lstat(file).then(
8169
8220
  () => true,
8170
8221
  (cause) => {
8171
8222
  if (cause.code === "ENOENT") return false;
@@ -8180,20 +8231,20 @@ async function readSafeFile(project, file, label) {
8180
8231
  await assertNoSymlinkComponents(project, relative2);
8181
8232
  let stat;
8182
8233
  try {
8183
- stat = await fs7.lstat(file);
8234
+ stat = await fs8.lstat(file);
8184
8235
  } catch (cause) {
8185
8236
  throw invalid4(`${label}\u4E0D\u53EF\u7528\uFF1A${relative2}`, cause);
8186
8237
  }
8187
8238
  if (stat.isSymbolicLink()) throw invalid4(`${label}\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
8188
8239
  if (!stat.isFile()) throw invalid4(`${label}\u4E0D\u662F\u666E\u901A\u6587\u4EF6\uFF1A${relative2}`);
8189
- return fs7.readFile(file);
8240
+ return fs8.readFile(file);
8190
8241
  }
8191
8242
  async function assertNoSymlinkComponents(project, relative2) {
8192
8243
  const parts = relative2.split("/").filter(Boolean);
8193
8244
  let current = project;
8194
8245
  for (const part of parts) {
8195
8246
  current = path6.join(current, part);
8196
- const stat = await fs7.lstat(current).catch(() => void 0);
8247
+ const stat = await fs8.lstat(current).catch(() => void 0);
8197
8248
  if (stat?.isSymbolicLink()) throw invalid4(`\u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
8198
8249
  if (!stat) break;
8199
8250
  }
@@ -8202,11 +8253,11 @@ async function realProject(requested) {
8202
8253
  const absolute = path6.resolve(requested);
8203
8254
  let project;
8204
8255
  try {
8205
- project = await fs7.realpath(absolute);
8256
+ project = await fs8.realpath(absolute);
8206
8257
  } catch (cause) {
8207
8258
  throw invalid4(`\u9879\u76EE\u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${absolute}`, cause);
8208
8259
  }
8209
- const stat = await fs7.stat(project);
8260
+ const stat = await fs8.stat(project);
8210
8261
  if (!stat.isDirectory()) throw invalid4(`\u9879\u76EE\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${absolute}`);
8211
8262
  return project;
8212
8263
  }
@@ -8295,11 +8346,11 @@ config.command("get <key>").description("\u8BFB\u53D6\u5168\u5C40 defaults").act
8295
8346
  var env = program.command("env").description("\u7BA1\u7406 HCM \u73AF\u5883\uFF08\u591A\u540E\u7AEF\u8FDE\u63A5\u914D\u7F6E\uFF09");
8296
8347
  env.command("list").description("\u5217\u51FA\u5168\u90E8 env").action(() => envList());
8297
8348
  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));
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));
8299
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));
8300
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));
8301
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 }));
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));
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));
8303
8354
  var identity = program.command("identity").description("\u7BA1\u7406 HCM \u8EAB\u4EFD\u51ED\u636E\uFF08env \u4E0B\u7684 identity\uFF09");
8304
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));
8305
8356
  identity.command("use <name>").description("\u628A identity \u8BBE\u4E3A\u5176 env \u7684 default identity").action((name) => identityUse(name));
@@ -8312,8 +8363,8 @@ program.command("query <Model>").description("\u67E5\u8BE2 Model \u5217\u8868\u6
8312
8363
  "--filter <JSON>",
8313
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`
8314
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));
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));
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));
8317
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));
8318
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));
8319
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));
@@ -8373,7 +8424,7 @@ skills.command("show <id>").description("\u6253\u5370\u6280\u80FD\u539F\u6587\uF
8373
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));
8374
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));
8375
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));
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").requiredOption("--data <JSON>", `\u8981\u66F4\u65B0\u7684\u5B57\u6BB5 JSON\uFF0C\u4F8B\u5982 '{"name":"\u65B0\u540D\u79F0"}'`).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));
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));
8377
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));
8378
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");
8379
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));