@reddoorla/maintenance 0.62.1 → 0.64.0
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/{announce-N6VWO5QZ.js → announce-QEON4O7E.js} +13 -21
- package/dist/announce-QEON4O7E.js.map +1 -0
- package/dist/chunk-GECESMVS.js +36 -0
- package/dist/chunk-GECESMVS.js.map +1 -0
- package/dist/{chunk-DXRKWALS.js → chunk-J37CZORZ.js} +57 -55
- package/dist/chunk-J37CZORZ.js.map +1 -0
- package/dist/chunk-P7VJM46I.js +63 -0
- package/dist/chunk-P7VJM46I.js.map +1 -0
- package/dist/cli/bin.js +11 -2
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.js +73 -33
- package/dist/index.js.map +1 -1
- package/dist/{orchestrate-I3KAJGFB.js → orchestrate-CYYZ737H.js} +4 -3
- package/dist/{report-PY6O3YMX.js → report-QNE7HFOZ.js} +2 -2
- package/dist/selftest-5ELLRH6Q.js +161 -0
- package/dist/selftest-5ELLRH6Q.js.map +1 -0
- package/package.json +1 -1
- package/dist/announce-N6VWO5QZ.js.map +0 -1
- package/dist/chunk-DXRKWALS.js.map +0 -1
- /package/dist/{orchestrate-I3KAJGFB.js.map → orchestrate-CYYZ737H.js.map} +0 -0
- /package/dist/{report-PY6O3YMX.js.map → report-QNE7HFOZ.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "./chunk-BMDBOPN3.js";
|
|
1
2
|
import {
|
|
2
3
|
findDueReports
|
|
3
4
|
} from "./chunk-WVRPOXKH.js";
|
|
@@ -25,17 +26,17 @@ import {
|
|
|
25
26
|
draftReportForSite
|
|
26
27
|
} from "./chunk-NPJFHBAX.js";
|
|
27
28
|
import "./chunk-6LIWDIXU.js";
|
|
28
|
-
import "./chunk-BMDBOPN3.js";
|
|
29
29
|
import {
|
|
30
30
|
sendApprovedReports
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-J37CZORZ.js";
|
|
32
|
+
import "./chunk-OGGRFBL4.js";
|
|
33
|
+
import "./chunk-GECESMVS.js";
|
|
32
34
|
import {
|
|
33
35
|
BLURRED_CID,
|
|
34
36
|
CHECK_CID,
|
|
35
37
|
loadBundledImages,
|
|
36
38
|
renderReportHtml
|
|
37
39
|
} from "./chunk-U3MF6RCS.js";
|
|
38
|
-
import "./chunk-OGGRFBL4.js";
|
|
39
40
|
import {
|
|
40
41
|
checklistFor,
|
|
41
42
|
escapeHtml,
|
|
@@ -650,7 +651,7 @@ function isReadyDeployStatus(status) {
|
|
|
650
651
|
function isFailedDeployStatus(status) {
|
|
651
652
|
return status !== null && FAILED_DEPLOY_STATES.has(status.toLowerCase());
|
|
652
653
|
}
|
|
653
|
-
var NEEDS_YOU_GROUP_RANK = { broken: 0,
|
|
654
|
+
var NEEDS_YOU_GROUP_RANK = { broken: 0, watch: 1, approval: 2 };
|
|
654
655
|
function buildNeedsYouFeed(model) {
|
|
655
656
|
const bySlug = /* @__PURE__ */ new Map();
|
|
656
657
|
const get = (siteName) => {
|
|
@@ -663,8 +664,8 @@ function buildNeedsYouFeed(model) {
|
|
|
663
664
|
reasons: [],
|
|
664
665
|
hasCritical: false,
|
|
665
666
|
broken: false,
|
|
666
|
-
|
|
667
|
-
|
|
667
|
+
watch: false,
|
|
668
|
+
approval: false
|
|
668
669
|
};
|
|
669
670
|
bySlug.set(slug, a);
|
|
670
671
|
}
|
|
@@ -672,17 +673,25 @@ function buildNeedsYouFeed(model) {
|
|
|
672
673
|
};
|
|
673
674
|
for (const card2 of model.cards) {
|
|
674
675
|
if (card2.tier === "attention") {
|
|
675
|
-
|
|
676
|
-
|
|
676
|
+
const isSelfPatchingVuln = (it) => it.kind === "vuln" && it.autoFixExhausted !== true;
|
|
677
|
+
const hardBroken = card2.items.filter((it) => !isSelfPatchingVuln(it));
|
|
678
|
+
const selfPatchingVulns = card2.items.filter(isSelfPatchingVuln);
|
|
679
|
+
if (hardBroken.length > 0) {
|
|
677
680
|
const a = get(card2.site.name);
|
|
678
|
-
|
|
681
|
+
for (const it of hardBroken) {
|
|
682
|
+
a.reasons.push(it.title);
|
|
683
|
+
if (it.severity === "critical") a.hasCritical = true;
|
|
684
|
+
}
|
|
679
685
|
a.broken = true;
|
|
680
|
-
|
|
686
|
+
} else if (selfPatchingVulns.length > 0) {
|
|
687
|
+
const a = get(card2.site.name);
|
|
688
|
+
for (const it of selfPatchingVulns) a.reasons.push(it.title);
|
|
689
|
+
a.watch = true;
|
|
681
690
|
}
|
|
682
691
|
} else if (card2.tier === "watch" && card2.watchReasons.length > 0) {
|
|
683
692
|
const a = get(card2.site.name);
|
|
684
693
|
for (const r of card2.watchReasons) a.reasons.push(r);
|
|
685
|
-
a.
|
|
694
|
+
a.watch = true;
|
|
686
695
|
}
|
|
687
696
|
}
|
|
688
697
|
for (const p of model.pending) {
|
|
@@ -693,7 +702,7 @@ function buildNeedsYouFeed(model) {
|
|
|
693
702
|
const items = [];
|
|
694
703
|
for (const a of bySlug.values()) {
|
|
695
704
|
if (a.reasons.length === 0) continue;
|
|
696
|
-
const group = a.broken ? "broken" : a.
|
|
705
|
+
const group = a.broken ? "broken" : a.watch ? "watch" : "approval";
|
|
697
706
|
items.push({
|
|
698
707
|
group,
|
|
699
708
|
hasCritical: a.hasCritical,
|
|
@@ -962,7 +971,11 @@ details.fleet-browse > summary, details.inbox > summary { cursor:pointer; font-w
|
|
|
962
971
|
.verdict.ok .verdict-meta { color:#2e7d32; }
|
|
963
972
|
.verdict.warn { background:#fdecea; color:#b00; }
|
|
964
973
|
.verdict.warn .verdict-meta { color:#b00; opacity:0.85; }
|
|
965
|
-
|
|
974
|
+
.verdict.watch { background:#fff4e5; color:#a65a00; }
|
|
975
|
+
.verdict.watch .verdict-meta { color:#a65a00; opacity:0.85; }
|
|
976
|
+
.verdict.soft { background:#e7f1ff; color:#1c5d99; }
|
|
977
|
+
.verdict.soft .verdict-meta { color:#1c5d99; opacity:0.85; }
|
|
978
|
+
@media (prefers-color-scheme: dark) { .verdict.ok { background:#10240f; color:#7fce85; } .verdict.warn { background:#2a0f0d; color:#ff8a80; } .verdict.watch { background:#2a2410; color:#ffd454; } .verdict.soft { background:#0f1d2a; color:#7fb6e8; } }
|
|
966
979
|
.verdict .fleet-actions { margin:0.6rem 0 0; }
|
|
967
980
|
.needs-you { border:1px solid #e5e5e5; border-radius:8px; padding:0.75rem 1rem; margin-bottom:1.25rem; }
|
|
968
981
|
@media (prefers-color-scheme: dark) { .needs-you { border-color:#2a2a2a; background:#181818; } }
|
|
@@ -976,39 +989,66 @@ details.fleet-browse > summary, details.inbox > summary { cursor:pointer; font-w
|
|
|
976
989
|
.dot { width:0.55rem; height:0.55rem; border-radius:50%; display:inline-block; flex:0 0 auto; }
|
|
977
990
|
.dot.broken { background:#dc2626; }
|
|
978
991
|
.dot.approval { background:#2563eb; }
|
|
979
|
-
.dot.
|
|
992
|
+
.dot.watch { background:#f59e0b; }
|
|
980
993
|
`;
|
|
981
|
-
function
|
|
994
|
+
function needsYouCounts(feed) {
|
|
995
|
+
let broken = 0;
|
|
996
|
+
let watch = 0;
|
|
997
|
+
let approval = 0;
|
|
998
|
+
for (const i of feed) {
|
|
999
|
+
if (i.group === "broken") broken++;
|
|
1000
|
+
else if (i.group === "watch") watch++;
|
|
1001
|
+
else approval++;
|
|
1002
|
+
}
|
|
1003
|
+
return { broken, watch, approval };
|
|
1004
|
+
}
|
|
1005
|
+
function verdictBar(model, feed) {
|
|
982
1006
|
const auditedIso = fleetLastAuditedAt(model.cards);
|
|
983
|
-
const
|
|
984
|
-
const
|
|
985
|
-
const
|
|
1007
|
+
const auditedTerm = auditedIso ? `fleet last audited ${escapeHtml(relativeTimeFromNow(auditedIso))}` : null;
|
|
1008
|
+
const total = model.cards.length;
|
|
1009
|
+
const { broken, watch, approval } = needsYouCounts(feed);
|
|
1010
|
+
const healthy = Math.max(0, total - (broken + watch + approval));
|
|
986
1011
|
const actions = `<div class="fleet-actions">
|
|
987
1012
|
<button type="button" class="refresh-fleet" data-refresh-url="/api/fleet/refresh">\u21BB Audit fleet</button>
|
|
988
1013
|
<div id="rf-status" class="rf-status" aria-live="polite"></div>
|
|
989
1014
|
</div>`;
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
<div class="verdict-meta">${sitesWord} healthy${audited}</div>
|
|
994
|
-
${actions}
|
|
995
|
-
</div>`;
|
|
996
|
-
}
|
|
997
|
-
const noun = feedCount === 1 ? "site needs" : "sites need";
|
|
998
|
-
return `<div class="verdict warn">
|
|
999
|
-
<div class="verdict-line">\u26A0 ${feedCount} ${noun} you</div>
|
|
1000
|
-
<div class="verdict-meta">${sitesWord}${audited}</div>
|
|
1015
|
+
const render = (cls, line, terms) => `<div class="verdict ${cls}">
|
|
1016
|
+
<div class="verdict-line">${line}</div>
|
|
1017
|
+
<div class="verdict-meta">${terms.filter(Boolean).join(" \xB7 ")}</div>
|
|
1001
1018
|
${actions}
|
|
1002
1019
|
</div>`;
|
|
1020
|
+
if (broken === 0 && watch === 0 && approval === 0) {
|
|
1021
|
+
const sitesWord = `${total} site${total === 1 ? "" : "s"}`;
|
|
1022
|
+
return render("ok", "\u2713 All clear", [`${sitesWord} healthy`, auditedTerm]);
|
|
1023
|
+
}
|
|
1024
|
+
const watchTerm = watch > 0 ? `${watch} watching` : null;
|
|
1025
|
+
const approvalTerm = approval > 0 ? `${approval} waiting on you` : null;
|
|
1026
|
+
const healthyTerm = healthy > 0 ? `${healthy} healthy` : null;
|
|
1027
|
+
if (broken > 0) {
|
|
1028
|
+
return render("warn", `\u26A0 ${broken} site${broken === 1 ? "" : "s"} broken`, [
|
|
1029
|
+
watchTerm,
|
|
1030
|
+
approvalTerm,
|
|
1031
|
+
healthyTerm,
|
|
1032
|
+
auditedTerm
|
|
1033
|
+
]);
|
|
1034
|
+
}
|
|
1035
|
+
if (watch > 0) {
|
|
1036
|
+
return render("watch", `${watch} site${watch === 1 ? "" : "s"} to watch`, [
|
|
1037
|
+
approvalTerm,
|
|
1038
|
+
healthyTerm,
|
|
1039
|
+
auditedTerm
|
|
1040
|
+
]);
|
|
1041
|
+
}
|
|
1042
|
+
return render("soft", `${approval} waiting on you`, [healthyTerm, auditedTerm]);
|
|
1003
1043
|
}
|
|
1004
1044
|
var NEEDS_YOU_GROUP_LABEL = {
|
|
1005
1045
|
broken: "Broken",
|
|
1006
|
-
|
|
1007
|
-
|
|
1046
|
+
watch: "Watch",
|
|
1047
|
+
approval: "Waiting on your yes"
|
|
1008
1048
|
};
|
|
1009
1049
|
function renderNeedsYouFeed(feed) {
|
|
1010
1050
|
if (feed.length === 0) return "";
|
|
1011
|
-
const groups = ["broken", "
|
|
1051
|
+
const groups = ["broken", "watch", "approval"];
|
|
1012
1052
|
const blocks = groups.map((g) => {
|
|
1013
1053
|
const rows = feed.filter((i) => i.group === g);
|
|
1014
1054
|
if (rows.length === 0) return "";
|
|
@@ -1212,7 +1252,7 @@ function renderCockpitHtml(model) {
|
|
|
1212
1252
|
<body>
|
|
1213
1253
|
<h1>Reddoor fleet cockpit</h1>
|
|
1214
1254
|
<div class="meta">${total} site${total === 1 ? "" : "s"} on the Reddoor stack.</div>
|
|
1215
|
-
${verdictBar(model, feed
|
|
1255
|
+
${verdictBar(model, feed)}
|
|
1216
1256
|
${renderNeedsYouFeed(feed)}
|
|
1217
1257
|
${renderFleetBrowsePanel(model)}
|
|
1218
1258
|
${renderRecentlyLane(model)}
|