@kungfu-tech/buildchain 2.10.4 → 2.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/bin/buildchain.mjs +299 -16
- package/dist/site/buildchain-contract.json +7 -7
- package/dist/site/buildchain-site.json +42 -37
- package/dist/site/capability-registry.json +2 -2
- package/dist/site/cli-registry.json +164 -8
- package/dist/site/kfd-claims.json +190 -19
- package/dist/site/manual-registry.json +10 -10
- package/dist/site/node-api-registry.json +24 -11
- package/dist/site/page-registry.json +27 -22
- package/dist/site/public-surface-audit.json +334 -126
- package/dist/site/release-provenance.json +2 -1
- package/dist/site/site-manifest.json +14 -14
- package/dist/site/workflow-registry.json +4 -1
- package/docs/MAP.md +2 -2
- package/docs/cli.md +48 -14
- package/docs/install.md +1 -1
- package/docs/kfd-support.md +80 -21
- package/docs/lifecycle-protocol.md +7 -2
- package/docs/publish-transaction.md +1 -1
- package/docs/readme-badges.md +2 -2
- package/docs/release-passport.md +1 -1
- package/docs/reusable-build-surface.md +7 -7
- package/docs/web-surface-deployments.md +33 -4
- package/package.json +3 -2
- package/packages/core/buildchain-config.js +10 -5
- package/packages/core/buildchain-layout.js +157 -0
- package/packages/core/index.js +34 -0
- package/packages/core/kfd.js +273 -0
- package/packages/core/kfd3-surface-register.js +25 -17
- package/packages/core/public-surface-audit.js +14 -7
- package/scripts/buildchain-contract-lock.mjs +6 -2
- package/scripts/check-inventory.mjs +5 -4
- package/scripts/generate-site-bundle.mjs +20 -3
- package/scripts/init-repo.mjs +2 -1
- package/scripts/web-surface-production-release-pr.mjs +209 -36
- package/scripts/web-surface-release-pr-review.mjs +2 -1
package/README.md
CHANGED
|
@@ -171,10 +171,25 @@ npx @kungfu-tech/buildchain validate --require-version-state
|
|
|
171
171
|
npx @kungfu-tech/buildchain release --dry-run --target-ref alpha/v2/v2.2
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
-
Buildchain supports package and non-package projects through
|
|
174
|
+
Buildchain supports package and non-package projects through
|
|
175
|
+
`.buildchain/buildchain.toml`. Legacy root `buildchain.toml` files remain
|
|
176
|
+
readable, but new consumers should keep Buildchain-owned files under
|
|
177
|
+
`.buildchain/`:
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
.buildchain/buildchain.toml
|
|
181
|
+
.buildchain/contract-lock.json
|
|
182
|
+
.buildchain/kfd/kfd-3-surfaces.json
|
|
183
|
+
.buildchain/release-passport/buildchain.release.json
|
|
184
|
+
```
|
|
185
|
+
|
|
175
186
|
Lifecycle commands can call pnpm, npm, yarn, pip, Conan, CMake, Make, custom
|
|
176
187
|
scripts, or any other command that can run in the repository checkout.
|
|
177
188
|
|
|
189
|
+
The KFD entrypoint is `buildchain kfd`. Buildchain currently provides concrete
|
|
190
|
+
KFD-1 contract-world, KFD-2 trust-claim, and KFD-3 collaboration-surface
|
|
191
|
+
workflows; KFD-4 is exposed as schema-only until a verification protocol exists.
|
|
192
|
+
|
|
178
193
|
Buildchain's active GitHub Action surface is deliberately small:
|
|
179
194
|
|
|
180
195
|
- `actions/validate-config`
|
package/bin/buildchain.mjs
CHANGED
|
@@ -64,6 +64,15 @@ import {
|
|
|
64
64
|
writeBuildFacts,
|
|
65
65
|
writeKungfuBuildInfoProjection,
|
|
66
66
|
} from "../packages/core/build-facts.js";
|
|
67
|
+
import {
|
|
68
|
+
collectKfdStatus,
|
|
69
|
+
kfd1,
|
|
70
|
+
kfd2,
|
|
71
|
+
layout as buildchainLayout,
|
|
72
|
+
listKfdSchemas,
|
|
73
|
+
normalizeKfdStandardId,
|
|
74
|
+
readKfdSchema,
|
|
75
|
+
} from "../packages/core/kfd.js";
|
|
67
76
|
import {
|
|
68
77
|
auditKfd3Surfaces,
|
|
69
78
|
createKfd3SurfaceWitness,
|
|
@@ -147,15 +156,30 @@ function usage() {
|
|
|
147
156
|
[--module-fact <file>]... [--artifact <path>]...
|
|
148
157
|
[--output <file>] [--json]
|
|
149
158
|
buildchain facts verify [--cwd <dir>] --fact <file> [--json]
|
|
150
|
-
buildchain kfd
|
|
151
|
-
buildchain kfd
|
|
159
|
+
buildchain kfd ...
|
|
160
|
+
buildchain kfd status [--cwd <dir>] [--json]
|
|
161
|
+
buildchain kfd migrate-layout [--cwd <dir>] [--write] [--force] [--json]
|
|
162
|
+
buildchain kfd schema list [--standard kfd-1|kfd-2|kfd-3|kfd-4] [--json]
|
|
163
|
+
buildchain kfd schema show <kfd-1|kfd-2|kfd-3|kfd-4> [--schema <name>] [--json]
|
|
164
|
+
buildchain kfd 1 schema [--schema <name>] [--json]
|
|
165
|
+
buildchain kfd 1 witness [--cwd <dir>] [--source-sha <sha>] [--output <file>] [--json]
|
|
166
|
+
buildchain kfd 1 gate --witness-json <file-or-json>... [--cwd <dir>] [--artifact-root <dir>]
|
|
167
|
+
[--output <file>] [--json]
|
|
168
|
+
buildchain kfd 1 verify --gate-json <file-or-json> [--json]
|
|
169
|
+
buildchain kfd 2 schema [--schema <name>] [--json]
|
|
170
|
+
buildchain kfd 2 taxonomy --entry-json <file-or-json>... [--kind residualRisk|downgradeReason] [--json]
|
|
171
|
+
buildchain kfd 2 claims [--cwd <dir>] [--output-dir <dir>] [--json]
|
|
172
|
+
buildchain kfd 3 ...
|
|
173
|
+
buildchain kfd 3 detect [--cwd <dir>] [--kind <kind>]... [--artifact <path>] [--json]
|
|
174
|
+
buildchain kfd 3 register <node-api|python-api|cli|binary|documentation|site-bundle>
|
|
152
175
|
[--cwd <dir>] [--registry <path>] [--artifact <path>]
|
|
153
176
|
[--product <name>] [--json]
|
|
154
|
-
buildchain kfd
|
|
155
|
-
buildchain kfd
|
|
177
|
+
buildchain kfd 3 audit [--cwd <dir>] [--registry <path>] [--artifact <path>] [--json]
|
|
178
|
+
buildchain kfd 3 witness [--cwd <dir>] [--registry <path>] [--kind prebuild|artifact]
|
|
156
179
|
[--source-sha <sha>] [--artifact <path>] [--output <file>] [--json]
|
|
157
|
-
buildchain kfd
|
|
180
|
+
buildchain kfd 3 query [<product>] [--cwd <dir>] [--registry <path>]
|
|
158
181
|
[--passport <file-or-url>] [--artifact <path>] [--json]
|
|
182
|
+
buildchain kfd 4 schema [--schema <name>] [--json]
|
|
159
183
|
buildchain sample process-tree [--interval-ms <n>] [--label <name>]
|
|
160
184
|
[--output <jsonl>] [--summary-output <json>]
|
|
161
185
|
[--requested-parallelism <n>] [--json]
|
|
@@ -195,7 +219,11 @@ Examples:
|
|
|
195
219
|
buildchain infra-contract --mode propagation-apply --propagation-plan <plan.json> --dry-run true
|
|
196
220
|
buildchain infra-contract --mode evidence-bundle --artifact <artifact.json> --propagation-result <result.json>
|
|
197
221
|
buildchain release-propagation plan --graph graph.json --upstream-release release.json --json
|
|
198
|
-
buildchain kfd
|
|
222
|
+
buildchain kfd status --json
|
|
223
|
+
buildchain kfd schema list --json
|
|
224
|
+
buildchain kfd 1 witness --json
|
|
225
|
+
buildchain kfd 2 claims --json
|
|
226
|
+
buildchain kfd 3 query buildchain --json
|
|
199
227
|
`;
|
|
200
228
|
}
|
|
201
229
|
|
|
@@ -335,6 +363,25 @@ function writeJsonFile(filePath, value) {
|
|
|
335
363
|
return filePath;
|
|
336
364
|
}
|
|
337
365
|
|
|
366
|
+
function readJsonInput(value, { cwd = process.cwd(), label = "json" } = {}) {
|
|
367
|
+
const input = String(value || "").trim();
|
|
368
|
+
if (!input) {
|
|
369
|
+
throw new Error(`${label} is required`);
|
|
370
|
+
}
|
|
371
|
+
const filePath = path.isAbsolute(input) ? input : path.join(cwd, input);
|
|
372
|
+
if (fs.existsSync(filePath)) {
|
|
373
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
374
|
+
}
|
|
375
|
+
return JSON.parse(input);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function readRepeatedJsonInputs(args, name, { cwd = process.cwd(), label = name } = {}) {
|
|
379
|
+
return readRepeatedFlag(args, name).map((value, index) => readJsonInput(value, {
|
|
380
|
+
cwd,
|
|
381
|
+
label: `${label}[${index}]`,
|
|
382
|
+
}));
|
|
383
|
+
}
|
|
384
|
+
|
|
338
385
|
async function runReadmeBadgesCli(args = []) {
|
|
339
386
|
const [subcommand = "", surface = "", ...badgeArgs] = args;
|
|
340
387
|
if (!["readme", "bundle"].includes(subcommand) || (surface && surface.startsWith("--") === false)) {
|
|
@@ -477,11 +524,11 @@ function kfd3Kinds(args = []) {
|
|
|
477
524
|
async function runKfd3Cli(args = []) {
|
|
478
525
|
const [subcommand = "", maybeKindOrProduct = "", ...rest] = args;
|
|
479
526
|
if (!["detect", "register", "audit", "witness", "query"].includes(subcommand)) {
|
|
480
|
-
throw new Error("usage: buildchain kfd
|
|
527
|
+
throw new Error("usage: buildchain kfd 3 <detect|register|audit|witness|query> ...");
|
|
481
528
|
}
|
|
482
529
|
const effectiveArgs = maybeKindOrProduct && maybeKindOrProduct.startsWith("--") ? [maybeKindOrProduct, ...rest] : rest;
|
|
483
530
|
const cwd = path.resolve(readFlag(effectiveArgs, "cwd", process.cwd()));
|
|
484
|
-
const registryPath = readFlag(effectiveArgs, "registry", "
|
|
531
|
+
const registryPath = readFlag(effectiveArgs, "registry", "");
|
|
485
532
|
const artifactPath = readFlag(effectiveArgs, "artifact", "");
|
|
486
533
|
const json = readBooleanFlag(effectiveArgs, "json");
|
|
487
534
|
|
|
@@ -490,7 +537,7 @@ async function runKfd3Cli(args = []) {
|
|
|
490
537
|
if (json) {
|
|
491
538
|
printJson(result);
|
|
492
539
|
} else {
|
|
493
|
-
process.stdout.write(`kfd
|
|
540
|
+
process.stdout.write(`kfd 3 detect: ${result.summary.surfaceCount} surfaces\n`);
|
|
494
541
|
for (const entry of result.surfaces) {
|
|
495
542
|
process.stdout.write(`- ${entry.kind}: ${entry.id} (${entry.detectionMethod})\n`);
|
|
496
543
|
}
|
|
@@ -501,7 +548,7 @@ async function runKfd3Cli(args = []) {
|
|
|
501
548
|
if (subcommand === "register") {
|
|
502
549
|
const registerKind = maybeKindOrProduct && !maybeKindOrProduct.startsWith("--") ? maybeKindOrProduct : "";
|
|
503
550
|
if (!registerKind) {
|
|
504
|
-
throw new Error("usage: buildchain kfd
|
|
551
|
+
throw new Error("usage: buildchain kfd 3 register <node-api|python-api|cli|binary|documentation|site-bundle>");
|
|
505
552
|
}
|
|
506
553
|
const result = registerKfd3Surfaces({
|
|
507
554
|
cwd,
|
|
@@ -515,7 +562,7 @@ async function runKfd3Cli(args = []) {
|
|
|
515
562
|
if (json) {
|
|
516
563
|
printJson(result);
|
|
517
564
|
} else {
|
|
518
|
-
process.stdout.write(`kfd
|
|
565
|
+
process.stdout.write(`kfd 3 register: ${result.registeredCount} ${registerKind} surfaces -> ${registryPath}\n`);
|
|
519
566
|
}
|
|
520
567
|
return;
|
|
521
568
|
}
|
|
@@ -525,7 +572,7 @@ async function runKfd3Cli(args = []) {
|
|
|
525
572
|
if (json) {
|
|
526
573
|
printJson(report);
|
|
527
574
|
} else {
|
|
528
|
-
process.stdout.write(`kfd
|
|
575
|
+
process.stdout.write(`kfd 3 audit: ${report.status}\n`);
|
|
529
576
|
process.stdout.write(`detected=${report.summary.detected} declared=${report.summary.declared} enforced=${report.summary.enforced}\n`);
|
|
530
577
|
for (const issue of report.issues) {
|
|
531
578
|
process.stdout.write(`- ${issue.level}: ${issue.code}: ${issue.surfaceId}\n`);
|
|
@@ -552,7 +599,7 @@ async function runKfd3Cli(args = []) {
|
|
|
552
599
|
if (json || !output) {
|
|
553
600
|
printJson(witness);
|
|
554
601
|
} else {
|
|
555
|
-
process.stdout.write(`kfd
|
|
602
|
+
process.stdout.write(`kfd 3 witness: wrote ${output}\n`);
|
|
556
603
|
}
|
|
557
604
|
return;
|
|
558
605
|
}
|
|
@@ -568,7 +615,7 @@ async function runKfd3Cli(args = []) {
|
|
|
568
615
|
if (json) {
|
|
569
616
|
printJson(result);
|
|
570
617
|
} else {
|
|
571
|
-
process.stdout.write(`kfd
|
|
618
|
+
process.stdout.write(`kfd 3 query: ${result.product} (${result.status || result.kfd?.kfd3 || "unknown"})\n`);
|
|
572
619
|
process.stdout.write(`capabilities: ${result.capabilities?.length || 0}\n`);
|
|
573
620
|
for (const entry of result.capabilities || []) {
|
|
574
621
|
process.stdout.write(`- ${entry.kind}: ${entry.id} [${entry.state || "declared"}]\n`);
|
|
@@ -576,6 +623,242 @@ async function runKfd3Cli(args = []) {
|
|
|
576
623
|
}
|
|
577
624
|
}
|
|
578
625
|
|
|
626
|
+
function printKfdSchemaOrJson({ result, json }) {
|
|
627
|
+
if (json) {
|
|
628
|
+
printJson(result);
|
|
629
|
+
} else {
|
|
630
|
+
process.stdout.write(JSON.stringify(result.schema, null, 2));
|
|
631
|
+
process.stdout.write("\n");
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
function runKfd1Cli(args = []) {
|
|
636
|
+
const [rawAction = "schema", ...rest] = args;
|
|
637
|
+
const action = rawAction || "schema";
|
|
638
|
+
const cwd = path.resolve(readFlag(rest, "cwd", process.cwd()));
|
|
639
|
+
const json = readBooleanFlag(rest, "json");
|
|
640
|
+
if (action === "schema") {
|
|
641
|
+
printKfdSchemaOrJson({
|
|
642
|
+
result: readKfdSchema({ standard: "kfd-1", schema: readFlag(rest, "schema", "") }),
|
|
643
|
+
json,
|
|
644
|
+
});
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
if (action === "witness") {
|
|
648
|
+
const witness = kfd1.createBuildchainWitness({
|
|
649
|
+
root: cwd,
|
|
650
|
+
sourceSha: readFlag(rest, "source-sha", process.env.GITHUB_SHA || ""),
|
|
651
|
+
});
|
|
652
|
+
const output = readFlag(rest, "output", "");
|
|
653
|
+
if (output) {
|
|
654
|
+
writeJsonFile(path.resolve(cwd, output), witness);
|
|
655
|
+
}
|
|
656
|
+
if (json || !output) {
|
|
657
|
+
printJson(witness);
|
|
658
|
+
} else {
|
|
659
|
+
process.stdout.write(`kfd 1 witness: wrote ${output}\n`);
|
|
660
|
+
}
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
if (action === "gate") {
|
|
664
|
+
const witnesses = readRepeatedJsonInputs(rest, "witness-json", { cwd, label: "kfd-1 witness" });
|
|
665
|
+
if (witnesses.length === 0) {
|
|
666
|
+
throw new Error("buildchain kfd 1 gate requires at least one --witness-json");
|
|
667
|
+
}
|
|
668
|
+
const gate = kfd1.createReleaseGateEvidence({
|
|
669
|
+
cwd,
|
|
670
|
+
artifactRoot: readFlag(rest, "artifact-root", ""),
|
|
671
|
+
witnesses,
|
|
672
|
+
});
|
|
673
|
+
const output = readFlag(rest, "output", "");
|
|
674
|
+
if (output) {
|
|
675
|
+
writeJsonFile(path.resolve(cwd, output), gate);
|
|
676
|
+
}
|
|
677
|
+
if (json || !output) {
|
|
678
|
+
printJson(gate);
|
|
679
|
+
} else {
|
|
680
|
+
process.stdout.write(`kfd 1 gate: wrote ${output}\n`);
|
|
681
|
+
}
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
if (action === "verify") {
|
|
685
|
+
const gate = readJsonInput(readFlag(rest, "gate-json", ""), { cwd, label: "kfd-1 gate" });
|
|
686
|
+
const issues = kfd1.validateReleaseGateEvidence(gate);
|
|
687
|
+
const result = {
|
|
688
|
+
schemaVersion: 1,
|
|
689
|
+
contract: "kungfu-buildchain-kfd-1-verify-result",
|
|
690
|
+
ok: issues.length === 0,
|
|
691
|
+
issues,
|
|
692
|
+
};
|
|
693
|
+
if (json) {
|
|
694
|
+
printJson(result);
|
|
695
|
+
} else {
|
|
696
|
+
process.stdout.write(`kfd 1 verify: ${result.ok ? "ok" : "failed"}\n`);
|
|
697
|
+
for (const issue of issues) {
|
|
698
|
+
process.stdout.write(`- ${issue.level || "error"}: ${issue.code || "kfd-1"}: ${issue.message || issue}\n`);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
if (!result.ok) {
|
|
702
|
+
process.exitCode = 1;
|
|
703
|
+
}
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
throw new Error("usage: buildchain kfd 1 <schema|witness|gate|verify> ...");
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
function runKfd2Cli(args = []) {
|
|
710
|
+
const [rawAction = "schema", ...rest] = args;
|
|
711
|
+
const action = rawAction || "schema";
|
|
712
|
+
const cwd = path.resolve(readFlag(rest, "cwd", process.cwd()));
|
|
713
|
+
const json = readBooleanFlag(rest, "json");
|
|
714
|
+
if (action === "schema") {
|
|
715
|
+
printKfdSchemaOrJson({
|
|
716
|
+
result: readKfdSchema({ standard: "kfd-2", schema: readFlag(rest, "schema", "") }),
|
|
717
|
+
json,
|
|
718
|
+
});
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
if (action === "taxonomy") {
|
|
722
|
+
const kind = readFlag(rest, "kind", "residualRisk");
|
|
723
|
+
const entries = readRepeatedJsonInputs(rest, "entry-json", { cwd, label: "kfd-2 taxonomy entry" });
|
|
724
|
+
const result = {
|
|
725
|
+
schemaVersion: 1,
|
|
726
|
+
contract: "kungfu-buildchain-kfd-2-taxonomy-validation",
|
|
727
|
+
ok: true,
|
|
728
|
+
kind,
|
|
729
|
+
entries: kfd2.validateTaxonomyEntries({ entries, kind }),
|
|
730
|
+
};
|
|
731
|
+
if (json) {
|
|
732
|
+
printJson(result);
|
|
733
|
+
} else {
|
|
734
|
+
process.stdout.write(`kfd 2 taxonomy: ${result.entries.length} ${kind} entries ok\n`);
|
|
735
|
+
}
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
if (action === "claims") {
|
|
739
|
+
const claims = kfd2.createBuildchainClaims({ root: cwd });
|
|
740
|
+
const outputDir = readFlag(rest, "output-dir", "");
|
|
741
|
+
if (outputDir) {
|
|
742
|
+
for (const claim of claims) {
|
|
743
|
+
const slug = String(claim.id || "claim").replace(/[^a-z0-9._-]+/gi, "-");
|
|
744
|
+
writeJsonFile(path.resolve(cwd, outputDir, `${slug}.json`), claim);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
const result = {
|
|
748
|
+
schemaVersion: 1,
|
|
749
|
+
contract: "kungfu-buildchain-kfd-2-claims",
|
|
750
|
+
count: claims.length,
|
|
751
|
+
claims,
|
|
752
|
+
};
|
|
753
|
+
if (json || !outputDir) {
|
|
754
|
+
printJson(result);
|
|
755
|
+
} else {
|
|
756
|
+
process.stdout.write(`kfd 2 claims: wrote ${claims.length} claims to ${outputDir}\n`);
|
|
757
|
+
}
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
throw new Error("usage: buildchain kfd 2 <schema|taxonomy|claims> ...");
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
async function runKfdCli(args = []) {
|
|
764
|
+
const [subcommand = "", maybeStandardOrAction = "", ...rest] = args;
|
|
765
|
+
if (!subcommand) {
|
|
766
|
+
throw new Error("usage: buildchain kfd <status|migrate-layout|schema|1|2|3|4> ...");
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (subcommand === "status") {
|
|
770
|
+
const effectiveArgs = maybeStandardOrAction && maybeStandardOrAction.startsWith("--") ? [maybeStandardOrAction, ...rest] : rest;
|
|
771
|
+
const cwd = path.resolve(readFlag(effectiveArgs, "cwd", process.cwd()));
|
|
772
|
+
const result = collectKfdStatus({ cwd });
|
|
773
|
+
if (readBooleanFlag(effectiveArgs, "json")) {
|
|
774
|
+
printJson(result);
|
|
775
|
+
} else {
|
|
776
|
+
process.stdout.write(`kfd status: layout=${result.layout.status}\n`);
|
|
777
|
+
for (const [standard, capabilities] of Object.entries(result.support)) {
|
|
778
|
+
process.stdout.write(`- ${standard}: ${capabilities.join(", ")}\n`);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (subcommand === "migrate-layout") {
|
|
785
|
+
const effectiveArgs = maybeStandardOrAction && maybeStandardOrAction.startsWith("--") ? [maybeStandardOrAction, ...rest] : rest;
|
|
786
|
+
const cwd = path.resolve(readFlag(effectiveArgs, "cwd", process.cwd()));
|
|
787
|
+
const result = buildchainLayout.migrate({
|
|
788
|
+
cwd,
|
|
789
|
+
write: readBooleanFlag(effectiveArgs, "write"),
|
|
790
|
+
force: readBooleanFlag(effectiveArgs, "force"),
|
|
791
|
+
});
|
|
792
|
+
if (readBooleanFlag(effectiveArgs, "json")) {
|
|
793
|
+
printJson(result);
|
|
794
|
+
} else {
|
|
795
|
+
process.stdout.write(`kfd migrate-layout: ${result.status}${result.write ? " (write)" : " (dry-run)"}\n`);
|
|
796
|
+
for (const move of result.moves) {
|
|
797
|
+
process.stdout.write(`- ${move.from} -> ${move.to}\n`);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if (subcommand === "schema") {
|
|
804
|
+
const [schemaCommand = "", maybeStandard = "", ...schemaRest] = [maybeStandardOrAction, ...rest];
|
|
805
|
+
const effectiveArgs = maybeStandard && maybeStandard.startsWith("--") ? [maybeStandard, ...schemaRest] : schemaRest;
|
|
806
|
+
const json = readBooleanFlag(effectiveArgs, "json");
|
|
807
|
+
if (schemaCommand === "list") {
|
|
808
|
+
const result = listKfdSchemas({ standard: readFlag(effectiveArgs, "standard", "") });
|
|
809
|
+
if (json) {
|
|
810
|
+
printJson(result);
|
|
811
|
+
} else {
|
|
812
|
+
process.stdout.write(`kfd schema list: ${result.schemas.length} schemas\n`);
|
|
813
|
+
for (const entry of result.schemas) {
|
|
814
|
+
process.stdout.write(`- ${entry.standard}:${entry.name} ${entry.schemaId || entry.schemaPath}\n`);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
if (schemaCommand === "show") {
|
|
820
|
+
const standard = maybeStandard && !maybeStandard.startsWith("--") ? maybeStandard : readFlag(effectiveArgs, "standard", "");
|
|
821
|
+
if (!standard) {
|
|
822
|
+
throw new Error("usage: buildchain kfd schema show <kfd-1|kfd-2|kfd-3|kfd-4> [--schema <name>]");
|
|
823
|
+
}
|
|
824
|
+
const result = readKfdSchema({ standard, schema: readFlag(effectiveArgs, "schema", "") });
|
|
825
|
+
if (json) {
|
|
826
|
+
printJson(result);
|
|
827
|
+
} else {
|
|
828
|
+
process.stdout.write(JSON.stringify(result.schema, null, 2));
|
|
829
|
+
process.stdout.write("\n");
|
|
830
|
+
}
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
throw new Error("usage: buildchain kfd schema <list|show> ...");
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
const standard = normalizeKfdStandardId(subcommand);
|
|
837
|
+
if (standard === "kfd-1") {
|
|
838
|
+
runKfd1Cli([maybeStandardOrAction, ...rest]);
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
if (standard === "kfd-2") {
|
|
842
|
+
runKfd2Cli([maybeStandardOrAction, ...rest]);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
if (standard === "kfd-3") {
|
|
846
|
+
await runKfd3Cli([maybeStandardOrAction, ...rest]);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (standard === "kfd-4") {
|
|
850
|
+
const action = maybeStandardOrAction || "schema";
|
|
851
|
+
if (action === "schema") {
|
|
852
|
+
const schemaArgs = rest;
|
|
853
|
+
const json = readBooleanFlag(schemaArgs, "json");
|
|
854
|
+
printKfdSchemaOrJson({ result: readKfdSchema({ standard, schema: readFlag(schemaArgs, "schema", "") }), json });
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
throw new Error("KFD-4 is currently schema-only in Buildchain; use: buildchain kfd 4 schema");
|
|
858
|
+
}
|
|
859
|
+
throw new Error("usage: buildchain kfd <status|migrate-layout|schema|1|2|3|4> ...");
|
|
860
|
+
}
|
|
861
|
+
|
|
579
862
|
async function runBuildFactsCli(args = []) {
|
|
580
863
|
const [subcommand = "", ...factArgs] = args;
|
|
581
864
|
const cwd = path.resolve(readFlag(factArgs, "cwd", process.cwd()));
|
|
@@ -940,8 +1223,8 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
940
1223
|
return;
|
|
941
1224
|
}
|
|
942
1225
|
|
|
943
|
-
if (command === "kfd
|
|
944
|
-
await
|
|
1226
|
+
if (command === "kfd") {
|
|
1227
|
+
await runKfdCli(args);
|
|
945
1228
|
return;
|
|
946
1229
|
}
|
|
947
1230
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"product": {
|
|
5
5
|
"name": "Buildchain",
|
|
6
6
|
"package": "@kungfu-tech/buildchain",
|
|
7
|
-
"version": "2.10.
|
|
7
|
+
"version": "2.10.5",
|
|
8
8
|
"repository": "https://github.com/kungfu-systems/buildchain"
|
|
9
9
|
},
|
|
10
10
|
"majorLine": "v2",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"GitHub Release passport and evidence publication is delegated to promote-buildchain-ref after the semver release transaction completes"
|
|
93
93
|
],
|
|
94
94
|
"breakingDigest": "sha256:403d2fcdb0c5eabe749e89102defad69745f70a1556707bec7831fcc2e9fa8f8",
|
|
95
|
-
"auditDigest": "sha256:
|
|
95
|
+
"auditDigest": "sha256:b3e96fe1d01793481dcf507373b7856a9b29451d168b18cd0f149517cb61ffde"
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
"contractVersion": 1,
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
"breaking contract drift fails closed before rendering, deployment, or release publication"
|
|
135
135
|
],
|
|
136
136
|
"breakingDigest": "sha256:82ee63cb336e40d832dfff4a1c5e6cbfa221a4fc8b2359990033bc931bffc43a",
|
|
137
|
-
"auditDigest": "sha256:
|
|
137
|
+
"auditDigest": "sha256:ae85fb8353b26d804f9856b971c9c77bd19bbbf6286f35e015284ebce31c818a"
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
"contractVersion": 1,
|
|
@@ -344,7 +344,7 @@
|
|
|
344
344
|
"README badge block checks and writes are generated from machine-readable repository facts"
|
|
345
345
|
],
|
|
346
346
|
"breakingDigest": "sha256:90a73892b2d6c214048448d5f45df75639bdf7b7e8fefd9c596e04b087407bcc",
|
|
347
|
-
"auditDigest": "sha256:
|
|
347
|
+
"auditDigest": "sha256:e7d8cea1254cd2a5acb2c217ae986cc349fd7117147a819fbc17d8dac7ed0755"
|
|
348
348
|
},
|
|
349
349
|
{
|
|
350
350
|
"contractVersion": 1,
|
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"manual entries carry source file digests so downstream sites and agents can detect stale hand-written documentation"
|
|
435
435
|
],
|
|
436
436
|
"breakingDigest": "sha256:7d0d2819e3a3e72989d9c57b5efe9d0bc0a79bc0f2c82a0c7b9d6c5a211a91f2",
|
|
437
|
-
"auditDigest": "sha256:
|
|
437
|
+
"auditDigest": "sha256:e6e30455ad08e8e979bea81065523e3082ca837470a979adc874bfa623740ef1"
|
|
438
438
|
},
|
|
439
439
|
{
|
|
440
440
|
"contractVersion": 1,
|
|
@@ -456,9 +456,9 @@
|
|
|
456
456
|
"agents can discover supported Node APIs without importing internal file paths"
|
|
457
457
|
],
|
|
458
458
|
"breakingDigest": "sha256:48f925608d3e2131d90936b07dc2a30341204cae3e6e785c0f77d61ad755c945",
|
|
459
|
-
"auditDigest": "sha256:
|
|
459
|
+
"auditDigest": "sha256:1d012a0a8f04a4c91abb0a6546103031584247fff028c4066e491ace8afab49d"
|
|
460
460
|
}
|
|
461
461
|
],
|
|
462
462
|
"compatibilityDigest": "sha256:967df7e854fdf582294ddfb6403eff25c00db9518a24051e7d47cbd75527c785",
|
|
463
|
-
"contractDigest": "sha256:
|
|
463
|
+
"contractDigest": "sha256:515f9d76f67aa18c607f96ecdd608cda561929ea3ae3c887609fe28d0f05c25f"
|
|
464
464
|
}
|