@hcmai/cli 0.3.6 → 0.3.8
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 +194 -70
- package/dist/index.js.map +1 -1
- package/dist/skills/manifest.json +28 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -523,8 +523,8 @@ var init_TerminalRenderer = __esm({
|
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
525
|
/** 来源行(仅子代理触发,agentPath ≥2 段时显示 `↑ 来自 a › b`,对齐 Web)。 */
|
|
526
|
-
originLine(
|
|
527
|
-
const segs =
|
|
526
|
+
originLine(path10) {
|
|
527
|
+
const segs = path10.split(".").filter(Boolean);
|
|
528
528
|
if (segs.length < 2) return "";
|
|
529
529
|
const names = segs.map((k) => agentDisplayName(k));
|
|
530
530
|
return chalk.gray(` \u2191 \u6765\u81EA ${names.join(" \u203A ")}`) + "\n";
|
|
@@ -1706,8 +1706,8 @@ function agentLabel(agentId) {
|
|
|
1706
1706
|
if (/^[0-9a-f]{8}-[0-9a-f-]{27}$/i.test(agentId)) return `agent \u2026${agentId.slice(-4)}`;
|
|
1707
1707
|
return agentDisplayName(agentId);
|
|
1708
1708
|
}
|
|
1709
|
-
function originLine(
|
|
1710
|
-
const segs = (
|
|
1709
|
+
function originLine(path10) {
|
|
1710
|
+
const segs = (path10 ?? "").split(".").filter(Boolean);
|
|
1711
1711
|
if (segs.length < 2) return null;
|
|
1712
1712
|
return `\u6765\u81EA ${segs.map((k) => agentDisplayName(k)).join(" \u203A ")}`;
|
|
1713
1713
|
}
|
|
@@ -1940,10 +1940,10 @@ __export(readline_exports, {
|
|
|
1940
1940
|
import * as readline2 from "readline";
|
|
1941
1941
|
function readLineFromStdin(prompt = "") {
|
|
1942
1942
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
1943
|
-
return new Promise((
|
|
1943
|
+
return new Promise((resolve4) => {
|
|
1944
1944
|
rl.question(prompt, (answer) => {
|
|
1945
1945
|
rl.close();
|
|
1946
|
-
|
|
1946
|
+
resolve4(answer);
|
|
1947
1947
|
});
|
|
1948
1948
|
});
|
|
1949
1949
|
}
|
|
@@ -1992,15 +1992,15 @@ import {
|
|
|
1992
1992
|
import * as readline from "readline";
|
|
1993
1993
|
async function promptText(question) {
|
|
1994
1994
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1995
|
-
return new Promise((
|
|
1995
|
+
return new Promise((resolve4) => {
|
|
1996
1996
|
rl.question(question, (ans) => {
|
|
1997
1997
|
rl.close();
|
|
1998
|
-
|
|
1998
|
+
resolve4(ans.trim());
|
|
1999
1999
|
});
|
|
2000
2000
|
});
|
|
2001
2001
|
}
|
|
2002
2002
|
async function promptSecret(question) {
|
|
2003
|
-
return new Promise((
|
|
2003
|
+
return new Promise((resolve4) => {
|
|
2004
2004
|
process.stdout.write(question);
|
|
2005
2005
|
const stdin = process.stdin;
|
|
2006
2006
|
stdin.setRawMode?.(true);
|
|
@@ -2014,7 +2014,7 @@ async function promptSecret(question) {
|
|
|
2014
2014
|
stdin.pause();
|
|
2015
2015
|
stdin.removeListener("data", onData);
|
|
2016
2016
|
process.stdout.write("\n");
|
|
2017
|
-
|
|
2017
|
+
resolve4(buf);
|
|
2018
2018
|
return;
|
|
2019
2019
|
}
|
|
2020
2020
|
if (ch === "") process.exit(130);
|
|
@@ -2286,9 +2286,9 @@ async function loginCommand(args) {
|
|
|
2286
2286
|
} catch (e) {
|
|
2287
2287
|
const err = e;
|
|
2288
2288
|
if (err.isAxiosError) {
|
|
2289
|
-
const { fromAxiosError:
|
|
2289
|
+
const { fromAxiosError: fromAxiosError20 } = await import("@hcmai/sdk");
|
|
2290
2290
|
exitWithError(
|
|
2291
|
-
|
|
2291
|
+
fromAxiosError20(
|
|
2292
2292
|
e,
|
|
2293
2293
|
envName
|
|
2294
2294
|
)
|
|
@@ -3059,8 +3059,8 @@ import {
|
|
|
3059
3059
|
formatObject as formatObject7,
|
|
3060
3060
|
fromAxiosError as fromAxiosError8
|
|
3061
3061
|
} from "@hcmai/sdk";
|
|
3062
|
-
function collectYmlFiles(
|
|
3063
|
-
if (statSync(
|
|
3062
|
+
function collectYmlFiles(path10) {
|
|
3063
|
+
if (statSync(path10).isFile()) return [path10];
|
|
3064
3064
|
const out = [];
|
|
3065
3065
|
const walk = (dir) => {
|
|
3066
3066
|
for (const name of readdirSync(dir).sort()) {
|
|
@@ -3069,7 +3069,7 @@ function collectYmlFiles(path9) {
|
|
|
3069
3069
|
else if (full.endsWith(".yml") || full.endsWith(".yaml")) out.push(full);
|
|
3070
3070
|
}
|
|
3071
3071
|
};
|
|
3072
|
-
walk(
|
|
3072
|
+
walk(path10);
|
|
3073
3073
|
return out.sort();
|
|
3074
3074
|
}
|
|
3075
3075
|
var DRY_RUN_CLIENT = {
|
|
@@ -3077,9 +3077,9 @@ var DRY_RUN_CLIENT = {
|
|
|
3077
3077
|
create: async () => ({ id: "" }),
|
|
3078
3078
|
update: async () => ({})
|
|
3079
3079
|
};
|
|
3080
|
-
async function importCommand(
|
|
3080
|
+
async function importCommand(path10, args) {
|
|
3081
3081
|
try {
|
|
3082
|
-
const files = collectYmlFiles(
|
|
3082
|
+
const files = collectYmlFiles(path10);
|
|
3083
3083
|
const fixtures = files.map(
|
|
3084
3084
|
(f) => parseFixture(readFileSync2(f, "utf8"), relative(process.cwd(), f))
|
|
3085
3085
|
);
|
|
@@ -3622,11 +3622,11 @@ async function chatCommand(prompt, args) {
|
|
|
3622
3622
|
lastConversationId: handle.conversationId,
|
|
3623
3623
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3624
3624
|
});
|
|
3625
|
-
await new Promise((
|
|
3625
|
+
await new Promise((resolve4) => {
|
|
3626
3626
|
if (process.stdout.writableNeedDrain) {
|
|
3627
|
-
process.stdout.once("drain",
|
|
3627
|
+
process.stdout.once("drain", resolve4);
|
|
3628
3628
|
} else {
|
|
3629
|
-
|
|
3629
|
+
resolve4();
|
|
3630
3630
|
}
|
|
3631
3631
|
});
|
|
3632
3632
|
process.exit(0);
|
|
@@ -3693,11 +3693,11 @@ async function chatCommand(prompt, args) {
|
|
|
3693
3693
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3694
3694
|
});
|
|
3695
3695
|
process.removeListener("SIGINT", sigintHandler);
|
|
3696
|
-
await new Promise((
|
|
3696
|
+
await new Promise((resolve4) => {
|
|
3697
3697
|
if (process.stdout.writableNeedDrain) {
|
|
3698
|
-
process.stdout.once("drain",
|
|
3698
|
+
process.stdout.once("drain", resolve4);
|
|
3699
3699
|
} else {
|
|
3700
|
-
|
|
3700
|
+
resolve4();
|
|
3701
3701
|
}
|
|
3702
3702
|
});
|
|
3703
3703
|
process.exit(result2.status === "interrupted" ? 130 : 0);
|
|
@@ -5380,11 +5380,11 @@ function preparedFile(filePath, content, mode) {
|
|
|
5380
5380
|
}
|
|
5381
5381
|
async function sha256File(file) {
|
|
5382
5382
|
const hash = createHash3("sha256");
|
|
5383
|
-
await new Promise((
|
|
5383
|
+
await new Promise((resolve4, reject) => {
|
|
5384
5384
|
const stream = createReadStream(file);
|
|
5385
5385
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
5386
5386
|
stream.on("error", reject);
|
|
5387
|
-
stream.on("end",
|
|
5387
|
+
stream.on("end", resolve4);
|
|
5388
5388
|
});
|
|
5389
5389
|
return hash.digest("hex");
|
|
5390
5390
|
}
|
|
@@ -6729,17 +6729,17 @@ async function metaListCommand(args) {
|
|
|
6729
6729
|
fail4(e, args);
|
|
6730
6730
|
}
|
|
6731
6731
|
}
|
|
6732
|
-
async function metaGetCommand(
|
|
6732
|
+
async function metaGetCommand(path10, args) {
|
|
6733
6733
|
try {
|
|
6734
6734
|
const c = await client2(args);
|
|
6735
|
-
const content = await getTenantMeta(c.raw(),
|
|
6735
|
+
const content = await getTenantMeta(c.raw(), path10);
|
|
6736
6736
|
process.stdout.write(content.endsWith("\n") ? content : content + "\n");
|
|
6737
6737
|
process.exit(0);
|
|
6738
6738
|
} catch (e) {
|
|
6739
6739
|
fail4(e, args);
|
|
6740
6740
|
}
|
|
6741
6741
|
}
|
|
6742
|
-
async function metaSetCommand(
|
|
6742
|
+
async function metaSetCommand(path10, args) {
|
|
6743
6743
|
try {
|
|
6744
6744
|
if (!args.file) {
|
|
6745
6745
|
throw new CliError20({
|
|
@@ -6747,16 +6747,16 @@ async function metaSetCommand(path9, args) {
|
|
|
6747
6747
|
message: "--file <path> \u5FC5\u586B\uFF08\u4ECE\u6587\u4EF6\u8BFB\u53D6 meta \u539F\u6587\uFF1B\u7528 - \u8868\u793A stdin\uFF09"
|
|
6748
6748
|
});
|
|
6749
6749
|
}
|
|
6750
|
-
const content = args.file === "-" ? await new Promise((
|
|
6750
|
+
const content = args.file === "-" ? await new Promise((resolve4, reject) => {
|
|
6751
6751
|
let buf = "";
|
|
6752
6752
|
process.stdin.setEncoding("utf8");
|
|
6753
6753
|
process.stdin.on("data", (d) => buf += d);
|
|
6754
|
-
process.stdin.on("end", () =>
|
|
6754
|
+
process.stdin.on("end", () => resolve4(buf));
|
|
6755
6755
|
process.stdin.on("error", reject);
|
|
6756
6756
|
}) : await fsp3.readFile(args.file, "utf8");
|
|
6757
6757
|
if (args.dryRun) {
|
|
6758
6758
|
process.stdout.write(
|
|
6759
|
-
`[dry-run] \u5C06\u5199\u5165 ${
|
|
6759
|
+
`[dry-run] \u5C06\u5199\u5165 ${path10}\uFF08${Buffer.byteLength(content)} B\uFF09\u2014\u2014\u672A\u5B9E\u9645\u5199\u5165
|
|
6760
6760
|
---
|
|
6761
6761
|
${content}
|
|
6762
6762
|
`
|
|
@@ -6764,10 +6764,10 @@ ${content}
|
|
|
6764
6764
|
process.exit(0);
|
|
6765
6765
|
}
|
|
6766
6766
|
const c = await client2(args);
|
|
6767
|
-
const result2 = await saveTenantMeta(c.raw(),
|
|
6767
|
+
const result2 = await saveTenantMeta(c.raw(), path10, content);
|
|
6768
6768
|
const fmt = args.output ?? "json";
|
|
6769
6769
|
if (fmt !== "json") {
|
|
6770
|
-
process.stdout.write(`\u2705 \u5DF2\u5199\u5165 ${
|
|
6770
|
+
process.stdout.write(`\u2705 \u5DF2\u5199\u5165 ${path10}
|
|
6771
6771
|
\u8BB0\u5F97\u6E05\u7F13\u5B58\uFF1Ahcm cache clear-meta <Model>
|
|
6772
6772
|
`);
|
|
6773
6773
|
}
|
|
@@ -6778,19 +6778,19 @@ ${content}
|
|
|
6778
6778
|
fail4(e, args);
|
|
6779
6779
|
}
|
|
6780
6780
|
}
|
|
6781
|
-
async function metaDeleteCommand(
|
|
6781
|
+
async function metaDeleteCommand(path10, args) {
|
|
6782
6782
|
try {
|
|
6783
6783
|
if (!args.yes) {
|
|
6784
|
-
const ok = await promptConfirm(`\u5C06\u5220\u9664\u5143\u6570\u636E ${
|
|
6784
|
+
const ok = await promptConfirm(`\u5C06\u5220\u9664\u5143\u6570\u636E ${path10}\uFF0C\u6B64\u64CD\u4F5C\u4E0D\u53EF\u9006\u3002\u7EE7\u7EED\uFF1F`);
|
|
6785
6785
|
if (!ok) {
|
|
6786
6786
|
process.stderr.write("\u5DF2\u53D6\u6D88\n");
|
|
6787
6787
|
process.exit(1);
|
|
6788
6788
|
}
|
|
6789
6789
|
}
|
|
6790
6790
|
const c = await client2(args);
|
|
6791
|
-
const result2 = await deleteTenantMeta(c.raw(),
|
|
6791
|
+
const result2 = await deleteTenantMeta(c.raw(), path10);
|
|
6792
6792
|
const fmt = args.output ?? "json";
|
|
6793
|
-
if (fmt !== "json") process.stdout.write(`\u{1F5D1}\uFE0F \u5DF2\u5220\u9664 ${
|
|
6793
|
+
if (fmt !== "json") process.stdout.write(`\u{1F5D1}\uFE0F \u5DF2\u5220\u9664 ${path10}
|
|
6794
6794
|
`);
|
|
6795
6795
|
process.stdout.write(formatObject16(result2, { format: fmt }) + "\n");
|
|
6796
6796
|
process.exit(0);
|
|
@@ -8644,12 +8644,123 @@ async function deliveryDoctorCommand(args) {
|
|
|
8644
8644
|
}
|
|
8645
8645
|
}
|
|
8646
8646
|
|
|
8647
|
+
// src/commands/delivery-recon.ts
|
|
8648
|
+
init_auth_guard();
|
|
8649
|
+
init_exit();
|
|
8650
|
+
import {
|
|
8651
|
+
HcmClient as HcmClient19,
|
|
8652
|
+
ReconLayout,
|
|
8653
|
+
ROUND_EXIT_CODES,
|
|
8654
|
+
computeReconSourceKey,
|
|
8655
|
+
formatObject as formatObject20,
|
|
8656
|
+
fromAxiosError as fromAxiosError18,
|
|
8657
|
+
httpProbe as httpProbe2,
|
|
8658
|
+
inspectRound,
|
|
8659
|
+
renderRound,
|
|
8660
|
+
runRecon
|
|
8661
|
+
} from "@hcmai/sdk";
|
|
8662
|
+
var DEFAULT_CAPABILITIES2 = "default";
|
|
8663
|
+
async function deliveryReconCommand(args) {
|
|
8664
|
+
try {
|
|
8665
|
+
const ctx = await getActiveAuthContextFromCli(args);
|
|
8666
|
+
const client3 = HcmClient19.fromAuthContext(ctx);
|
|
8667
|
+
const probe = httpProbe2(client3.raw(), args.capabilities ?? DEFAULT_CAPABILITIES2);
|
|
8668
|
+
const sourceKey = await computeReconSourceKey(probe);
|
|
8669
|
+
const layout = new ReconLayout(args.out ?? ".", ctx.tenantId, sourceKey);
|
|
8670
|
+
const summary = await runRecon(probe, layout, {
|
|
8671
|
+
state: args.state ?? "",
|
|
8672
|
+
onlyModel: args.model ?? null,
|
|
8673
|
+
identity: ctx.tenantId ? { requestedTenantId: ctx.tenantId } : null
|
|
8674
|
+
});
|
|
8675
|
+
process.stdout.write(formatObject20(summary, { format: args.output ?? "json" }) + "\n");
|
|
8676
|
+
} catch (e) {
|
|
8677
|
+
const err = e;
|
|
8678
|
+
if (err?.isAxiosError) exitWithError(fromAxiosError18(err, args.env));
|
|
8679
|
+
exitWithError(e);
|
|
8680
|
+
process.exit(1);
|
|
8681
|
+
}
|
|
8682
|
+
}
|
|
8683
|
+
async function deliveryReconRoundCommand(args) {
|
|
8684
|
+
let code;
|
|
8685
|
+
try {
|
|
8686
|
+
const result2 = inspectRound(args.dir ?? ".");
|
|
8687
|
+
const fmt = args.output ?? "json";
|
|
8688
|
+
if (fmt !== "json") process.stdout.write(renderRound(result2));
|
|
8689
|
+
process.stdout.write(formatObject20(result2, { format: fmt }) + "\n");
|
|
8690
|
+
code = ROUND_EXIT_CODES[result2.state];
|
|
8691
|
+
} catch (e) {
|
|
8692
|
+
exitWithError(e);
|
|
8693
|
+
code = 1;
|
|
8694
|
+
}
|
|
8695
|
+
process.exit(code);
|
|
8696
|
+
}
|
|
8697
|
+
|
|
8698
|
+
// src/commands/delivery-gate0.ts
|
|
8699
|
+
init_exit();
|
|
8700
|
+
import {
|
|
8701
|
+
baselineRoundPremise,
|
|
8702
|
+
checkPremise,
|
|
8703
|
+
CHANNELS,
|
|
8704
|
+
deriveAclass,
|
|
8705
|
+
exitCode as gate0ExitCode,
|
|
8706
|
+
formatObject as formatObject21,
|
|
8707
|
+
inspectRound as inspectRound2,
|
|
8708
|
+
loadProtocolFacts,
|
|
8709
|
+
scan
|
|
8710
|
+
} from "@hcmai/sdk";
|
|
8711
|
+
import * as path8 from "path";
|
|
8712
|
+
function renderGate0(result2, skillRoot) {
|
|
8713
|
+
const where = skillRoot ? `\uFF08${path8.resolve(skillRoot)}\uFF09` : "";
|
|
8714
|
+
const lines = [
|
|
8715
|
+
`\u626B\u63CF\u9762${where}\uFF1A${result2.scanned.length} \u4E2A\u6587\u4EF6\uFF1B\u5224\u7EA2 ${result2.red.length} \u6761\uFF1B\u7F3A\u53E3\u653E\u884C ${result2.gaps.length} \u6761\u3002`
|
|
8716
|
+
];
|
|
8717
|
+
for (const channel of CHANNELS) {
|
|
8718
|
+
const rows = result2.channels[channel];
|
|
8719
|
+
lines.push(` [${channel}] ${rows.length} \u6761`);
|
|
8720
|
+
for (const red of rows) lines.push(` - (${red.reason}) ${red.message}`);
|
|
8721
|
+
}
|
|
8722
|
+
if (result2.gaps.length > 0) {
|
|
8723
|
+
lines.push(` [gaps] ${result2.gaps.length} \u6761\uFF08\u4E0D\u9876 rc\uFF0C\u8BF7\u81EA\u5DF1\u770B\u4E00\u773C\uFF09`);
|
|
8724
|
+
for (const gap of result2.gaps) lines.push(` - (${gap.reason}) ${gap.why}`);
|
|
8725
|
+
}
|
|
8726
|
+
return `${lines.join("\n")}
|
|
8727
|
+
`;
|
|
8728
|
+
}
|
|
8729
|
+
async function deliveryGate0Command(args) {
|
|
8730
|
+
let code;
|
|
8731
|
+
try {
|
|
8732
|
+
const skillRoot = args.skills ?? ".";
|
|
8733
|
+
const reconDir = args.recon ?? ".";
|
|
8734
|
+
const { aclass, problems: aclassProblems } = deriveAclass(reconDir, args.mapping ?? null);
|
|
8735
|
+
const { facts, problems: factsProblems } = loadProtocolFacts();
|
|
8736
|
+
const result2 = scan(skillRoot, aclass, facts, { aclassProblems, factsProblems });
|
|
8737
|
+
const premise = checkPremise([
|
|
8738
|
+
...result2.premise,
|
|
8739
|
+
...baselineRoundPremise(inspectRound2(reconDir))
|
|
8740
|
+
]);
|
|
8741
|
+
const merged = { ...result2, premise };
|
|
8742
|
+
const fmt = args.output ?? "json";
|
|
8743
|
+
if (fmt !== "json") process.stdout.write(renderGate0(merged, skillRoot));
|
|
8744
|
+
process.stdout.write(`${formatObject21(merged, { format: fmt })}
|
|
8745
|
+
`);
|
|
8746
|
+
for (const problem of premise) {
|
|
8747
|
+
process.stderr.write(`\u{1F534} \u524D\u63D0\u4E0D\u6210\u7ACB\uFF08${problem.reason}\uFF09\uFF1A${problem.message}
|
|
8748
|
+
`);
|
|
8749
|
+
}
|
|
8750
|
+
code = gate0ExitCode(merged);
|
|
8751
|
+
} catch (e) {
|
|
8752
|
+
exitWithError(e);
|
|
8753
|
+
code = 1;
|
|
8754
|
+
}
|
|
8755
|
+
process.exit(code);
|
|
8756
|
+
}
|
|
8757
|
+
|
|
8647
8758
|
// src/commands/delivery-execution.ts
|
|
8648
8759
|
import { createHash as createHash7, randomBytes as secureRandomBytes } from "crypto";
|
|
8649
8760
|
import { spawn } from "child_process";
|
|
8650
8761
|
import { createReadStream as createReadStream2, promises as fs8 } from "fs";
|
|
8651
|
-
import
|
|
8652
|
-
import { CliError as CliError22, CliErrorCode as CliErrorCode21, formatObject as
|
|
8762
|
+
import path9 from "path";
|
|
8763
|
+
import { CliError as CliError22, CliErrorCode as CliErrorCode21, formatObject as formatObject22 } from "@hcmai/sdk";
|
|
8653
8764
|
init_exit();
|
|
8654
8765
|
var EXECUTION_CONTRACT_VERSION = "2026-08-29.controlled-v2";
|
|
8655
8766
|
var DEFAULT_TTL_SECONDS = 15 * 60;
|
|
@@ -8689,9 +8800,9 @@ async function prepareDeliveryExecution(input) {
|
|
|
8689
8800
|
};
|
|
8690
8801
|
const planId = sha2567(canonicalJson(core)).slice(0, 24);
|
|
8691
8802
|
const plan = { ...core, planId };
|
|
8692
|
-
const plansDir =
|
|
8803
|
+
const plansDir = path9.join(project, ".hcm-delivery", "execution-plans");
|
|
8693
8804
|
await safeManagedDirectory(project, ".hcm-delivery/execution-plans", plansDir);
|
|
8694
|
-
const planFile =
|
|
8805
|
+
const planFile = path9.join(plansDir, `${planId}.json`);
|
|
8695
8806
|
try {
|
|
8696
8807
|
await fs8.writeFile(planFile, `${JSON.stringify(plan, null, 2)}
|
|
8697
8808
|
`, {
|
|
@@ -8710,7 +8821,7 @@ async function executeDeliveryPlan(input) {
|
|
|
8710
8821
|
if (await readProjectMode(project) !== "controlled") {
|
|
8711
8822
|
throw invalid4("\u9879\u76EE\u4E0D\u662F controlled\uFF0C\u4E0D\u80FD\u6267\u884C R2 \u8BA1\u5212");
|
|
8712
8823
|
}
|
|
8713
|
-
const planFile =
|
|
8824
|
+
const planFile = path9.join(project, ".hcm-delivery", "execution-plans", `${input.planId}.json`);
|
|
8714
8825
|
const plan = await readPlan(project, planFile);
|
|
8715
8826
|
if (plan.planId !== input.planId || computePlanId(plan) !== input.planId) {
|
|
8716
8827
|
throw invalid4("\u6267\u884C\u8BA1\u5212\u5185\u5BB9\u4E0E planId \u6458\u8981\u4E0D\u4E00\u81F4");
|
|
@@ -8742,11 +8853,11 @@ async function executeDeliveryPlan(input) {
|
|
|
8742
8853
|
await assertDocumentUnchanged(project, plan.documents.rollback, "\u56DE\u6EDA\u8BF4\u660E");
|
|
8743
8854
|
await assertPayloadsUnchanged(project, plan.payloads);
|
|
8744
8855
|
const evidenceDir = await bindEvidenceDirectory(project, plan.evidenceDir);
|
|
8745
|
-
const receiptFile =
|
|
8856
|
+
const receiptFile = path9.join(evidenceDir.absolute, `${plan.planId}.receipt.json`);
|
|
8746
8857
|
if (await pathExists(receiptFile)) throw invalid4(`\u6267\u884C\u6536\u636E\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u518D\u6B21\u6267\u884C\uFF1A${plan.planId}`);
|
|
8747
|
-
const claimsDir =
|
|
8858
|
+
const claimsDir = path9.join(project, ".hcm-delivery", "execution-claims");
|
|
8748
8859
|
await safeManagedDirectory(project, ".hcm-delivery/execution-claims", claimsDir);
|
|
8749
|
-
const claimFile =
|
|
8860
|
+
const claimFile = path9.join(claimsDir, `${plan.planId}.json`);
|
|
8750
8861
|
try {
|
|
8751
8862
|
await fs8.writeFile(
|
|
8752
8863
|
claimFile,
|
|
@@ -8805,7 +8916,7 @@ async function deliveryPrepareCommand(argv, args) {
|
|
|
8805
8916
|
evidenceDir: args.evidenceDir,
|
|
8806
8917
|
...ttlSeconds === void 0 ? {} : { ttlSeconds }
|
|
8807
8918
|
});
|
|
8808
|
-
process.stdout.write(
|
|
8919
|
+
process.stdout.write(formatObject22(plan, { format: args.output ?? "json" }) + "\n");
|
|
8809
8920
|
} catch (cause) {
|
|
8810
8921
|
exitWithError(cause);
|
|
8811
8922
|
}
|
|
@@ -8817,14 +8928,14 @@ async function deliveryExecuteCommand(planId, argv, args) {
|
|
|
8817
8928
|
planId,
|
|
8818
8929
|
argv
|
|
8819
8930
|
});
|
|
8820
|
-
process.stdout.write(
|
|
8931
|
+
process.stdout.write(formatObject22(receipt, { format: args.output ?? "json" }) + "\n");
|
|
8821
8932
|
process.exitCode = receipt.exitCode;
|
|
8822
8933
|
} catch (cause) {
|
|
8823
8934
|
exitWithError(cause);
|
|
8824
8935
|
}
|
|
8825
8936
|
}
|
|
8826
8937
|
async function readProjectMode(project) {
|
|
8827
|
-
const file =
|
|
8938
|
+
const file = path9.join(project, ".hcm-delivery", "project.yml");
|
|
8828
8939
|
const content = await readSafeFile(project, file, "\u9879\u76EE\u914D\u7F6E");
|
|
8829
8940
|
const match = content.toString("utf8").match(
|
|
8830
8941
|
/^deliveryMode:\s*(?:"(plan-only|controlled)"|'(plan-only|controlled)'|(plan-only|controlled))\s*$/m
|
|
@@ -8836,7 +8947,7 @@ async function readProjectMode(project) {
|
|
|
8836
8947
|
return mode;
|
|
8837
8948
|
}
|
|
8838
8949
|
async function readChironLock(project) {
|
|
8839
|
-
const file =
|
|
8950
|
+
const file = path9.join(project, ".hcm-delivery", "chiron.lock.json");
|
|
8840
8951
|
const bytes = await readSafeFile(project, file, "Chiron \u9501");
|
|
8841
8952
|
let parsed;
|
|
8842
8953
|
try {
|
|
@@ -8853,7 +8964,7 @@ async function bindDocument(project, reference, label) {
|
|
|
8853
8964
|
if (!(relative2.startsWith("work/") || relative2.startsWith("decisions/"))) {
|
|
8854
8965
|
throw invalid4(`${label}\u5FC5\u987B\u4F4D\u4E8E\u9879\u76EE work/ \u6216 decisions/ \u4E0B`);
|
|
8855
8966
|
}
|
|
8856
|
-
const file =
|
|
8967
|
+
const file = path9.join(project, relative2);
|
|
8857
8968
|
const bytes = await readSafeFile(project, file, label);
|
|
8858
8969
|
return { path: relative2, sha256: sha2567(bytes) };
|
|
8859
8970
|
}
|
|
@@ -8866,7 +8977,7 @@ async function bindEvidenceDirectory(project, reference) {
|
|
|
8866
8977
|
if (!(relative2 === "evidence" || relative2.startsWith("evidence/"))) {
|
|
8867
8978
|
throw invalid4("evidence \u76EE\u5F55\u5FC5\u987B\u4F4D\u4E8E\u9879\u76EE evidence/ \u4E0B");
|
|
8868
8979
|
}
|
|
8869
|
-
const absolute =
|
|
8980
|
+
const absolute = path9.join(project, relative2);
|
|
8870
8981
|
await assertNoSymlinkComponents(project, relative2);
|
|
8871
8982
|
const stat = await fs8.stat(absolute).catch((cause) => {
|
|
8872
8983
|
throw invalid4(`evidence \u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${relative2}`, cause);
|
|
@@ -8987,7 +9098,7 @@ async function bindPayloadFiles(project, argv) {
|
|
|
8987
9098
|
}
|
|
8988
9099
|
async function bindPayloadFile(project, reference, label) {
|
|
8989
9100
|
const relative2 = safeRelative(reference, label);
|
|
8990
|
-
const file =
|
|
9101
|
+
const file = path9.join(project, relative2);
|
|
8991
9102
|
const bytes = await readSafeFile(project, file, label);
|
|
8992
9103
|
return { path: relative2, sha256: sha2567(bytes) };
|
|
8993
9104
|
}
|
|
@@ -9030,7 +9141,7 @@ async function currentRuntimeIdentity() {
|
|
|
9030
9141
|
async function runCurrentCliCommand(argv, cwd, streams) {
|
|
9031
9142
|
const entry = process.argv[1];
|
|
9032
9143
|
if (!entry) throw invalid4("\u65E0\u6CD5\u89E3\u6790\u5F53\u524D CLI entry");
|
|
9033
|
-
return new Promise((
|
|
9144
|
+
return new Promise((resolve4, reject) => {
|
|
9034
9145
|
const child = spawn(process.execPath, [entry, ...argv], {
|
|
9035
9146
|
cwd,
|
|
9036
9147
|
env: process.env,
|
|
@@ -9047,7 +9158,7 @@ async function runCurrentCliCommand(argv, cwd, streams) {
|
|
|
9047
9158
|
process.stderr.write(chunk);
|
|
9048
9159
|
});
|
|
9049
9160
|
child.once("error", reject);
|
|
9050
|
-
child.once("close", (code, signal) =>
|
|
9161
|
+
child.once("close", (code, signal) => resolve4({ exitCode: code ?? (signal ? 1 : 0) }));
|
|
9051
9162
|
});
|
|
9052
9163
|
}
|
|
9053
9164
|
async function writeReceiptExclusive(target, receipt) {
|
|
@@ -9061,13 +9172,13 @@ async function writeReceiptExclusive(target, receipt) {
|
|
|
9061
9172
|
});
|
|
9062
9173
|
await fs8.link(temp, target);
|
|
9063
9174
|
} catch (cause) {
|
|
9064
|
-
throw invalid4(`\u6267\u884C\u6536\u636E\u5199\u5165\u5931\u8D25\u6216\u5DF2\u5B58\u5728\uFF1A${
|
|
9175
|
+
throw invalid4(`\u6267\u884C\u6536\u636E\u5199\u5165\u5931\u8D25\u6216\u5DF2\u5B58\u5728\uFF1A${path9.basename(target)}`, cause);
|
|
9065
9176
|
} finally {
|
|
9066
9177
|
await fs8.unlink(temp).catch(() => void 0);
|
|
9067
9178
|
}
|
|
9068
9179
|
}
|
|
9069
9180
|
async function safeManagedDirectory(project, relative2, absolute) {
|
|
9070
|
-
await assertNoSymlinkComponents(project,
|
|
9181
|
+
await assertNoSymlinkComponents(project, path9.dirname(relative2));
|
|
9071
9182
|
const existing = await fs8.lstat(absolute).catch(() => void 0);
|
|
9072
9183
|
if (existing?.isSymbolicLink()) throw invalid4(`\u53D7\u7BA1\u76EE\u5F55\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
9073
9184
|
if (existing && !existing.isDirectory()) throw invalid4(`\u53D7\u7BA1\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${relative2}`);
|
|
@@ -9084,8 +9195,8 @@ async function pathExists(file) {
|
|
|
9084
9195
|
);
|
|
9085
9196
|
}
|
|
9086
9197
|
async function readSafeFile(project, file, label) {
|
|
9087
|
-
const relative2 =
|
|
9088
|
-
if (relative2.startsWith("../") ||
|
|
9198
|
+
const relative2 = path9.relative(project, file).split(path9.sep).join("/");
|
|
9199
|
+
if (relative2.startsWith("../") || path9.isAbsolute(relative2))
|
|
9089
9200
|
throw invalid4(`${label}\u8DEF\u5F84\u9003\u9038\u9879\u76EE`);
|
|
9090
9201
|
await assertNoSymlinkComponents(project, relative2);
|
|
9091
9202
|
let stat;
|
|
@@ -9102,14 +9213,14 @@ async function assertNoSymlinkComponents(project, relative2) {
|
|
|
9102
9213
|
const parts = relative2.split("/").filter(Boolean);
|
|
9103
9214
|
let current = project;
|
|
9104
9215
|
for (const part of parts) {
|
|
9105
|
-
current =
|
|
9216
|
+
current = path9.join(current, part);
|
|
9106
9217
|
const stat = await fs8.lstat(current).catch(() => void 0);
|
|
9107
9218
|
if (stat?.isSymbolicLink()) throw invalid4(`\u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
9108
9219
|
if (!stat) break;
|
|
9109
9220
|
}
|
|
9110
9221
|
}
|
|
9111
9222
|
async function realProject(requested) {
|
|
9112
|
-
const absolute =
|
|
9223
|
+
const absolute = path9.resolve(requested);
|
|
9113
9224
|
let project;
|
|
9114
9225
|
try {
|
|
9115
9226
|
project = await fs8.realpath(absolute);
|
|
@@ -9121,10 +9232,10 @@ async function realProject(requested) {
|
|
|
9121
9232
|
return project;
|
|
9122
9233
|
}
|
|
9123
9234
|
function safeRelative(reference, label) {
|
|
9124
|
-
if (!reference ||
|
|
9235
|
+
if (!reference || path9.isAbsolute(reference) || /[\r\n\0]/.test(reference)) {
|
|
9125
9236
|
throw invalid4(`${label}\u5FC5\u987B\u662F\u9879\u76EE\u5185\u76F8\u5BF9\u8DEF\u5F84`);
|
|
9126
9237
|
}
|
|
9127
|
-
const normalized =
|
|
9238
|
+
const normalized = path9.normalize(reference).split(path9.sep).join("/");
|
|
9128
9239
|
if (normalized === ".." || normalized.startsWith("../") || normalized === ".") {
|
|
9129
9240
|
throw invalid4(`${label}\u8DEF\u5F84\u9003\u9038\u9879\u76EE`);
|
|
9130
9241
|
}
|
|
@@ -9165,11 +9276,11 @@ function sha2567(value) {
|
|
|
9165
9276
|
}
|
|
9166
9277
|
async function sha256File2(file) {
|
|
9167
9278
|
const hash = createHash7("sha256");
|
|
9168
|
-
await new Promise((
|
|
9279
|
+
await new Promise((resolve4, reject) => {
|
|
9169
9280
|
const stream = createReadStream2(file);
|
|
9170
9281
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
9171
9282
|
stream.on("error", reject);
|
|
9172
|
-
stream.on("end",
|
|
9283
|
+
stream.on("end", resolve4);
|
|
9173
9284
|
});
|
|
9174
9285
|
return hash.digest("hex");
|
|
9175
9286
|
}
|
|
@@ -9181,10 +9292,10 @@ function invalid4(message, cause) {
|
|
|
9181
9292
|
init_auth_guard();
|
|
9182
9293
|
init_exit();
|
|
9183
9294
|
import {
|
|
9184
|
-
HcmClient as
|
|
9295
|
+
HcmClient as HcmClient20,
|
|
9185
9296
|
adminResetPassword,
|
|
9186
|
-
formatObject as
|
|
9187
|
-
fromAxiosError as
|
|
9297
|
+
formatObject as formatObject23,
|
|
9298
|
+
fromAxiosError as fromAxiosError19,
|
|
9188
9299
|
CliError as CliError23,
|
|
9189
9300
|
CliErrorCode as CliErrorCode22
|
|
9190
9301
|
} from "@hcmai/sdk";
|
|
@@ -9215,12 +9326,12 @@ async function userResetPasswordCommand(args) {
|
|
|
9215
9326
|
try {
|
|
9216
9327
|
const password = args.passwordStdin ? await readSecretFromStdin() : await promptPasswordTwice();
|
|
9217
9328
|
const request = buildAdminResetPasswordRequest(args, password);
|
|
9218
|
-
const client3 =
|
|
9329
|
+
const client3 = HcmClient20.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
9219
9330
|
const result2 = await adminResetPassword(client3.raw(), request);
|
|
9220
|
-
process.stdout.write(
|
|
9331
|
+
process.stdout.write(formatObject23(result2, { format: args.output ?? "json" }) + "\n");
|
|
9221
9332
|
} catch (cause) {
|
|
9222
9333
|
const err = cause;
|
|
9223
|
-
if (err?.isAxiosError) exitWithError(
|
|
9334
|
+
if (err?.isAxiosError) exitWithError(fromAxiosError19(err, args.env));
|
|
9224
9335
|
exitWithError(cause);
|
|
9225
9336
|
}
|
|
9226
9337
|
}
|
|
@@ -9278,6 +9389,19 @@ user.command("reset-password").description("\u7531 admin.system \u5B89\u5168\u91
|
|
|
9278
9389
|
var delivery = program.command("delivery").description("\u987E\u95EE\u4EA4\u4ED8\uFF1A\u73B0\u573A\u63A2\u6D3B\u3001\u98CE\u9669\u8BC4\u4F30\u4E0E\u4E00\u6B21\u6027\u53D7\u63A7\u6267\u884C\u5408\u540C");
|
|
9279
9390
|
delivery.command("assess").description("\u8BC4\u4F30\u4E00\u6B21 HCM CLI argv\uFF1BAction \u98CE\u63A7\u58F0\u660E\u8BFB\u53D6\u81EA\u76EE\u6807 Core\uFF0C\u7528 -- \u5206\u9694\u88AB\u8BC4\u4F30\u547D\u4EE4").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").allowUnknownOption(true).argument("<command...>", "\u88AB\u8BC4\u4F30\u7684 HCM \u5B50\u547D\u4EE4\u4E0E\u53C2\u6570\uFF0C\u4E0D\u5305\u542B hcm \u672C\u8EAB").action((command, opts) => deliveryAssessCommand(command, opts));
|
|
9280
9391
|
delivery.command("doctor").description("\u56DB\u6761\u951A\u70B9\u63A2\u6D3B\uFF1A\u8FDE\u901A / \u6211\u662F\u8C01 / configAdmin / \u7AD9\u5728\u54EA\u4E00\u5C42").option("--env <name>", "\u76EE\u6807\u73AF\u5883\u522B\u540D").option("--as <identity>", "\u4E34\u65F6\u6362\u8EAB\u4EFD").option("--capabilities <s>", "\u722C\u53D6\u65F6\u58F0\u660E\u7684 capability \u4E32\uFF08\u4F1A\u968F\u56DB\u5143\u7EC4\u7559\u6863\uFF09").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((opts) => deliveryDoctorCommand(opts));
|
|
9392
|
+
var recon = delivery.command("recon").description("\u722C\u4E00\u4EFD\u53EF\u5E26\u8D70\u7684\u57FA\u7EBF\uFF1A\u6A21\u578B / \u5B57\u6BB5 / \u53EA\u8BFB\u95F8 / \u4F9D\u8D56\u56FE / \u7801\u8868 / \u53EF\u5199\u6027\u753B\u50CF").option("--env <name>", "\u76EE\u6807\u73AF\u5883\u522B\u540D").option("--as <identity>", "\u4E34\u65F6\u6362\u8EAB\u4EFD").option("--out <dir>", "\u4EA7\u7269\u6839\u76EE\u5F55\uFF08\u4EA7\u7269\u843D\u5728 <out>/recon/<\u79DF\u6237\u6BB5>/<\u6765\u6E90\u6BB5>\uFF09", ".").option("--state <s>", "\u53EA\u8BFB\u95F8\u7684 state\uFF08\u4EA7\u54C1\u91CC state \u4E0D\u53EF\u679A\u4E3E\uFF0C\u95F8\u7684\u8986\u76D6\u9762\u6C38\u8FDC\u662F state-scoped\uFF09").option("--model <key>", "\u5B9A\u5411\u91CD\u722C\uFF1A\u53EA\u91CD\u722C\u8FD9\u4E00\u4E2A\u6A21\u578B\uFF0C\u5176\u4F59\u6CBF\u7528\u4E0A\u4E00\u8F6E\u4EA7\u7269").option("--capabilities <s>", "\u722C\u53D6\u65F6\u58F0\u660E\u7684 capability \u4E32\uFF08\u4F1A\u968F\u56DB\u5143\u7EC4\u7559\u6863\uFF09").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((opts) => deliveryReconCommand(opts));
|
|
9393
|
+
recon.command("round").description("\u96F6\u7F51\u7EDC\uFF1A\u8BFB\u4E00\u4EFD\u5DF2\u843D\u76D8\u7684\u57FA\u7EBF\uFF0C\u5224\u65AD\u5B83\u662F\u4E0D\u662F\u4E00\u8F6E\u5B8C\u6574\u8DD1\u51FA\u6765\u7684\uFF08complete/mixed/unknown\uFF09").option("--dir <dir>", "\u4EA7\u7269\u76EE\u5F55\uFF08<out>/recon/<\u79DF\u6237\u6BB5>/<\u6765\u6E90\u6BB5>\uFF09", ".").action(
|
|
9394
|
+
(opts, cmd) => deliveryReconRoundCommand({
|
|
9395
|
+
...opts,
|
|
9396
|
+
output: cmd.parent?.opts()?.output
|
|
9397
|
+
})
|
|
9398
|
+
);
|
|
9399
|
+
delivery.command("gate0").description(
|
|
9400
|
+
"\u96F6\u7F51\u7EDC\uFF1A\u626B\u4E00\u4EFD skill \u7684\u6B63\u6587\uFF0C\u628A\u73AF\u5883\u4E8B\u5B9E / \u672A\u767B\u8BB0\u7684\u534F\u8BAE\u5F62\u6001 / \u4EA7\u7269\u8DEF\u5F84\u6321\u5728\u6210\u7A3F\u4E4B\u5916"
|
|
9401
|
+
).requiredOption("--skills <dir>", "\u8981\u626B\u7684 skill \u6839\u76EE\u5F55\uFF08\u6B63\u6587 + references/ \u5168\u76EE\u5F55\uFF0C\u540C\u4E00\u5224\u636E\uFF09").option("--recon <dir>", "\u57FA\u7EBF\u4EA7\u7269\u76EE\u5F55\uFF08<out>/recon/<\u79DF\u6237\u6BB5>/<\u6765\u6E90\u6BB5>\uFF09", ".").option(
|
|
9402
|
+
"--mapping <file>",
|
|
9403
|
+
"\u987E\u95EE\u624B\u5199\u7684\u6620\u5C04\u5DE5\u4EF6\uFF08naturalKey \u8FD9\u4E00\u7C7B\u7684\u552F\u4E00\u6765\u6E90\uFF09\uFF1B\u4E0D\u7ED9 \u21D2 \u90A3\u4E00\u7C7B\u6052\u7EFF \u21D2 rc=2"
|
|
9404
|
+
).option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((opts) => deliveryGate0Command(opts));
|
|
9281
9405
|
delivery.command("prepare").description("\u628A\u53D7\u652F\u6301\u7684 R2 argv \u4E0E\u9501\u3001\u8FD0\u884C\u65F6\u548C\u53D8\u66F4/\u56DE\u6EDA\u8BF4\u660E\u7ED1\u5B9A\u4E3A\u77ED\u65F6\u6267\u884C\u8BA1\u5212").requiredOption("--change-ref <file>", "\u9879\u76EE work/ \u6216 decisions/ \u4E0B\u7684\u53D8\u66F4\u8BF4\u660E").requiredOption("--rollback-ref <file>", "\u9879\u76EE work/ \u6216 decisions/ \u4E0B\u7684\u56DE\u6EDA\u8BF4\u660E").requiredOption("--evidence-dir <dir>", "\u9879\u76EE evidence/ \u4E0B\u7684\u6536\u636E\u76EE\u5F55").option("--project <dir>", "HCM \u987E\u95EE\u9879\u76EE\u6839\u76EE\u5F55", ".").option("--ttl-seconds <n>", "\u6709\u6548\u671F\u79D2\u6570\uFF0860-3600\uFF09", "900").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").allowUnknownOption(true).argument("<command...>", "\u88AB\u7ED1\u5B9A\u7684 R2 HCM \u5B50\u547D\u4EE4\u4E0E\u53C2\u6570\uFF0C\u4E0D\u5305\u542B hcm \u672C\u8EAB").action((command, opts) => deliveryPrepareCommand(command, opts));
|
|
9282
9406
|
delivery.command("execute <planId>").description("\u9010\u6B21\u6279\u51C6\u540E\u6D88\u8D39\u77ED\u65F6\u8BA1\u5212\uFF0C\u5E76\u6267\u884C\u4E00\u6B21\u4E0E\u8BA1\u5212\u5B8C\u5168\u76F8\u540C\u7684 R2 argv").option("--project <dir>", "HCM \u987E\u95EE\u9879\u76EE\u6839\u76EE\u5F55", ".").option("--output <fmt>", "\u6536\u636E\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").allowUnknownOption(true).argument("<command...>", "\u4E0E prepare \u5B8C\u5168\u76F8\u540C\u7684 R2 HCM \u5B50\u547D\u4EE4\u4E0E\u53C2\u6570").action((planId, command, opts) => deliveryExecuteCommand(planId, command, opts));
|
|
9283
9407
|
program.command("query <Model>").description("\u67E5\u8BE2 Model \u5217\u8868\u6570\u636E\uFF08\u901A\u8FC7 ModelQueryDsl JSON \u8868\u8FBE\u8FC7\u6EE4/\u6392\u5E8F/\u5206\u9875\uFF09").option(
|