zyrk 0.8.1 → 0.8.3
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 +10 -1
- package/VERSION +1 -1
- package/dist/cli/build-approval.d.ts +4 -0
- package/dist/cli/build-approval.d.ts.map +1 -0
- package/dist/cli/build-approval.js +31 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +11 -15
- package/dist/cli/progress.d.ts +1 -0
- package/dist/cli/progress.d.ts.map +1 -1
- package/dist/cli/progress.js +41 -5
- package/dist/install/private.d.ts +7 -2
- package/dist/install/private.d.ts.map +1 -1
- package/dist/install/private.js +33 -13
- package/dist/install/run.d.ts +1 -0
- package/dist/install/run.d.ts.map +1 -1
- package/dist/install/run.js +17 -5
- package/dist/install/workspace-install.d.ts.map +1 -1
- package/dist/install/workspace-install.js +17 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -131,6 +131,11 @@ zyrk install
|
|
|
131
131
|
zyrk rebuild --offline # rebuild the complete approved locked graph
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
+
The review labels every exact source as `PENDING`, `APPROVED`, or `DENIED`,
|
|
135
|
+
shows its lifecycle commands, and names the policy scope that made the decision.
|
|
136
|
+
Review mode never runs package code. A mandatory deny cannot be selected and
|
|
137
|
+
does not prevent a separate permitted source from being approved.
|
|
138
|
+
|
|
134
139
|
Approvals are local to the exact graph, sources, patch contents, and script
|
|
135
140
|
policy. Interactive selections are written to the checked-in
|
|
136
141
|
`zyrk-workspace.json` file with exact package source identities, so collaborators
|
|
@@ -476,7 +481,11 @@ linking on stderr. Interactive terminals show the stages as a calm, multi-line
|
|
|
476
481
|
sequence, followed by a success footer; package downloads show received bytes,
|
|
477
482
|
and a checkmark lists each unique package/version linked after the project
|
|
478
483
|
transaction commits. Both `zyrk add prettier` and `zyrk install prettier` show
|
|
479
|
-
these details. Redirected output uses plain progress messages
|
|
484
|
+
these details. Redirected output uses plain progress messages, with frequent
|
|
485
|
+
source and download updates limited to once per second. Stage changes and
|
|
486
|
+
completion flush the latest counts, including when an install fails.
|
|
487
|
+
Intentionally unbuilt installs use an attention footer and state which review
|
|
488
|
+
action is needed. Source counters
|
|
480
489
|
distinguish verified reuse from newly downloaded sources. Source counts differ
|
|
481
490
|
from dependency contexts when peers split a package. `--json` disables progress.
|
|
482
491
|
Other native commands use the same terminal language: successful summaries get
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v0.8.
|
|
1
|
+
v0.8.3
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BuildReview } from "../install/private.ts";
|
|
2
|
+
/** Human review text only. It never executes package code or changes policy. */
|
|
3
|
+
export declare function renderBuildReviews(reviews: readonly BuildReview[]): string;
|
|
4
|
+
//# sourceMappingURL=build-approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-approval.d.ts","sourceRoot":"","sources":["../../src/cli/build-approval.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAsBzD,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAW1E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { redactSecrets } from "../log.js";
|
|
2
|
+
const decisionLabel = {
|
|
3
|
+
approved: "APPROVED",
|
|
4
|
+
denied: "DENIED",
|
|
5
|
+
pending: "PENDING",
|
|
6
|
+
};
|
|
7
|
+
const scopeLabel = {
|
|
8
|
+
"user-deny": "mandatory user policy",
|
|
9
|
+
"project-deny": "project deny policy",
|
|
10
|
+
"project-policy": "project script policy",
|
|
11
|
+
"workspace-policy": "zyrk-workspace.json",
|
|
12
|
+
"local-session": "current graph approval",
|
|
13
|
+
none: "no approval recorded",
|
|
14
|
+
};
|
|
15
|
+
function safe(value) {
|
|
16
|
+
return redactSecrets(value).replace(/[\x00-\x1f\x7f-\x9f]/g, " ");
|
|
17
|
+
}
|
|
18
|
+
/** Human review text only. It never executes package code or changes policy. */
|
|
19
|
+
export function renderBuildReviews(reviews) {
|
|
20
|
+
if (!reviews.length)
|
|
21
|
+
return "No dependency builds require approval.\n";
|
|
22
|
+
const entries = reviews
|
|
23
|
+
.map((review) => {
|
|
24
|
+
const stages = review.stages
|
|
25
|
+
.map((stage) => ` ${safe(stage.name)}: ${safe(stage.command)}`)
|
|
26
|
+
.join("\n");
|
|
27
|
+
return `${decisionLabel[review.decision]} ${safe(review.name)}@${safe(review.version)}\n source: ${safe(review.sourceId)}\n policy: ${scopeLabel[review.policyScope]}\n lifecycle:\n${stages}`;
|
|
28
|
+
})
|
|
29
|
+
.join("\n\n");
|
|
30
|
+
return `Dependency build review (no package code ran)\n\n${entries}\n\nApprovals persist by exact source in zyrk-workspace.json. User and project denies take precedence.\nApproved scripts run with your OS account permissions; approval is not a sandbox.\n`;
|
|
31
|
+
}
|
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAqCA,OAAO,EAAe,SAAS,EAAe,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,OAAO,EAAoB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAM3C,OAAO,EAAqC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhF,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAsFzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA0BhD;AA0MD,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6EF;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GACnD,SAAS,CAgDX;AAmBD,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAC1B,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CACxC,CAAC;AAuDF,gFAAgF;AAChF,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAuhBpE"}
|
package/dist/cli/main.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { runNextCommand } from "../commands/next.js";
|
|
2
2
|
import { createInstallProgress } from "./progress.js";
|
|
3
|
+
import { renderBuildReviews } from "./build-approval.js";
|
|
3
4
|
import { renderCommandError, renderCommandOutput } from "./terminal.js";
|
|
4
5
|
import { runMaintenanceCommand } from "../commands/maintenance.js";
|
|
5
6
|
import { runDeployCommand } from "../commands/deploy.js";
|
|
@@ -39,6 +40,7 @@ function installCompletion(readiness) {
|
|
|
39
40
|
};
|
|
40
41
|
case "intentionally-unbuilt":
|
|
41
42
|
return {
|
|
43
|
+
tone: "attention",
|
|
42
44
|
title: "Installed; some dependency builds were intentionally skipped.",
|
|
43
45
|
detail: "Review build policy before running packages that need those builds.",
|
|
44
46
|
};
|
|
@@ -220,7 +222,7 @@ Example: zyrk audit --audit-level high`,
|
|
|
220
222
|
Reconstruct project links from verified sources selected by the existing lockfile.`,
|
|
221
223
|
"approve-builds": `Usage: zyrk approve-builds [package ... | --all]
|
|
222
224
|
|
|
223
|
-
Review
|
|
225
|
+
Review exact source identities, lifecycle commands, and current policy decisions without running package code. Selected approvals persist to zyrk-workspace.json; user and project denies take precedence. Approved scripts are not sandboxed.
|
|
224
226
|
|
|
225
227
|
Example: zyrk approve-builds`,
|
|
226
228
|
rebuild: `Usage: zyrk rebuild [--offline]
|
|
@@ -426,16 +428,16 @@ function readCliVersion() {
|
|
|
426
428
|
}
|
|
427
429
|
}
|
|
428
430
|
async function promptForBuildApproval(builds, input, output) {
|
|
429
|
-
output.write("\nDependency
|
|
431
|
+
output.write("\nDependency build approval\nScripts run with your OS account permissions; approval is not a sandbox.\nSelected exact-source approvals are saved to zyrk-workspace.json for collaborators.\n\n");
|
|
430
432
|
builds.forEach((build, index) => {
|
|
431
433
|
const stages = build.stages
|
|
432
434
|
.map((stage) => `${stage.name}: ${redactSecrets(stage.command)
|
|
433
435
|
.replace(/[\x00-\x1f\x7f-\x9f]/g, "")
|
|
434
436
|
.slice(0, 180)}`)
|
|
435
437
|
.join("; ");
|
|
436
|
-
output.write(` ${index + 1}. ${build.name}@${build.version}
|
|
438
|
+
output.write(` ${index + 1}. [ ] ${build.name}@${build.version}\n source: ${build.sourceId}\n lifecycle: ${stages}\n`);
|
|
437
439
|
});
|
|
438
|
-
output.write("Enter numbers separated by commas to approve selected sources, `all` to approve all listed sources, or press Enter to skip
|
|
440
|
+
output.write("Enter numbers separated by commas to approve selected sources, `all` to approve all listed sources, or press Enter to skip pending scripts and continue intentionally unbuilt.\n");
|
|
439
441
|
const prompt = createInterface({
|
|
440
442
|
input,
|
|
441
443
|
output: output,
|
|
@@ -616,6 +618,8 @@ export async function runCli(options) {
|
|
|
616
618
|
const payload = (command === "audit" ? sanitizeDiagnostic(result) : result);
|
|
617
619
|
if (Array.isArray(payload.builds))
|
|
618
620
|
payload.builds = sanitizeDiagnostic(payload.builds);
|
|
621
|
+
if (Array.isArray(payload.buildReviews))
|
|
622
|
+
payload.buildReviews = sanitizeDiagnostic(payload.buildReviews);
|
|
619
623
|
const exitCode = payload.status === "unavailable" || payload.thresholdExceeded === true
|
|
620
624
|
? 1
|
|
621
625
|
: 0;
|
|
@@ -626,15 +630,10 @@ export async function runCli(options) {
|
|
|
626
630
|
stderr: "",
|
|
627
631
|
});
|
|
628
632
|
if (command === "approve-builds") {
|
|
629
|
-
const
|
|
633
|
+
const reviews = (payload.buildReviews ?? []);
|
|
630
634
|
return emit({
|
|
631
635
|
exitCode,
|
|
632
|
-
stdout:
|
|
633
|
-
? builds
|
|
634
|
-
.map((b) => `${b.name}@${b.version} ${b.sourceId}\n${b.stages.map((s) => ` ${s.name}: ${redactSecrets(s.command)}`).join("\n")}`)
|
|
635
|
-
.join("\n") +
|
|
636
|
-
"\nReview runs no package code. Approval trusts these exact candidate sources.\n"
|
|
637
|
-
: "No dependency builds require approval.\n",
|
|
636
|
+
stdout: renderBuildReviews(reviews),
|
|
638
637
|
stderr: "",
|
|
639
638
|
});
|
|
640
639
|
}
|
|
@@ -805,10 +804,7 @@ export async function runCli(options) {
|
|
|
805
804
|
}
|
|
806
805
|
: {}),
|
|
807
806
|
});
|
|
808
|
-
progress.close(
|
|
809
|
-
title: `Dependency changes installed from the verified shared store.`,
|
|
810
|
-
detail: `${result.packages} packages; ${result.reused} realizations reused.`,
|
|
811
|
-
});
|
|
807
|
+
progress.close(installCompletion(result.readiness));
|
|
812
808
|
if (parsed.json) {
|
|
813
809
|
return emit({
|
|
814
810
|
exitCode: 0,
|
package/dist/cli/progress.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { InstallProgress } from "../install/run.ts";
|
|
|
2
2
|
export type InstallCompletion = {
|
|
3
3
|
title: string;
|
|
4
4
|
detail?: string;
|
|
5
|
+
tone?: "success" | "attention";
|
|
5
6
|
};
|
|
6
7
|
/** Presentation only: never writes to stdout or exposes package URLs or paths. */
|
|
7
8
|
export declare function createInstallProgress(stream: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAYzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAYzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;CAChC,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE;IAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAC1D,KAAK,EAAE,OAAO,EACd,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC;IACD,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,KAAK,CAAC,UAAU,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC7C,CAiIA"}
|
package/dist/cli/progress.js
CHANGED
|
@@ -18,6 +18,9 @@ export function createInstallProgress(stream, quiet, options = {}) {
|
|
|
18
18
|
let statusLine = false;
|
|
19
19
|
let lastDownload = 0;
|
|
20
20
|
let lastPlain = "";
|
|
21
|
+
let pendingPlain = "";
|
|
22
|
+
let lastPlainAt = -Infinity;
|
|
23
|
+
let downloadAnnounced = false;
|
|
21
24
|
const write = (text) => {
|
|
22
25
|
try {
|
|
23
26
|
stream.write(text);
|
|
@@ -32,6 +35,14 @@ export function createInstallProgress(stream, quiet, options = {}) {
|
|
|
32
35
|
write(`\r\u001b[2K${lineBreak ? "\n" : ""}`);
|
|
33
36
|
statusLine = false;
|
|
34
37
|
};
|
|
38
|
+
const flushPlain = () => {
|
|
39
|
+
if (pendingPlain && pendingPlain !== lastPlain) {
|
|
40
|
+
write(`zyrk: ${pendingPlain}\n`);
|
|
41
|
+
lastPlain = pendingPlain;
|
|
42
|
+
lastPlainAt = Date.now();
|
|
43
|
+
}
|
|
44
|
+
pendingPlain = "";
|
|
45
|
+
};
|
|
35
46
|
return {
|
|
36
47
|
update(event) {
|
|
37
48
|
if (quiet || closed)
|
|
@@ -45,6 +56,8 @@ export function createInstallProgress(stream, quiet, options = {}) {
|
|
|
45
56
|
if (pkg?.status === "linked") {
|
|
46
57
|
if (tty)
|
|
47
58
|
clearStatus(true);
|
|
59
|
+
else
|
|
60
|
+
flushPlain();
|
|
48
61
|
write(`${green("✓")} ${packageLabel} linked\n`);
|
|
49
62
|
return;
|
|
50
63
|
}
|
|
@@ -63,7 +76,7 @@ export function createInstallProgress(stream, quiet, options = {}) {
|
|
|
63
76
|
lastDownload = Date.now();
|
|
64
77
|
const status = pkg?.status === "downloading"
|
|
65
78
|
? ` Downloading ${packageLabel}: ${((pkg.bytes ?? 0) / 1024).toFixed(1)} KiB`
|
|
66
|
-
: ` Sources verified ${event.completed ?? 0}
|
|
79
|
+
: ` Sources verified ${event.completed ?? 0}${event.total === undefined ? "" : `/${event.total}`} · reused ${event.reused ?? 0} · downloaded ${event.downloaded ?? 0}`;
|
|
67
80
|
write(`\r\u001b[2K${dim(status)}`);
|
|
68
81
|
statusLine = true;
|
|
69
82
|
}
|
|
@@ -78,9 +91,25 @@ export function createInstallProgress(stream, quiet, options = {}) {
|
|
|
78
91
|
(event.reused === undefined
|
|
79
92
|
? ""
|
|
80
93
|
: ` — reused ${event.reused}, downloaded ${event.downloaded ?? 0}`);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
94
|
+
const newStage = stage !== currentStage;
|
|
95
|
+
if (newStage) {
|
|
96
|
+
flushPlain();
|
|
97
|
+
currentStage = stage;
|
|
98
|
+
downloadAnnounced = false;
|
|
99
|
+
}
|
|
100
|
+
const firstDownload = pkg?.status === "downloading" && !downloadAnnounced;
|
|
101
|
+
if (pkg?.status === "downloading")
|
|
102
|
+
downloadAnnounced = true;
|
|
103
|
+
pendingPlain = current;
|
|
104
|
+
const sourcesComplete = event.phase === "fetching" &&
|
|
105
|
+
pkg?.status !== "downloading" &&
|
|
106
|
+
event.total !== undefined &&
|
|
107
|
+
event.completed === event.total;
|
|
108
|
+
if (newStage ||
|
|
109
|
+
firstDownload ||
|
|
110
|
+
sourcesComplete ||
|
|
111
|
+
Date.now() - lastPlainAt >= 1000)
|
|
112
|
+
flushPlain();
|
|
84
113
|
},
|
|
85
114
|
close(completion) {
|
|
86
115
|
if (closed)
|
|
@@ -88,11 +117,18 @@ export function createInstallProgress(stream, quiet, options = {}) {
|
|
|
88
117
|
closed = true;
|
|
89
118
|
if (quiet)
|
|
90
119
|
return;
|
|
120
|
+
if (!tty)
|
|
121
|
+
flushPlain();
|
|
91
122
|
if (tty) {
|
|
92
123
|
clearStatus(true);
|
|
93
124
|
if (completion) {
|
|
94
125
|
write(`${dim("─".repeat(46))}\n`);
|
|
95
|
-
|
|
126
|
+
const marker = completion.tone === "attention"
|
|
127
|
+
? color
|
|
128
|
+
? "\u001b[33m!\u001b[0m"
|
|
129
|
+
: "!"
|
|
130
|
+
: green("✓");
|
|
131
|
+
write(`${marker} ${completion.title}\n`);
|
|
96
132
|
if (completion.detail)
|
|
97
133
|
write(`${dim(completion.detail)}\n`);
|
|
98
134
|
}
|
|
@@ -12,6 +12,10 @@ export type BuildCandidate = {
|
|
|
12
12
|
command: string;
|
|
13
13
|
}>;
|
|
14
14
|
};
|
|
15
|
+
export type BuildReview = BuildCandidate & {
|
|
16
|
+
decision: "approved" | "denied" | "pending";
|
|
17
|
+
policyScope: "user-deny" | "project-deny" | "project-policy" | "workspace-policy" | "local-session" | "none";
|
|
18
|
+
};
|
|
15
19
|
export declare const WORKSPACE_POLICY_FILE = "zyrk-workspace.json";
|
|
16
20
|
export declare function candidates(nodes: readonly ResolvedOccurrence[], dirs: ReadonlyMap<string, string>): Promise<BuildCandidate[]>;
|
|
17
21
|
export declare function candidateDigest(graph: GraphDoc, builds: readonly BuildCandidate[], policy: unknown, patches: string): string;
|
|
@@ -24,13 +28,14 @@ export declare function approveCandidate(options: {
|
|
|
24
28
|
policy?: unknown;
|
|
25
29
|
portable?: boolean;
|
|
26
30
|
}): Promise<void>;
|
|
27
|
-
export declare function
|
|
31
|
+
export declare function reviewBuildCandidates(options: {
|
|
28
32
|
project: string;
|
|
29
33
|
env: NodeJS.ProcessEnv;
|
|
30
34
|
digest: string;
|
|
31
35
|
builds: readonly BuildCandidate[];
|
|
32
36
|
policy: unknown;
|
|
33
|
-
}): Promise<
|
|
37
|
+
}): Promise<BuildReview[]>;
|
|
38
|
+
export declare function approvedCandidates(options: Parameters<typeof reviewBuildCandidates>[0]): Promise<BuildCandidate[]>;
|
|
34
39
|
export declare function assertApproved(options: {
|
|
35
40
|
project: string;
|
|
36
41
|
env: NodeJS.ProcessEnv;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/install/private.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,OAAO,EAA2B,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAOjE,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD,CAAC;AACF,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAe3D,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,kBAAkB,EAAE,EACpC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,cAAc,EAAE,CAAC,CA8C3B;AAyBD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,MAAM,GACd,MAAM,CASR;AACD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAClC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/install/private.ts"],"names":[],"mappings":"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"}
|
package/dist/install/private.js
CHANGED
|
@@ -88,25 +88,22 @@ export function candidateDigest(graph, builds, policy, patches) {
|
|
|
88
88
|
}
|
|
89
89
|
export async function approveCandidate(options) {
|
|
90
90
|
const user = await readUserPolicy(options.env ?? process.env);
|
|
91
|
-
for (const build of options.builds)
|
|
92
|
-
if (denied(user.scripts, build) || denied(options.policy, build))
|
|
93
|
-
fail(`Build of ${build.name}@${build.version} is denied by policy.`);
|
|
94
91
|
const selected = new Set(options.selected);
|
|
95
92
|
const all = selected.has("*");
|
|
96
93
|
for (const name of selected)
|
|
97
94
|
if (name !== "*" &&
|
|
98
95
|
!options.builds.some((b) => b.name === name || b.sourceId === name))
|
|
99
96
|
fail("An approval selector does not match a reviewed build candidate.");
|
|
97
|
+
const selectedBuilds = options.builds.filter((build) => all || selected.has(build.name) || selected.has(build.sourceId));
|
|
98
|
+
const deniedSelections = selectedBuilds.filter((build) => denied(user.scripts, build) || denied(options.policy, build));
|
|
99
|
+
for (const build of deniedSelections)
|
|
100
|
+
fail(`Build of ${build.name}@${build.version} is denied by policy.`);
|
|
100
101
|
await writeFileAtomic(path.join(options.project, ".zyrk-local", "approvals.json"), JSON.stringify({
|
|
101
102
|
schemaVersion: 1,
|
|
102
103
|
candidate: options.digest,
|
|
103
|
-
sources:
|
|
104
|
-
.filter((b) => all || selected.has(b.name) || selected.has(b.sourceId))
|
|
105
|
-
.map((b) => b.sourceId)
|
|
106
|
-
.sort(),
|
|
104
|
+
sources: selectedBuilds.map((build) => build.sourceId).sort(),
|
|
107
105
|
}), { mode: 0o600 });
|
|
108
106
|
if (options.portable) {
|
|
109
|
-
const selectedBuilds = options.builds.filter((build) => all || selected.has(build.name) || selected.has(build.sourceId));
|
|
110
107
|
await writePortableApprovals(options.project, selectedBuilds);
|
|
111
108
|
}
|
|
112
109
|
}
|
|
@@ -164,7 +161,7 @@ async function readUserPolicy(env) {
|
|
|
164
161
|
fail("Mandatory user build policy is malformed.");
|
|
165
162
|
return user;
|
|
166
163
|
}
|
|
167
|
-
export async function
|
|
164
|
+
export async function reviewBuildCandidates(options) {
|
|
168
165
|
if (!options.builds.length)
|
|
169
166
|
return [];
|
|
170
167
|
const user = await readUserPolicy(options.env);
|
|
@@ -181,9 +178,11 @@ export async function approvedCandidates(options) {
|
|
|
181
178
|
local = undefined;
|
|
182
179
|
}
|
|
183
180
|
const portable = await readPortableApprovals(options.project);
|
|
184
|
-
return options.builds.
|
|
185
|
-
if (denied(user.scripts, build)
|
|
186
|
-
return
|
|
181
|
+
return options.builds.map((build) => {
|
|
182
|
+
if (denied(user.scripts, build))
|
|
183
|
+
return { ...build, decision: "denied", policyScope: "user-deny" };
|
|
184
|
+
if (denied(options.policy, build))
|
|
185
|
+
return { ...build, decision: "denied", policyScope: "project-deny" };
|
|
187
186
|
const manifestAllowed = object(options.policy) &&
|
|
188
187
|
Array.isArray(options.policy.allow) &&
|
|
189
188
|
options.policy.allow.includes(build.sourceId);
|
|
@@ -193,9 +192,30 @@ export async function approvedCandidates(options) {
|
|
|
193
192
|
local.candidate === options.digest &&
|
|
194
193
|
Array.isArray(local.sources) &&
|
|
195
194
|
local.sources.includes(build.sourceId);
|
|
196
|
-
|
|
195
|
+
if (manifestAllowed)
|
|
196
|
+
return {
|
|
197
|
+
...build,
|
|
198
|
+
decision: "approved",
|
|
199
|
+
policyScope: "project-policy",
|
|
200
|
+
};
|
|
201
|
+
if (workspaceAllowed)
|
|
202
|
+
return {
|
|
203
|
+
...build,
|
|
204
|
+
decision: "approved",
|
|
205
|
+
policyScope: "workspace-policy",
|
|
206
|
+
};
|
|
207
|
+
if (localAllowed)
|
|
208
|
+
return {
|
|
209
|
+
...build,
|
|
210
|
+
decision: "approved",
|
|
211
|
+
policyScope: "local-session",
|
|
212
|
+
};
|
|
213
|
+
return { ...build, decision: "pending", policyScope: "none" };
|
|
197
214
|
});
|
|
198
215
|
}
|
|
216
|
+
export async function approvedCandidates(options) {
|
|
217
|
+
return (await reviewBuildCandidates(options)).filter((review) => review.decision === "approved");
|
|
218
|
+
}
|
|
199
219
|
export async function assertApproved(options) {
|
|
200
220
|
const approved = await approvedCandidates(options);
|
|
201
221
|
if (approved.length !== options.builds.length) {
|
package/dist/install/run.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export type InstallResult = {
|
|
|
62
62
|
generationId?: string;
|
|
63
63
|
candidateDigest?: string;
|
|
64
64
|
builds?: BuildCandidate[];
|
|
65
|
+
buildReviews?: import("./private.ts").BuildReview[];
|
|
65
66
|
};
|
|
66
67
|
export declare function installProject(options: InstallOptions): Promise<InstallResult>;
|
|
67
68
|
//# sourceMappingURL=run.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/install/run.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/install/run.ts"],"names":[],"mappings":"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"}
|
package/dist/install/run.js
CHANGED
|
@@ -4,7 +4,7 @@ import { findWorkspaceRoot } from "./workspaces.js";
|
|
|
4
4
|
import { assertSupportedSourcePayload } from "./source-policy.js";
|
|
5
5
|
import { prepareRepair } from "./repair.js";
|
|
6
6
|
import { createFetchOperation } from "../fetch/package.js";
|
|
7
|
-
import { candidates, candidateDigest, approveCandidate,
|
|
7
|
+
import { candidates, candidateDigest, approveCandidate, reviewBuildCandidates, materializePrivate, buildPrivate, } from "./private.js";
|
|
8
8
|
import { loadProjectPatches, applyProjectPatches } from "../commands/patch.js";
|
|
9
9
|
import { registerGeneration } from "./metadata.js";
|
|
10
10
|
import { randomId } from "../util/ids.js";
|
|
@@ -565,6 +565,13 @@ export async function installProject(options) {
|
|
|
565
565
|
policy: scriptPolicy(manifest),
|
|
566
566
|
portable: true,
|
|
567
567
|
});
|
|
568
|
+
const buildReviews = await reviewBuildCandidates({
|
|
569
|
+
project,
|
|
570
|
+
env: options.env ?? process.env,
|
|
571
|
+
digest: reviewedDigest,
|
|
572
|
+
builds,
|
|
573
|
+
policy: scriptPolicy(manifest),
|
|
574
|
+
});
|
|
568
575
|
return {
|
|
569
576
|
readiness: "build-review",
|
|
570
577
|
packages: activeNodes.length,
|
|
@@ -572,6 +579,7 @@ export async function installProject(options) {
|
|
|
572
579
|
warnings,
|
|
573
580
|
candidateDigest: reviewedDigest,
|
|
574
581
|
builds,
|
|
582
|
+
buildReviews,
|
|
575
583
|
};
|
|
576
584
|
}
|
|
577
585
|
let approvedBuilds = [];
|
|
@@ -583,11 +591,14 @@ export async function installProject(options) {
|
|
|
583
591
|
builds,
|
|
584
592
|
policy: scriptPolicy(manifest),
|
|
585
593
|
};
|
|
586
|
-
|
|
594
|
+
let reviews = await reviewBuildCandidates(approvalOptions);
|
|
595
|
+
approvedBuilds = reviews.filter((review) => review.decision === "approved");
|
|
587
596
|
if (approvedBuilds.length < builds.length &&
|
|
588
597
|
options.requestBuildApproval) {
|
|
589
|
-
const pending =
|
|
590
|
-
const selected =
|
|
598
|
+
const pending = reviews.filter((review) => review.decision === "pending");
|
|
599
|
+
const selected = pending.length
|
|
600
|
+
? await options.requestBuildApproval(pending)
|
|
601
|
+
: [];
|
|
591
602
|
if (selected.length) {
|
|
592
603
|
await approveCandidate({
|
|
593
604
|
project,
|
|
@@ -598,7 +609,8 @@ export async function installProject(options) {
|
|
|
598
609
|
policy: scriptPolicy(manifest),
|
|
599
610
|
portable: true,
|
|
600
611
|
});
|
|
601
|
-
|
|
612
|
+
reviews = await reviewBuildCandidates(approvalOptions);
|
|
613
|
+
approvedBuilds = reviews.filter((review) => review.decision === "approved");
|
|
602
614
|
}
|
|
603
615
|
}
|
|
604
616
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-install.d.ts","sourceRoot":"","sources":["../../src/install/workspace-install.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuH9D,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"workspace-install.d.ts","sourceRoot":"","sources":["../../src/install/workspace-install.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuH9D,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAouBxB"}
|
|
@@ -32,7 +32,7 @@ import { loadProjectPatches, applyProjectPatches } from "../commands/patch.js";
|
|
|
32
32
|
import { prepareRepair } from "./repair.js";
|
|
33
33
|
import { assertSupportedSourcePayload } from "./source-policy.js";
|
|
34
34
|
import { registerGeneration } from "./metadata.js";
|
|
35
|
-
import { candidates, candidateDigest, approveCandidate,
|
|
35
|
+
import { candidates, candidateDigest, approveCandidate, reviewBuildCandidates, buildPrivate, } from "./private.js";
|
|
36
36
|
const object = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
37
37
|
const unsupported = (message) => {
|
|
38
38
|
throw new ZyrkError("ZYRK_NOT_IMPLEMENTED", message, {
|
|
@@ -446,6 +446,13 @@ export async function installWorkspaceProject(options) {
|
|
|
446
446
|
policy,
|
|
447
447
|
portable: true,
|
|
448
448
|
});
|
|
449
|
+
const buildReviews = await reviewBuildCandidates({
|
|
450
|
+
project: root,
|
|
451
|
+
env: options.env ?? process.env,
|
|
452
|
+
digest,
|
|
453
|
+
builds,
|
|
454
|
+
policy,
|
|
455
|
+
});
|
|
449
456
|
return {
|
|
450
457
|
readiness: "build-review",
|
|
451
458
|
packages: nodes.length,
|
|
@@ -453,6 +460,7 @@ export async function installWorkspaceProject(options) {
|
|
|
453
460
|
warnings,
|
|
454
461
|
candidateDigest: digest,
|
|
455
462
|
builds,
|
|
463
|
+
buildReviews,
|
|
456
464
|
};
|
|
457
465
|
}
|
|
458
466
|
let approvedBuilds = [];
|
|
@@ -464,11 +472,14 @@ export async function installWorkspaceProject(options) {
|
|
|
464
472
|
builds,
|
|
465
473
|
policy,
|
|
466
474
|
};
|
|
467
|
-
|
|
475
|
+
let reviews = await reviewBuildCandidates(approvalOptions);
|
|
476
|
+
approvedBuilds = reviews.filter((review) => review.decision === "approved");
|
|
468
477
|
if (approvedBuilds.length < builds.length &&
|
|
469
478
|
options.requestBuildApproval) {
|
|
470
|
-
const pending =
|
|
471
|
-
const selected =
|
|
479
|
+
const pending = reviews.filter((review) => review.decision === "pending");
|
|
480
|
+
const selected = pending.length
|
|
481
|
+
? await options.requestBuildApproval(pending)
|
|
482
|
+
: [];
|
|
472
483
|
if (selected.length) {
|
|
473
484
|
await approveCandidate({
|
|
474
485
|
project: root,
|
|
@@ -479,7 +490,8 @@ export async function installWorkspaceProject(options) {
|
|
|
479
490
|
policy,
|
|
480
491
|
portable: true,
|
|
481
492
|
});
|
|
482
|
-
|
|
493
|
+
reviews = await reviewBuildCandidates(approvalOptions);
|
|
494
|
+
approvedBuilds = reviews.filter((review) => review.decision === "approved");
|
|
483
495
|
}
|
|
484
496
|
}
|
|
485
497
|
}
|