@hcmai/cli 0.3.7 → 0.3.9
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 +130 -64
- package/dist/index.js.map +1 -1
- package/dist/skills/hcm-delivery-gate0/SKILL.md +78 -0
- package/dist/skills/llms.txt +1 -0
- package/dist/skills/manifest.json +31 -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);
|
|
@@ -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);
|
|
@@ -8695,12 +8695,72 @@ async function deliveryReconRoundCommand(args) {
|
|
|
8695
8695
|
process.exit(code);
|
|
8696
8696
|
}
|
|
8697
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
|
+
|
|
8698
8758
|
// src/commands/delivery-execution.ts
|
|
8699
8759
|
import { createHash as createHash7, randomBytes as secureRandomBytes } from "crypto";
|
|
8700
8760
|
import { spawn } from "child_process";
|
|
8701
8761
|
import { createReadStream as createReadStream2, promises as fs8 } from "fs";
|
|
8702
|
-
import
|
|
8703
|
-
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";
|
|
8704
8764
|
init_exit();
|
|
8705
8765
|
var EXECUTION_CONTRACT_VERSION = "2026-08-29.controlled-v2";
|
|
8706
8766
|
var DEFAULT_TTL_SECONDS = 15 * 60;
|
|
@@ -8740,9 +8800,9 @@ async function prepareDeliveryExecution(input) {
|
|
|
8740
8800
|
};
|
|
8741
8801
|
const planId = sha2567(canonicalJson(core)).slice(0, 24);
|
|
8742
8802
|
const plan = { ...core, planId };
|
|
8743
|
-
const plansDir =
|
|
8803
|
+
const plansDir = path9.join(project, ".hcm-delivery", "execution-plans");
|
|
8744
8804
|
await safeManagedDirectory(project, ".hcm-delivery/execution-plans", plansDir);
|
|
8745
|
-
const planFile =
|
|
8805
|
+
const planFile = path9.join(plansDir, `${planId}.json`);
|
|
8746
8806
|
try {
|
|
8747
8807
|
await fs8.writeFile(planFile, `${JSON.stringify(plan, null, 2)}
|
|
8748
8808
|
`, {
|
|
@@ -8761,7 +8821,7 @@ async function executeDeliveryPlan(input) {
|
|
|
8761
8821
|
if (await readProjectMode(project) !== "controlled") {
|
|
8762
8822
|
throw invalid4("\u9879\u76EE\u4E0D\u662F controlled\uFF0C\u4E0D\u80FD\u6267\u884C R2 \u8BA1\u5212");
|
|
8763
8823
|
}
|
|
8764
|
-
const planFile =
|
|
8824
|
+
const planFile = path9.join(project, ".hcm-delivery", "execution-plans", `${input.planId}.json`);
|
|
8765
8825
|
const plan = await readPlan(project, planFile);
|
|
8766
8826
|
if (plan.planId !== input.planId || computePlanId(plan) !== input.planId) {
|
|
8767
8827
|
throw invalid4("\u6267\u884C\u8BA1\u5212\u5185\u5BB9\u4E0E planId \u6458\u8981\u4E0D\u4E00\u81F4");
|
|
@@ -8793,11 +8853,11 @@ async function executeDeliveryPlan(input) {
|
|
|
8793
8853
|
await assertDocumentUnchanged(project, plan.documents.rollback, "\u56DE\u6EDA\u8BF4\u660E");
|
|
8794
8854
|
await assertPayloadsUnchanged(project, plan.payloads);
|
|
8795
8855
|
const evidenceDir = await bindEvidenceDirectory(project, plan.evidenceDir);
|
|
8796
|
-
const receiptFile =
|
|
8856
|
+
const receiptFile = path9.join(evidenceDir.absolute, `${plan.planId}.receipt.json`);
|
|
8797
8857
|
if (await pathExists(receiptFile)) throw invalid4(`\u6267\u884C\u6536\u636E\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u518D\u6B21\u6267\u884C\uFF1A${plan.planId}`);
|
|
8798
|
-
const claimsDir =
|
|
8858
|
+
const claimsDir = path9.join(project, ".hcm-delivery", "execution-claims");
|
|
8799
8859
|
await safeManagedDirectory(project, ".hcm-delivery/execution-claims", claimsDir);
|
|
8800
|
-
const claimFile =
|
|
8860
|
+
const claimFile = path9.join(claimsDir, `${plan.planId}.json`);
|
|
8801
8861
|
try {
|
|
8802
8862
|
await fs8.writeFile(
|
|
8803
8863
|
claimFile,
|
|
@@ -8856,7 +8916,7 @@ async function deliveryPrepareCommand(argv, args) {
|
|
|
8856
8916
|
evidenceDir: args.evidenceDir,
|
|
8857
8917
|
...ttlSeconds === void 0 ? {} : { ttlSeconds }
|
|
8858
8918
|
});
|
|
8859
|
-
process.stdout.write(
|
|
8919
|
+
process.stdout.write(formatObject22(plan, { format: args.output ?? "json" }) + "\n");
|
|
8860
8920
|
} catch (cause) {
|
|
8861
8921
|
exitWithError(cause);
|
|
8862
8922
|
}
|
|
@@ -8868,14 +8928,14 @@ async function deliveryExecuteCommand(planId, argv, args) {
|
|
|
8868
8928
|
planId,
|
|
8869
8929
|
argv
|
|
8870
8930
|
});
|
|
8871
|
-
process.stdout.write(
|
|
8931
|
+
process.stdout.write(formatObject22(receipt, { format: args.output ?? "json" }) + "\n");
|
|
8872
8932
|
process.exitCode = receipt.exitCode;
|
|
8873
8933
|
} catch (cause) {
|
|
8874
8934
|
exitWithError(cause);
|
|
8875
8935
|
}
|
|
8876
8936
|
}
|
|
8877
8937
|
async function readProjectMode(project) {
|
|
8878
|
-
const file =
|
|
8938
|
+
const file = path9.join(project, ".hcm-delivery", "project.yml");
|
|
8879
8939
|
const content = await readSafeFile(project, file, "\u9879\u76EE\u914D\u7F6E");
|
|
8880
8940
|
const match = content.toString("utf8").match(
|
|
8881
8941
|
/^deliveryMode:\s*(?:"(plan-only|controlled)"|'(plan-only|controlled)'|(plan-only|controlled))\s*$/m
|
|
@@ -8887,7 +8947,7 @@ async function readProjectMode(project) {
|
|
|
8887
8947
|
return mode;
|
|
8888
8948
|
}
|
|
8889
8949
|
async function readChironLock(project) {
|
|
8890
|
-
const file =
|
|
8950
|
+
const file = path9.join(project, ".hcm-delivery", "chiron.lock.json");
|
|
8891
8951
|
const bytes = await readSafeFile(project, file, "Chiron \u9501");
|
|
8892
8952
|
let parsed;
|
|
8893
8953
|
try {
|
|
@@ -8904,7 +8964,7 @@ async function bindDocument(project, reference, label) {
|
|
|
8904
8964
|
if (!(relative2.startsWith("work/") || relative2.startsWith("decisions/"))) {
|
|
8905
8965
|
throw invalid4(`${label}\u5FC5\u987B\u4F4D\u4E8E\u9879\u76EE work/ \u6216 decisions/ \u4E0B`);
|
|
8906
8966
|
}
|
|
8907
|
-
const file =
|
|
8967
|
+
const file = path9.join(project, relative2);
|
|
8908
8968
|
const bytes = await readSafeFile(project, file, label);
|
|
8909
8969
|
return { path: relative2, sha256: sha2567(bytes) };
|
|
8910
8970
|
}
|
|
@@ -8917,7 +8977,7 @@ async function bindEvidenceDirectory(project, reference) {
|
|
|
8917
8977
|
if (!(relative2 === "evidence" || relative2.startsWith("evidence/"))) {
|
|
8918
8978
|
throw invalid4("evidence \u76EE\u5F55\u5FC5\u987B\u4F4D\u4E8E\u9879\u76EE evidence/ \u4E0B");
|
|
8919
8979
|
}
|
|
8920
|
-
const absolute =
|
|
8980
|
+
const absolute = path9.join(project, relative2);
|
|
8921
8981
|
await assertNoSymlinkComponents(project, relative2);
|
|
8922
8982
|
const stat = await fs8.stat(absolute).catch((cause) => {
|
|
8923
8983
|
throw invalid4(`evidence \u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${relative2}`, cause);
|
|
@@ -9038,7 +9098,7 @@ async function bindPayloadFiles(project, argv) {
|
|
|
9038
9098
|
}
|
|
9039
9099
|
async function bindPayloadFile(project, reference, label) {
|
|
9040
9100
|
const relative2 = safeRelative(reference, label);
|
|
9041
|
-
const file =
|
|
9101
|
+
const file = path9.join(project, relative2);
|
|
9042
9102
|
const bytes = await readSafeFile(project, file, label);
|
|
9043
9103
|
return { path: relative2, sha256: sha2567(bytes) };
|
|
9044
9104
|
}
|
|
@@ -9081,7 +9141,7 @@ async function currentRuntimeIdentity() {
|
|
|
9081
9141
|
async function runCurrentCliCommand(argv, cwd, streams) {
|
|
9082
9142
|
const entry = process.argv[1];
|
|
9083
9143
|
if (!entry) throw invalid4("\u65E0\u6CD5\u89E3\u6790\u5F53\u524D CLI entry");
|
|
9084
|
-
return new Promise((
|
|
9144
|
+
return new Promise((resolve4, reject) => {
|
|
9085
9145
|
const child = spawn(process.execPath, [entry, ...argv], {
|
|
9086
9146
|
cwd,
|
|
9087
9147
|
env: process.env,
|
|
@@ -9098,7 +9158,7 @@ async function runCurrentCliCommand(argv, cwd, streams) {
|
|
|
9098
9158
|
process.stderr.write(chunk);
|
|
9099
9159
|
});
|
|
9100
9160
|
child.once("error", reject);
|
|
9101
|
-
child.once("close", (code, signal) =>
|
|
9161
|
+
child.once("close", (code, signal) => resolve4({ exitCode: code ?? (signal ? 1 : 0) }));
|
|
9102
9162
|
});
|
|
9103
9163
|
}
|
|
9104
9164
|
async function writeReceiptExclusive(target, receipt) {
|
|
@@ -9112,13 +9172,13 @@ async function writeReceiptExclusive(target, receipt) {
|
|
|
9112
9172
|
});
|
|
9113
9173
|
await fs8.link(temp, target);
|
|
9114
9174
|
} catch (cause) {
|
|
9115
|
-
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);
|
|
9116
9176
|
} finally {
|
|
9117
9177
|
await fs8.unlink(temp).catch(() => void 0);
|
|
9118
9178
|
}
|
|
9119
9179
|
}
|
|
9120
9180
|
async function safeManagedDirectory(project, relative2, absolute) {
|
|
9121
|
-
await assertNoSymlinkComponents(project,
|
|
9181
|
+
await assertNoSymlinkComponents(project, path9.dirname(relative2));
|
|
9122
9182
|
const existing = await fs8.lstat(absolute).catch(() => void 0);
|
|
9123
9183
|
if (existing?.isSymbolicLink()) throw invalid4(`\u53D7\u7BA1\u76EE\u5F55\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
9124
9184
|
if (existing && !existing.isDirectory()) throw invalid4(`\u53D7\u7BA1\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${relative2}`);
|
|
@@ -9135,8 +9195,8 @@ async function pathExists(file) {
|
|
|
9135
9195
|
);
|
|
9136
9196
|
}
|
|
9137
9197
|
async function readSafeFile(project, file, label) {
|
|
9138
|
-
const relative2 =
|
|
9139
|
-
if (relative2.startsWith("../") ||
|
|
9198
|
+
const relative2 = path9.relative(project, file).split(path9.sep).join("/");
|
|
9199
|
+
if (relative2.startsWith("../") || path9.isAbsolute(relative2))
|
|
9140
9200
|
throw invalid4(`${label}\u8DEF\u5F84\u9003\u9038\u9879\u76EE`);
|
|
9141
9201
|
await assertNoSymlinkComponents(project, relative2);
|
|
9142
9202
|
let stat;
|
|
@@ -9153,14 +9213,14 @@ async function assertNoSymlinkComponents(project, relative2) {
|
|
|
9153
9213
|
const parts = relative2.split("/").filter(Boolean);
|
|
9154
9214
|
let current = project;
|
|
9155
9215
|
for (const part of parts) {
|
|
9156
|
-
current =
|
|
9216
|
+
current = path9.join(current, part);
|
|
9157
9217
|
const stat = await fs8.lstat(current).catch(() => void 0);
|
|
9158
9218
|
if (stat?.isSymbolicLink()) throw invalid4(`\u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\uFF1A${relative2}`);
|
|
9159
9219
|
if (!stat) break;
|
|
9160
9220
|
}
|
|
9161
9221
|
}
|
|
9162
9222
|
async function realProject(requested) {
|
|
9163
|
-
const absolute =
|
|
9223
|
+
const absolute = path9.resolve(requested);
|
|
9164
9224
|
let project;
|
|
9165
9225
|
try {
|
|
9166
9226
|
project = await fs8.realpath(absolute);
|
|
@@ -9172,10 +9232,10 @@ async function realProject(requested) {
|
|
|
9172
9232
|
return project;
|
|
9173
9233
|
}
|
|
9174
9234
|
function safeRelative(reference, label) {
|
|
9175
|
-
if (!reference ||
|
|
9235
|
+
if (!reference || path9.isAbsolute(reference) || /[\r\n\0]/.test(reference)) {
|
|
9176
9236
|
throw invalid4(`${label}\u5FC5\u987B\u662F\u9879\u76EE\u5185\u76F8\u5BF9\u8DEF\u5F84`);
|
|
9177
9237
|
}
|
|
9178
|
-
const normalized =
|
|
9238
|
+
const normalized = path9.normalize(reference).split(path9.sep).join("/");
|
|
9179
9239
|
if (normalized === ".." || normalized.startsWith("../") || normalized === ".") {
|
|
9180
9240
|
throw invalid4(`${label}\u8DEF\u5F84\u9003\u9038\u9879\u76EE`);
|
|
9181
9241
|
}
|
|
@@ -9216,11 +9276,11 @@ function sha2567(value) {
|
|
|
9216
9276
|
}
|
|
9217
9277
|
async function sha256File2(file) {
|
|
9218
9278
|
const hash = createHash7("sha256");
|
|
9219
|
-
await new Promise((
|
|
9279
|
+
await new Promise((resolve4, reject) => {
|
|
9220
9280
|
const stream = createReadStream2(file);
|
|
9221
9281
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
9222
9282
|
stream.on("error", reject);
|
|
9223
|
-
stream.on("end",
|
|
9283
|
+
stream.on("end", resolve4);
|
|
9224
9284
|
});
|
|
9225
9285
|
return hash.digest("hex");
|
|
9226
9286
|
}
|
|
@@ -9234,7 +9294,7 @@ init_exit();
|
|
|
9234
9294
|
import {
|
|
9235
9295
|
HcmClient as HcmClient20,
|
|
9236
9296
|
adminResetPassword,
|
|
9237
|
-
formatObject as
|
|
9297
|
+
formatObject as formatObject23,
|
|
9238
9298
|
fromAxiosError as fromAxiosError19,
|
|
9239
9299
|
CliError as CliError23,
|
|
9240
9300
|
CliErrorCode as CliErrorCode22
|
|
@@ -9268,7 +9328,7 @@ async function userResetPasswordCommand(args) {
|
|
|
9268
9328
|
const request = buildAdminResetPasswordRequest(args, password);
|
|
9269
9329
|
const client3 = HcmClient20.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
9270
9330
|
const result2 = await adminResetPassword(client3.raw(), request);
|
|
9271
|
-
process.stdout.write(
|
|
9331
|
+
process.stdout.write(formatObject23(result2, { format: args.output ?? "json" }) + "\n");
|
|
9272
9332
|
} catch (cause) {
|
|
9273
9333
|
const err = cause;
|
|
9274
9334
|
if (err?.isAxiosError) exitWithError(fromAxiosError19(err, args.env));
|
|
@@ -9336,6 +9396,12 @@ recon.command("round").description("\u96F6\u7F51\u7EDC\uFF1A\u8BFB\u4E00\u4EFD\u
|
|
|
9336
9396
|
output: cmd.parent?.opts()?.output
|
|
9337
9397
|
})
|
|
9338
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));
|
|
9339
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));
|
|
9340
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));
|
|
9341
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(
|