@kungfu-tech/buildchain 3.0.9-alpha.13 → 3.0.9-alpha.15
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/site/buildchain-contract.json +3 -3
- package/dist/site/buildchain-site.json +4 -4
- package/dist/site/kfd-claims.json +2 -2
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/public-surface-audit.json +1 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +4 -4
- package/dist/site/workflow-registry.json +4 -4
- package/package.json +1 -1
- package/scripts/audit-publication-control-plane.mjs +28 -27
- package/scripts/auditable-demo-platform.mjs +3 -3
- package/scripts/auditable-demo-renditions.mjs +11 -3
- package/scripts/auditable-demo.mjs +10 -4
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"product": {
|
|
5
5
|
"name": "Buildchain",
|
|
6
6
|
"package": "@kungfu-tech/buildchain",
|
|
7
|
-
"version": "3.0.9-alpha.
|
|
7
|
+
"version": "3.0.9-alpha.15",
|
|
8
8
|
"repository": "https://github.com/kungfu-systems/buildchain"
|
|
9
9
|
},
|
|
10
10
|
"majorLine": "v3",
|
|
@@ -684,7 +684,7 @@
|
|
|
684
684
|
"GitHub Release passport and evidence publication is delegated to promote-buildchain-ref after the semver release transaction completes"
|
|
685
685
|
],
|
|
686
686
|
"breakingDigest": "sha256:e60642aa298933d2c103284794921a6c340a50aa91ee528b06e58892a2a006bf",
|
|
687
|
-
"auditDigest": "sha256:
|
|
687
|
+
"auditDigest": "sha256:7cb902bedd4f7bdf03bd8b9736e43cb105661046e7bed78eccef367e6f7caece",
|
|
688
688
|
"compatibleBreakingDigests": [
|
|
689
689
|
"sha256:acd401cfc46450115a3763fd4b679d85f185e8757ebd52510d6262e1533df4cf"
|
|
690
690
|
],
|
|
@@ -4269,5 +4269,5 @@
|
|
|
4269
4269
|
],
|
|
4270
4270
|
"compatibilityProofRegistryRoot": "sha256:b7194b811e4d3af2df4390bc4d1731e16a86215bd64ee18cb630dd5492f4fb63",
|
|
4271
4271
|
"compatibilityDigest": "sha256:57d37609068590238f547a133b6b69ee994b452825030447d20529683ba61fbd",
|
|
4272
|
-
"contractDigest": "sha256:
|
|
4272
|
+
"contractDigest": "sha256:5952e1766dc136a4c405efc5f50d5227cacfe89c151d5a6287b1744c2a90a53c"
|
|
4273
4273
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-bundle",
|
|
4
|
-
"generatedAt": "2026-08-
|
|
5
|
-
"publishedAt": "2026-08-
|
|
4
|
+
"generatedAt": "2026-08-13T17:47:25.000Z",
|
|
5
|
+
"publishedAt": "2026-08-13T17:47:25.000Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "5e2d41bab6c50155bd407bd2d7558c174c44e66f",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"package": {
|
|
39
39
|
"name": "@kungfu-tech/buildchain",
|
|
40
|
-
"version": "3.0.9-alpha.
|
|
40
|
+
"version": "3.0.9-alpha.15",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"source": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"contract": "kungfu-buildchain-public-surface-reverse-audit",
|
|
22
22
|
"path": "dist/site/public-surface-audit.json",
|
|
23
23
|
"status": "passed",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "a9d60e93977fa6a58d83afa111f0941ea2768dfbf396bf716e7aead28afa819e",
|
|
25
25
|
"summary": {
|
|
26
26
|
"cliCommandCount": 114,
|
|
27
27
|
"workflowCount": 69,
|
|
@@ -246,7 +246,7 @@
|
|
|
246
246
|
"contract": "kungfu-buildchain-public-surface-reverse-audit",
|
|
247
247
|
"path": "dist/site/public-surface-audit.json",
|
|
248
248
|
"status": "passed",
|
|
249
|
-
"sha256": "
|
|
249
|
+
"sha256": "a9d60e93977fa6a58d83afa111f0941ea2768dfbf396bf716e7aead28afa819e",
|
|
250
250
|
"summary": {
|
|
251
251
|
"cliCommandCount": 114,
|
|
252
252
|
"workflowCount": 69,
|
|
@@ -8351,7 +8351,7 @@
|
|
|
8351
8351
|
"workflowRegistryPath": "dist/site/workflow-registry.json",
|
|
8352
8352
|
"pageRegistryPath": "dist/site/page-registry.json",
|
|
8353
8353
|
"cliRegistryDigest": "613ca42d3fe36e953603221d1cf16478ba84e6cf27dd6d11ddb2c1caea42ec3b",
|
|
8354
|
-
"workflowRegistryDigest": "
|
|
8354
|
+
"workflowRegistryDigest": "9c6353b322571a7cd66408dbb751ba53d0e286eabd5a0dfb829c9f2a8e248c8e",
|
|
8355
8355
|
"pageRegistryDigest": "278318ddd3f832a3681ff805eff19f9a1e3d7da382c62db10a8be663cdc99139"
|
|
8356
8356
|
},
|
|
8357
8357
|
"comparison": {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-publication-release-registry",
|
|
4
|
-
"generatedAt": "2026-08-
|
|
5
|
-
"publishedAt": "2026-08-
|
|
4
|
+
"generatedAt": "2026-08-13T17:47:25.000Z",
|
|
5
|
+
"publishedAt": "2026-08-13T17:47:25.000Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "5e2d41bab6c50155bd407bd2d7558c174c44e66f",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"package": {
|
|
34
34
|
"name": "@kungfu-tech/buildchain",
|
|
35
|
-
"version": "3.0.9-alpha.
|
|
35
|
+
"version": "3.0.9-alpha.15",
|
|
36
36
|
"versionSource": "package.json#version"
|
|
37
37
|
},
|
|
38
38
|
"sourceKind": "package-site-bundle",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-manifest",
|
|
4
|
-
"generatedAt": "2026-08-
|
|
5
|
-
"publishedAt": "2026-08-
|
|
4
|
+
"generatedAt": "2026-08-13T17:47:25.000Z",
|
|
5
|
+
"publishedAt": "2026-08-13T17:47:25.000Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "5e2d41bab6c50155bd407bd2d7558c174c44e66f",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"package": {
|
|
39
39
|
"name": "@kungfu-tech/buildchain",
|
|
40
|
-
"version": "3.0.9-alpha.
|
|
40
|
+
"version": "3.0.9-alpha.15",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"entrypoint": "buildchain-site.json",
|
|
@@ -1970,7 +1970,7 @@
|
|
|
1970
1970
|
"status": "preview",
|
|
1971
1971
|
"owner": "buildchain-workflows",
|
|
1972
1972
|
"maturity": "preview",
|
|
1973
|
-
"introducedVersion": "3.0.9-alpha.
|
|
1973
|
+
"introducedVersion": "3.0.9-alpha.15",
|
|
1974
1974
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
1975
1975
|
"deprecationReplacement": "",
|
|
1976
1976
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
@@ -1991,7 +1991,7 @@
|
|
|
1991
1991
|
"status": "preview",
|
|
1992
1992
|
"owner": "buildchain-workflows",
|
|
1993
1993
|
"maturity": "preview",
|
|
1994
|
-
"introducedVersion": "3.0.9-alpha.
|
|
1994
|
+
"introducedVersion": "3.0.9-alpha.15",
|
|
1995
1995
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
1996
1996
|
"deprecationReplacement": "",
|
|
1997
1997
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
@@ -2012,7 +2012,7 @@
|
|
|
2012
2012
|
"status": "preview",
|
|
2013
2013
|
"owner": "buildchain-workflows",
|
|
2014
2014
|
"maturity": "preview",
|
|
2015
|
-
"introducedVersion": "3.0.9-alpha.
|
|
2015
|
+
"introducedVersion": "3.0.9-alpha.15",
|
|
2016
2016
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
2017
2017
|
"deprecationReplacement": "",
|
|
2018
2018
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
@@ -2062,7 +2062,7 @@
|
|
|
2062
2062
|
"status": "preview",
|
|
2063
2063
|
"owner": "buildchain-workflows",
|
|
2064
2064
|
"maturity": "preview",
|
|
2065
|
-
"introducedVersion": "3.0.9-alpha.
|
|
2065
|
+
"introducedVersion": "3.0.9-alpha.15",
|
|
2066
2066
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
2067
2067
|
"deprecationReplacement": "",
|
|
2068
2068
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "3.0.9-alpha.
|
|
3
|
+
"version": "3.0.9-alpha.15",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Buildchain Release Passport, release governance, CLI toolkit, and site facts.",
|
|
6
6
|
"repository": "https://github.com/kungfu-systems/buildchain",
|
|
@@ -10,18 +10,12 @@ import {
|
|
|
10
10
|
} from "../packages/core/publication-control-plane-audit.js";
|
|
11
11
|
|
|
12
12
|
const GITHUB_JSON_MAX_BUFFER = 16 * 1024 * 1024;
|
|
13
|
+
const GITHUB_COMMAND_OPTIONS = Object.freeze({ encoding: "utf8", timeout: 60_000, maxBuffer: GITHUB_JSON_MAX_BUFFER });
|
|
13
14
|
|
|
14
|
-
function flag(name, fallback = "") {
|
|
15
|
-
const index = process.argv.indexOf(`--${name}`);
|
|
16
|
-
return index === -1 ? fallback : String(process.argv[index + 1] || "");
|
|
17
|
-
}
|
|
15
|
+
function flag(name, fallback = "") { const index = process.argv.indexOf(`--${name}`); return index === -1 ? fallback : String(process.argv[index + 1] || ""); }
|
|
18
16
|
|
|
19
17
|
function commandJson(command, args, label) {
|
|
20
|
-
const result = spawnSync(command, args,
|
|
21
|
-
encoding: "utf8",
|
|
22
|
-
timeout: 60_000,
|
|
23
|
-
maxBuffer: GITHUB_JSON_MAX_BUFFER,
|
|
24
|
-
});
|
|
18
|
+
const result = spawnSync(command, args, GITHUB_COMMAND_OPTIONS);
|
|
25
19
|
if (result.status !== 0) {
|
|
26
20
|
const category = /401|E401|unauthorized/i.test(result.stderr) ? "unauthorized" : "unavailable";
|
|
27
21
|
throw new Error(`${label} is ${category}; publication control-plane audit fails closed`);
|
|
@@ -33,16 +27,28 @@ function commandJson(command, args, label) {
|
|
|
33
27
|
}
|
|
34
28
|
}
|
|
35
29
|
|
|
36
|
-
function githubJson(apiPath, label) {
|
|
37
|
-
|
|
30
|
+
function githubJson(apiPath, label) { return commandJson("gh", ["api", apiPath, "-H", "Accept: application/vnd.github+json"], label); }
|
|
31
|
+
|
|
32
|
+
function exactWorkflowText({ repository, workflowPath, workflowRef }) {
|
|
33
|
+
const encodedWorkflow = workflowPath.split("/").map(encodeURIComponent).join("/");
|
|
34
|
+
try {
|
|
35
|
+
const workflowFile = githubJson(
|
|
36
|
+
`repos/${repository}/contents/${encodedWorkflow}${workflowRef ? `?ref=${encodeURIComponent(workflowRef)}` : ""}`,
|
|
37
|
+
"publication workflow source",
|
|
38
|
+
);
|
|
39
|
+
return Buffer.from(String(workflowFile.content || ""), "base64").toString("utf8");
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (!/^[0-9a-fA-F]{40}$/.test(workflowRef)) throw error;
|
|
42
|
+
const checkoutHead = spawnSync("git", ["rev-parse", "HEAD"], GITHUB_COMMAND_OPTIONS);
|
|
43
|
+
if (checkoutHead.status !== 0 || checkoutHead.stdout.trim().toLowerCase() !== workflowRef.toLowerCase()) throw error;
|
|
44
|
+
const localWorkflow = spawnSync("git", ["show", `${workflowRef}:${workflowPath}`], GITHUB_COMMAND_OPTIONS);
|
|
45
|
+
if (localWorkflow.status !== 0 || !localWorkflow.stdout) throw error;
|
|
46
|
+
return localWorkflow.stdout;
|
|
47
|
+
}
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
function githubJsonOptional(apiPath, label, fallback) {
|
|
41
|
-
const result = spawnSync("gh", ["api", apiPath, "-H", "Accept: application/vnd.github+json"],
|
|
42
|
-
encoding: "utf8",
|
|
43
|
-
timeout: 60_000,
|
|
44
|
-
maxBuffer: GITHUB_JSON_MAX_BUFFER,
|
|
45
|
-
});
|
|
51
|
+
const result = spawnSync("gh", ["api", apiPath, "-H", "Accept: application/vnd.github+json"], GITHUB_COMMAND_OPTIONS);
|
|
46
52
|
if (result.status !== 0) {
|
|
47
53
|
if (/404|not found/i.test(`${result.stdout}\n${result.stderr}`)) return fallback;
|
|
48
54
|
const category = /401|403|unauthorized|forbidden/i.test(`${result.stdout}\n${result.stderr}`) ? "unauthorized" : "unavailable";
|
|
@@ -56,11 +62,7 @@ function githubJsonOptional(apiPath, label, fallback) {
|
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
function githubJsonReadLimited(apiPath, label, fallback) {
|
|
59
|
-
const result = spawnSync("gh", ["api", apiPath, "-H", "Accept: application/vnd.github+json"],
|
|
60
|
-
encoding: "utf8",
|
|
61
|
-
timeout: 60_000,
|
|
62
|
-
maxBuffer: GITHUB_JSON_MAX_BUFFER,
|
|
63
|
-
});
|
|
65
|
+
const result = spawnSync("gh", ["api", apiPath, "-H", "Accept: application/vnd.github+json"], GITHUB_COMMAND_OPTIONS);
|
|
64
66
|
if (result.status !== 0) {
|
|
65
67
|
if (/401|403|404|unauthorized|forbidden|not found/i.test(`${result.stdout}\n${result.stderr}`)) return fallback;
|
|
66
68
|
throw new Error(`${label} is unavailable; publication control-plane audit fails closed`);
|
|
@@ -217,12 +219,11 @@ function main() {
|
|
|
217
219
|
const allowReleaseReconciliation = process.argv.includes("--allow-release-reconciliation");
|
|
218
220
|
if (!repository || !branch) throw new Error("--repository and --branch are required");
|
|
219
221
|
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
);
|
|
225
|
-
const workflowText = Buffer.from(String(workflowFile.content || ""), "base64").toString("utf8");
|
|
222
|
+
const workflowText = exactWorkflowText({
|
|
223
|
+
repository: workflowRepository,
|
|
224
|
+
workflowPath,
|
|
225
|
+
workflowRef,
|
|
226
|
+
});
|
|
226
227
|
const block = jobBlock(workflowText, jobId);
|
|
227
228
|
if (!block) throw new Error(`publication workflow job is missing: ${workflowPath}#${jobId}`);
|
|
228
229
|
const jobsOffset = workflowText.search(/^jobs:\s*$/m);
|
|
@@ -7,7 +7,7 @@ import path from "node:path";
|
|
|
7
7
|
import { pathToFileURL } from "node:url";
|
|
8
8
|
import { materializeDemoPresentation, validateDemoPresentation } from "./auditable-demo-presentation.mjs";
|
|
9
9
|
import { copyVerifiedRegular, verifyBundleChecksums } from "./auditable-demo-bundle-verification.mjs";
|
|
10
|
-
|
|
10
|
+
import { boundedLongFormFps, LONG_FORM_MAX_DURATION_MS } from "./auditable-demo-renditions.mjs";
|
|
11
11
|
const DIGEST = /^sha256:[0-9a-f]{64}$/u;
|
|
12
12
|
const SAFE_ID = /^[a-z0-9][a-z0-9._-]{0,63}$/u;
|
|
13
13
|
const SAFE_MARKER = /^[a-z0-9][a-z0-9._:-]{0,79}$/u;
|
|
@@ -26,7 +26,7 @@ const RENDITIONS = [
|
|
|
26
26
|
{ id: "720p", role: "responsive", columns: 150, rows: 28, width: 1280, height: 720 },
|
|
27
27
|
];
|
|
28
28
|
const STANDARD_MAX_SECONDS = 60;
|
|
29
|
-
const LONG_FORM_MAX_SECONDS =
|
|
29
|
+
const LONG_FORM_MAX_SECONDS = LONG_FORM_MAX_DURATION_MS / 1000;
|
|
30
30
|
const PRESENTATION_FRAMED = "presentation-framed";
|
|
31
31
|
const TERMINAL_FILL = "terminal-fill";
|
|
32
32
|
const MAX_EXECUTABLE_FILES = 32;
|
|
@@ -305,7 +305,7 @@ function projection(capture, transcript, demo, rendition, durationClass, sharedC
|
|
|
305
305
|
id: `${demo.id}-${rendition.id}`.slice(0, 64),
|
|
306
306
|
width: rendition.width,
|
|
307
307
|
height: rendition.height,
|
|
308
|
-
fps: policy.durationClass === "long-form" ?
|
|
308
|
+
fps: policy.durationClass === "long-form" ? boundedLongFormFps(durationMs) : 15,
|
|
309
309
|
...(policy.durationClass === "long-form" ? { durationClass: "long-form" } : {}),
|
|
310
310
|
compositionMode,
|
|
311
311
|
durationMs,
|
|
@@ -18,10 +18,17 @@ const RENDITION_SET_NON_AUTHORITIES = [
|
|
|
18
18
|
];
|
|
19
19
|
const MAX_BUNDLE_MEMBER_BYTES = 8 * 1024 * 1024;
|
|
20
20
|
export const MAX_LONG_FORM_RENDERER_MANIFEST_BYTES = 64 * 1024 * 1024;
|
|
21
|
+
export const LONG_FORM_MAX_DURATION_MS = 360_000;
|
|
22
|
+
export const LONG_FORM_MAX_FPS = 10;
|
|
23
|
+
export const MAX_RENDER_FRAMES = 1_800;
|
|
21
24
|
const PRESENTATION_FRAMED = "presentation-framed";
|
|
22
25
|
const TERMINAL_FILL = "terminal-fill";
|
|
23
26
|
const GEOMETRY_TOLERANCE = 0.001;
|
|
24
27
|
|
|
28
|
+
export function boundedLongFormFps(durationMs) {
|
|
29
|
+
return Math.max(1, Math.min(LONG_FORM_MAX_FPS, Math.floor((MAX_RENDER_FRAMES * 1000) / durationMs)));
|
|
30
|
+
}
|
|
31
|
+
|
|
25
32
|
function closeEnough(left, right, tolerance = GEOMETRY_TOLERANCE) {
|
|
26
33
|
return Number.isFinite(left) && Number.isFinite(right) && Math.abs(left - right) <= tolerance;
|
|
27
34
|
}
|
|
@@ -238,10 +245,11 @@ function validateLongFormManifestRendition(entry, declaration, index, helpers) {
|
|
|
238
245
|
&& scene?.height === declaration.height
|
|
239
246
|
&& Number.isInteger(scene?.durationMs)
|
|
240
247
|
&& scene.durationMs >= 500
|
|
241
|
-
&& scene.durationMs <=
|
|
248
|
+
&& scene.durationMs <= LONG_FORM_MAX_DURATION_MS
|
|
242
249
|
&& Number.isInteger(scene?.fps)
|
|
243
250
|
&& scene.fps >= 1
|
|
244
|
-
&& scene.fps <=
|
|
251
|
+
&& scene.fps <= LONG_FORM_MAX_FPS
|
|
252
|
+
&& Math.ceil((scene.durationMs / 1000) * scene.fps) <= MAX_RENDER_FRAMES
|
|
245
253
|
&& capture?.schema === "kungfu.terminal-capture/v1"
|
|
246
254
|
&& digestPattern.test(capture?.root)
|
|
247
255
|
&& Number.isInteger(capture?.durationMs)
|
|
@@ -293,7 +301,7 @@ export function validateTerminalCapture(value, scene, helpers) {
|
|
|
293
301
|
exactKeys(value.dimensions, ["columns", "rows"], [], "terminalCapture.dimensions");
|
|
294
302
|
integer(value.dimensions.columns, 80, 200, "terminalCapture.dimensions.columns");
|
|
295
303
|
integer(value.dimensions.rows, 24, 80, "terminalCapture.dimensions.rows");
|
|
296
|
-
const maximumDurationMs = scene.durationClass === "long-form" ?
|
|
304
|
+
const maximumDurationMs = scene.durationClass === "long-form" ? LONG_FORM_MAX_DURATION_MS : 60000;
|
|
297
305
|
const durationMs = integer(value.durationMs, 500, maximumDurationMs, "terminalCapture.durationMs");
|
|
298
306
|
invariant(
|
|
299
307
|
durationMs <= scene.durationMs && scene.durationMs - durationMs <= 2000,
|
|
@@ -7,7 +7,16 @@ import os from "node:os";
|
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { spawnSync } from "node:child_process";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
LONG_FORM_MAX_DURATION_MS,
|
|
12
|
+
LONG_FORM_MAX_FPS,
|
|
13
|
+
MAX_LONG_FORM_RENDERER_MANIFEST_BYTES,
|
|
14
|
+
MAX_RENDER_FRAMES,
|
|
15
|
+
readRendererManifest,
|
|
16
|
+
validateRendererCompositionInputs,
|
|
17
|
+
validateRenditionSet,
|
|
18
|
+
validateTerminalCapture,
|
|
19
|
+
} from "./auditable-demo-renditions.mjs";
|
|
11
20
|
|
|
12
21
|
const UTF8 = new TextDecoder("utf-8", { fatal: true });
|
|
13
22
|
const IMAGE_PATTERN = /^[a-z0-9][a-z0-9./_-]*@sha256:[0-9a-f]{64}$/;
|
|
@@ -34,9 +43,6 @@ const OPTIONAL_ADAPTER_FILES = [
|
|
|
34
43
|
const MAX_TERMINAL_CAPTURE_BYTES = 4 * 1024 * 1024;
|
|
35
44
|
const MAX_TERMINAL_CAPTURE_EVENTS = 10_000;
|
|
36
45
|
const STANDARD_MAX_DURATION_MS = 60_000;
|
|
37
|
-
const LONG_FORM_MAX_DURATION_MS = 180_000;
|
|
38
|
-
const LONG_FORM_MAX_FPS = 10;
|
|
39
|
-
const MAX_RENDER_FRAMES = 1_800;
|
|
40
46
|
|
|
41
47
|
function invariant(condition, message) {
|
|
42
48
|
if (!condition) throw new Error(message);
|