@continuous-excellence/ze-great-dashboard-aws 0.14.2 → 0.14.4

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.
@@ -0,0 +1 @@
1
+ ._board_91ffc_1{gap:var(--gap);height:100dvh;min-height:0;padding:var(--gap);flex-direction:column;display:flex;overflow:hidden auto}._header_91ffc_11{border-bottom:1px solid var(--edge);padding-bottom:var(--gap);flex:none;align-items:baseline;display:flex}._title_91ffc_18{letter-spacing:-.01em;margin:0;font-size:1.75em;font-weight:650}._grid_91ffc_24{gap:var(--gap);flex:1;grid-template-rows:repeat(12,minmax(0,1fr));grid-template-columns:repeat(12,minmax(0,1fr));grid-auto-rows:minmax(0,1fr);align-content:stretch;min-height:0;display:grid}._footerTools_91ffc_34{align-items:center;gap:.75rem;display:flex}._layoutWarning_91ffc_39{position:relative}._layoutWarningButton_91ffc_42{border:1px solid var(--status-warning);min-width:2em;min-height:2em;color:var(--status-warning);background:var(--surface-raised);font:inherit;cursor:pointer;border-radius:50%;justify-content:center;align-items:center;gap:.2em;display:inline-flex}._layoutWarningButton_91ffc_42:hover,._layoutWarningButton_91ffc_42:focus-visible{background:var(--surface)}._layoutWarningDialog_91ffc_60{z-index:10;width:min(32rem, calc(100vw - 2 * var(--gap)));border:1px solid var(--status-warning);border-radius:var(--radius);color:var(--ink-secondary);background:var(--surface-raised);padding:.8rem;position:absolute;bottom:calc(100% + .75rem);right:0;box-shadow:0 .5rem 1.5rem #00000059}._layoutWarningHeading_91ffc_73{justify-content:space-between;align-items:center;gap:1rem;display:flex}._layoutWarningHeading_91ffc_73 strong{color:var(--status-warning)}._layoutWarningDialog_91ffc_60 p{margin:.6rem 0}._layoutWarningDialog_91ffc_60 ul{margin:.35rem 0 .75rem;padding-left:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.85em}._layoutWarningClose_91ffc_91{color:var(--ink-muted);cursor:pointer;background:0 0;border:0;font-size:1.25em;line-height:1}._layoutWarningDownloads_91ffc_99{gap:.35rem;display:grid}._layoutWarningDownloads_91ffc_99 a{border:1px solid var(--edge);background:var(--surface-raised);color:var(--ink-secondary);font:inherit;text-align:center;border-radius:.25rem;padding:.3em .55em;text-decoration:none}._layoutWarningDownloads_91ffc_99 a:hover,._layoutWarningDownloads_91ffc_99 a:focus-visible{border-color:var(--ink-secondary);color:var(--ink-primary)}._layoutWarningNote_91ffc_118{color:var(--ink-muted);font-size:.85em}._footer_91ffc_34{color:var(--ink-muted);flex-wrap:wrap;flex:none;justify-content:space-between;align-items:center;gap:.5rem;font-size:.75em;display:flex}@media (width<=64rem){._board_91ffc_1{height:auto;min-height:100dvh;overflow:visible}._grid_91ffc_24{flex:none;grid-template-columns:1fr;grid-auto-rows:auto;min-height:auto}._layoutWarningDialog_91ffc_60{right:var(--gap);bottom:calc(var(--gap) + 3rem);position:fixed}}._diagnostics_lseur_1{position:relative}._button_lseur_5{border:1px solid var(--edge);background:var(--surface-raised);color:var(--ink-secondary);font:inherit;border-radius:.25rem;padding:.3em .55em}._area_lseur_14{z-index:1;border:1px solid var(--edge);border-radius:var(--radius);background:var(--surface-raised);width:min(24rem,90vw);padding:.75rem;position:absolute;bottom:calc(100% + .5rem);right:0;box-shadow:0 .5rem 1.5rem #0008}._area_lseur_14 p{margin:0 0 .5rem}._warning_lseur_31{color:var(--status-warning)}._panels_lseur_35{border-top:1px solid var(--edge);max-height:12rem;margin:.5rem 0;padding-top:.5rem;overflow-y:auto}._actions_lseur_43{gap:.5rem;display:flex}._panel_1vwpp_1{grid-column:var(--panel-column,span 6);grid-row:var(--panel-row,auto);min-width:0;min-height:0;padding:clamp(.5rem, .8vw, var(--gap));border:1px solid var(--edge);border-radius:var(--radius);background:var(--surface-raised);isolation:isolate;flex-direction:column;justify-content:center;gap:.15em;line-height:1.2;display:flex;position:relative;overflow:hidden;container:panel/inline-size}._content_1vwpp_21{z-index:1;flex-direction:column;flex:0 auto;justify-content:center;gap:.1em;min-width:0;min-height:0;display:flex;position:relative}._content_1vwpp_21>*,._details_1vwpp_33>*{min-width:0;max-width:100%}:is(._content_1vwpp_21:has([data-running-progress=runway]),._content_1vwpp_21:has([data-running-progress=signal-field])){flex:1 1 0}._error_1vwpp_41{border-color:var(--status-serious)}._wide_1vwpp_44{grid-column:span 12}._primary_1vwpp_47{gap:.1em;padding:.65em}._primary_1vwpp_47 ._content_1vwpp_21{gap:.1em}._compact_1vwpp_54{justify-content:flex-start;gap:0;min-height:3.5em;padding:.2em;line-height:1.05}._compact_1vwpp_54 ._content_1vwpp_21{gap:0}._label_1vwpp_64{overflow-wrap:anywhere;color:var(--ink-secondary);margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:1em;font-weight:600}._compact_1vwpp_54 ._label_1vwpp_64{font-size:.8em}._hint_1vwpp_75{color:var(--ink-muted);overflow-wrap:anywhere;margin:0;font-size:.75em}._branch_1vwpp_81{overflow-wrap:anywhere;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}._observed_1vwpp_85{flex-wrap:wrap;align-items:center;gap:.35em;display:flex}._stale_1vwpp_91{color:var(--status-warning)}._status_1vwpp_94{margin:0;font-size:1.35em;font-weight:650}._compact_1vwpp_54 ._status_1vwpp_94{font-size:1.1em}._passed_1vwpp_102{color:var(--status-good)}._failed_1vwpp_105{color:var(--status-critical)}._running_1vwpp_108{color:var(--status-warning)}._cancelled_1vwpp_111,._unknown_1vwpp_112{color:var(--ink-secondary)}._sourceAction_1vwpp_115{z-index:2;width:2em;height:2em;color:var(--ink-secondary);border-radius:.3em;place-items:center;font-size:.85em;font-weight:600;line-height:1;text-decoration:none;display:inline-grid;position:absolute;top:.35em;right:.35em}._sourceAction_1vwpp_115:hover{color:var(--ink-primary);background:color-mix(in srgb, var(--ink-primary) 8%, transparent)}._sourceAction_1vwpp_115:focus-visible{outline:2px solid var(--ink-primary);outline-offset:2px}._primary_1vwpp_47 :is(._hint_1vwpp_75,._observed_1vwpp_85),._compact_1vwpp_54 :is(._hint_1vwpp_75,._observed_1vwpp_85){font-size:.65em}@container panel (width>=48rem){._primary_1vwpp_47._shallow_1vwpp_145{padding:.45em .65em}._primary_1vwpp_47._shallow_1vwpp_145 ._content_1vwpp_21{flex-flow:wrap;align-items:baseline;gap:.15em .7em}._primary_1vwpp_47._shallow_1vwpp_145 ._status_1vwpp_94{flex:none;font-size:1em}._primary_1vwpp_47._shallow_1vwpp_145 :is(._label_1vwpp_64,._observed_1vwpp_85){flex:none}}@container panel (width>=12rem){._compact_1vwpp_54._shallow_1vwpp_145 ._content_1vwpp_21{flex-flow:wrap;align-items:baseline;gap:.15em .7em}._compact_1vwpp_54._shallow_1vwpp_145 :is(._label_1vwpp_64,._observed_1vwpp_85){flex:none}}@container panel (width<=15rem){._panel_1vwpp_1{font-size:.9em}}@container panel (width<=22rem){._panel_1vwpp_1{font-size:.8em}}@media (width<=64rem){._panel_1vwpp_1{grid-area:auto/1/auto/-1;min-height:6em}._primary_1vwpp_47 ._content_1vwpp_21,._compact_1vwpp_54 ._content_1vwpp_21{flex-direction:column;align-items:stretch}}._fact_17pw7_1{display:contents}@container panel (width>=48rem){[data-display=compact][data-shallow=true] ._fact_17pw7_1>*{margin:0}}@container panel (width>=12rem){[data-display=compact][data-shallow=true] ._fact_17pw7_1>*{margin:0}}._variant_1lsfm_1{color:var(--ink-muted);text-transform:capitalize;margin:0;font-size:.72em;transition:color .18s}@media (prefers-reduced-motion:reduce){._variant_1lsfm_1{transition:none}}._field_1x3vm_1{z-index:0;pointer-events:none;contain:layout paint;color:var(--status-warning);position:absolute;inset:0;overflow:hidden}._grid_1x3vm_10{position:absolute;inset:10%}._piece_1x3vm_14{left:calc((var(--piece-x) / var(--shape-columns)) * 100%);top:calc((var(--piece-y) / var(--shape-rows)) * 100%);width:calc((var(--piece-width) / var(--shape-columns)) * 100%);height:calc((var(--piece-height) / var(--shape-rows)) * 100%);transition:left .12s linear,top .12s linear;position:absolute}._field_1x3vm_1[data-recycling=true] ._piece_1x3vm_14{transition:left .5s cubic-bezier(.22,1,.36,1),top .5s cubic-bezier(.22,1,.36,1),opacity .18s}._field_1x3vm_1[data-overdue=true] ._piece_1x3vm_14[data-piece-phase=settled]{opacity:.72;border-color:currentColor}._field_1x3vm_1[data-overdue=true] ._cell_1x3vm_34{background:color-mix(in srgb, currentColor 38%, transparent);box-shadow:0 0 .6em color-mix(in srgb, currentColor 48%, transparent)}._field_1x3vm_1[data-overdue=true] ._clearingCell_1x3vm_38{animation-duration:.9s}._cell_1x3vm_34{left:calc((var(--cell-x) / var(--piece-width)) * 100% + .12em);top:calc((var(--cell-y) / var(--piece-height)) * 100% + .12em);width:calc(100% / var(--piece-width) - .24em);height:calc(100% / var(--piece-height) - .24em);border:1px solid color-mix(in srgb, currentColor 55%, transparent);background:color-mix(in srgb, currentColor 28%, transparent);box-shadow:0 0 .45em color-mix(in srgb, currentColor 35%, transparent);border-radius:.12em;position:absolute}._clearingCell_1x3vm_38{left:calc((var(--clear-x) / var(--shape-columns)) * 100% + .12em);top:calc((var(--clear-y) / var(--shape-rows)) * 100% + .12em);width:calc(100% / var(--shape-columns) - .24em);height:calc(100% / var(--shape-rows) - .24em);border:1px solid color-mix(in srgb, currentColor 55%, transparent);background:color-mix(in srgb, currentColor 28%, transparent);border-radius:.12em;animation:.5s ease-out forwards _clear-cell_1x3vm_1;position:absolute}._piece_1x3vm_14[data-piece-phase=entry]{opacity:.35}._piece_1x3vm_14[data-piece-phase=align]{opacity:.65}._piece_1x3vm_14[data-piece-phase=travel]{opacity:.9}._piece_1x3vm_14[data-piece-phase=settled]{opacity:.5}@media (prefers-reduced-motion:reduce){._piece_1x3vm_14,._field_1x3vm_1[data-recycling=true] ._piece_1x3vm_14{transition:none}._field_1x3vm_1[data-overdue=true] ._clearingCell_1x3vm_38,._clearingCell_1x3vm_38{opacity:0;animation:none}}@keyframes _clear-cell_1x3vm_1{to{opacity:0;transform:scale(.35)}}._frontier_rnw91_1{width:var(--running-progress);background:linear-gradient(90deg, color-mix(in srgb, currentColor 16%, transparent), transparent);border-right:1px solid color-mix(in srgb, currentColor 75%, transparent);position:absolute;inset:0 auto 0 0}._now_rnw91_12{background:color-mix(in srgb, var(--ink-primary) 45%, transparent);width:1px;position:absolute;top:10%;bottom:10%;left:70%}._routes_rnw91_20{align-content:space-between;display:grid;position:absolute;inset:18% 8%}._route_rnw91_20{background:linear-gradient(90deg, transparent, color-mix(in srgb, var(--ink-muted) 45%, transparent), transparent);height:1px}._route_rnw91_20:nth-child(2){transform:translate(8%)}._route_rnw91_20:nth-child(3){transform:translate(-6%)}._trail_rnw91_41,._packet_rnw91_42{border-radius:999px;animation:4.8s ease-in-out infinite alternate _packet_rnw91_42;position:absolute;top:50%;left:-10%}._trail_rnw91_41{opacity:.65;background:linear-gradient(90deg,#0000,currentColor);width:18%;height:2px}._packet_rnw91_42{background:currentColor;width:.48em;height:.48em;box-shadow:0 0 .65em}@container running-field (width<=40rem){._routes_rnw91_20,._trail_rnw91_41,._packet_rnw91_42,._now_rnw91_12{display:none}._frontier_rnw91_1{background:currentColor;border-right:0;width:.28em}}[data-overdue=true] ._frontier_rnw91_1{background:linear-gradient(90deg, color-mix(in srgb, currentColor 28%, transparent), transparent);width:70%}[data-overdue=true] ._packet_rnw91_42{animation:1.8s ease-in-out infinite alternate _packet-stall_rnw91_1;left:70%}[data-overdue=true] ._trail_rnw91_41{width:27%;animation:1.8s ease-in-out infinite alternate _trail-backup_rnw91_1;left:43%}@keyframes _packet_rnw91_42{0%{transform:translate(-10cqw,-50%)}to{transform:translate(120cqw,-50%)}}@keyframes _packet-stall_rnw91_1{0%{opacity:.72;transform:translate(-50%,-50%)scale(.82)}to{opacity:1;transform:translate(-50%,-50%)scale(1.12)}}@keyframes _trail-backup_rnw91_1{0%{opacity:.5;transform:translate(-8%,-50%)}to{opacity:.95;transform:translate(8%,-50%)}}@media (prefers-reduced-motion:reduce){[data-overdue=true] ._trail_rnw91_41,[data-overdue=true] ._packet_rnw91_42,._trail_rnw91_41,._packet_rnw91_42{animation:none}._frontier_rnw91_1{transition:none}}._field_1i9kx_1{z-index:0;pointer-events:none;color:var(--status-warning);position:absolute;inset:0;overflow:hidden;container:running-field/size}._overdue_1i9kx_11{color:var(--status-serious)}._timing_1i9kx_14{width:min(12ch,100%);min-width:0;max-width:100%;color:var(--ink-secondary);font-variant-numeric:tabular-nums;text-align:end;white-space:nowrap;flex:0 12ch;margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.72em;overflow:hidden}._timingOverdue_1i9kx_28{color:var(--status-serious)}._haze_3npie_1{background:radial-gradient(ellipse at 18% 44%, color-mix(in srgb, currentColor 19%, transparent), transparent 42%), radial-gradient(ellipse at 74% 63%, color-mix(in srgb, currentColor 12%, transparent), transparent 38%);animation:15s ease-in-out infinite alternate _haze_3npie_1;position:absolute;inset:-15%}._pressure_3npie_17{display:none}._band_3npie_20{background:linear-gradient(90deg, transparent, color-mix(in srgb, currentColor 32%, transparent), transparent);height:1px;animation:10s ease-in-out infinite alternate _band_3npie_20;position:absolute;left:-15%;right:-15%}._bandOne_3npie_33{top:32%}._bandTwo_3npie_36{animation-delay:-4s;top:67%}._bandThree_3npie_40{opacity:.55;animation-delay:-7s;top:49%}._drift_3npie_45{border:1px solid color-mix(in srgb, currentColor 78%, transparent);width:clamp(.34em,.9cqw,.7em);height:clamp(.34em,.9cqw,.7em);box-shadow:0 0 .55em color-mix(in srgb, currentColor 55%, transparent);border-radius:50%;animation:11s ease-in-out infinite alternate _drift_3npie_45;position:absolute}._driftOne_3npie_54{top:25%;left:12%}._driftTwo_3npie_58{opacity:.6;width:.34em;height:.34em;animation-duration:14s;animation-delay:-4s;top:72%;left:58%}._driftThree_3npie_67{opacity:.55;width:.7em;height:.7em;animation-duration:17s;animation-delay:-9s;top:18%;left:74%}._driftFour_3npie_76{opacity:.75;width:.42em;height:.42em;animation-duration:9s;animation-delay:-2s;top:58%;left:31%}._driftFive_3npie_85{opacity:.45;width:.58em;height:.58em;animation-duration:13s;animation-delay:-6s;top:84%;left:83%}@container running-field (width<=40rem) or (height<=6rem){._drift_3npie_45,._band_3npie_20{display:none}._haze_3npie_1{opacity:.65;width:2.5em;height:2.5em;inset:auto 0 0 auto}}[data-overdue=true] ._haze_3npie_1{background:radial-gradient(ellipse at 22% 48%, color-mix(in srgb, currentColor 34%, transparent), transparent 42%), radial-gradient(ellipse at 78% 58%, color-mix(in srgb, currentColor 25%, transparent), transparent 36%);inset:-30%}[data-overdue=true] ._pressure_3npie_17{border-top:1px solid color-mix(in srgb, currentColor 65%, transparent);border-bottom:1px solid color-mix(in srgb, currentColor 65%, transparent);background:repeating-linear-gradient(180deg, transparent 0 .55em, color-mix(in srgb, currentColor 14%, transparent) .55em .62em);opacity:.75;animation:3.4s ease-in-out infinite alternate _pressure_3npie_17;display:block;position:absolute;inset:20% 0}[data-overdue=true] ._band_3npie_20{background:linear-gradient(90deg,#0000,currentColor,#0000);animation-name:_storm-band_3npie_1}[data-overdue=true] ._drift_3npie_45{transform:translate(12cqw,-2cqh)scale(.82)}@keyframes _haze_3npie_1{to{transform:translate(9%,-4%)}}@keyframes _band_3npie_20{to{opacity:.45;transform:translate(8%)}}@keyframes _drift_3npie_45{to{transform:translate(10cqw,-2cqh)}}@keyframes _pressure_3npie_17{0%{opacity:.45;transform:scaleY(.72)}to{opacity:.9;transform:scaleY(1.12)}}@keyframes _storm-band_3npie_1{to{opacity:.9;transform:translate(-14%)}}@media (prefers-reduced-motion:reduce){[data-overdue=true] ._pressure_3npie_17,._haze_3npie_1,._band_3npie_20,._drift_3npie_45,._pressure_3npie_17{animation:none}}._anchor_1bd86_1{top:50%;left:var(--running-progress);position:absolute}._body_1bd86_6{animation:3.2s ease-in-out infinite alternate _phased-marker_1bd86_1;animation-delay:var(--phased-marker-delay,0s);will-change:transform;position:absolute;inset:0}@keyframes _phased-marker_1bd86_1{0%{transform:translate(var(--phased-marker-travel,-10em), -50%)}to{transform:translate(-50%,-50%)}}@media (prefers-reduced-motion:reduce){._body_1bd86_6{animation:none}}._frontier_2wwhn_1{width:var(--running-progress);background:linear-gradient(90deg, color-mix(in srgb, currentColor 16%, transparent), transparent);border-right:1px solid color-mix(in srgb, currentColor 75%, transparent);position:absolute;inset:0 auto 0 0}._flare_2wwhn_12{display:none}._lanes_2wwhn_15{align-content:space-between;display:grid;position:absolute;inset:13% 7%}._lane_2wwhn_15{background:linear-gradient(90deg, transparent, color-mix(in srgb, var(--edge) 90%, transparent), transparent);height:1px;position:relative}._markerAnchor_2wwhn_31{width:.42em;height:.25em}._markerBody_2wwhn_35{--phased-marker-travel:-10cqw;background:currentColor;border-radius:999px;box-shadow:0 0 .6em}._lane_2wwhn_15:nth-child(2) ._markerBody_2wwhn_35{opacity:.7}._lane_2wwhn_15:nth-child(3) ._markerBody_2wwhn_35{opacity:.5}._lane_2wwhn_15:nth-child(4) ._markerBody_2wwhn_35{opacity:.8}@container running-field (width<=40rem) or (height<=6rem){._lanes_2wwhn_15{display:none}._frontier_2wwhn_1{background:currentColor;border-right:0;width:.28em}}[data-overdue=true] ._frontier_2wwhn_1{background:linear-gradient(90deg, color-mix(in srgb, currentColor 34%, transparent), transparent);border-right-color:currentColor;width:100%}[data-overdue=true] ._flare_2wwhn_12{background:radial-gradient(currentColor 0,#0000 68%);width:2.4em;height:100%;animation:1.6s ease-in-out infinite alternate _bloom-flare_2wwhn_1;display:block;position:absolute;top:0;left:100%;transform:translate(-50%)}[data-overdue=true] ._markerBody_2wwhn_35{--phased-marker-travel:-22.5cqw;animation-duration:.72s;animation-timing-function:ease-in-out}@media (prefers-reduced-motion:reduce){._frontier_2wwhn_1{transition:none}[data-overdue=true] ._flare_2wwhn_12,[data-overdue=true] ._markerBody_2wwhn_35{animation:none}}@keyframes _bloom-flare_2wwhn_1{0%{opacity:.42;transform:translate(-50%)scale(.8)}to{opacity:.95;transform:translate(-50%)scale(1.15)}}._progress_1x79l_1{min-width:0;color:var(--status-warning);align-items:center;gap:.6em;display:flex}._visual_1x79l_8{flex:none;position:relative}._timing_1x79l_12{color:var(--ink-secondary);margin:0;font-size:.72em}._overdue_1x79l_17,._overdue_1x79l_17 ._timing_1x79l_12{color:var(--status-serious)}._readout_1x79l_23{font-variant-numeric:tabular-nums;text-align:end;white-space:nowrap;flex:0 0 12ch;width:12ch;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}._radial_1x79l_31 ._visual_1x79l_8{border:.14em solid var(--edge);background:conic-gradient(var(--status-warning) var(--running-progress), var(--edge) 0);width:2.35em;height:2.35em;box-shadow:inset 0 0 0 .22em var(--surface-raised), 0 0 .55em color-mix(in srgb, var(--status-warning) 45%, transparent);border-radius:50%}._radial_1x79l_31 ._visual_1x79l_8:after{content:"";border-top:.14em solid var(--status-warning);border-radius:50%;animation:1.7s linear infinite _sweep_1x79l_1;position:absolute;inset:-.14em}._overdue_1x79l_17._radial_1x79l_31 ._visual_1x79l_8:before{content:"";border:.1em solid var(--status-serious);box-shadow:0 0 .55em color-mix(in srgb, var(--status-serious) 65%, transparent);border-radius:50%;animation:1.8s ease-in-out infinite _alarm-ring_1x79l_1;position:absolute;inset:-.42em}._radialCore_1x79l_58{background:var(--status-warning);box-shadow:0 0 .45em var(--status-warning);border-radius:50%;position:absolute;inset:.68em}._overdue_1x79l_17 ._radialCore_1x79l_58{background:var(--status-serious);box-shadow:0 0 .55em var(--status-serious);animation:1.8s ease-in-out infinite alternate _reactor-breathe_1x79l_1}._runway_1x79l_70{grid-template-columns:minmax(0,1fr) auto;align-self:stretch;display:grid;container-type:inline-size}._runway_1x79l_70 ._visual_1x79l_8{border:1px solid var(--edge);background:linear-gradient(90deg, var(--status-warning) var(--running-progress), var(--edge) 0);border-radius:999px;width:min(12em,100%);max-width:100%;height:.8em;overflow:hidden}._runway_1x79l_70 ._visual_1x79l_8:after{content:"";top:-.25em;bottom:-.25em;left:calc(var(--running-progress) - .06em);background:var(--ink-primary);width:.12em;box-shadow:0 0 .45em var(--ink-primary);position:absolute}._overdue_1x79l_17._runway_1x79l_70 ._visual_1x79l_8:before{content:"";background:repeating-linear-gradient(-45deg, var(--status-serious) 0 .12em, var(--surface) .12em .24em);width:.55em;box-shadow:0 0 .5em color-mix(in srgb, var(--status-serious) 70%, transparent);animation:1.4s ease-in-out infinite alternate _barrier-pulse_1x79l_1;position:absolute;inset:-.2em 0 -.2em calc(100% - .55em)}._overdue_1x79l_17._runway_1x79l_70 ._visual_1x79l_8:after{background:var(--status-serious);box-shadow:0 0 .55em var(--status-serious);animation:1.4s ease-in-out infinite alternate _barrier-pulse_1x79l_1}._spark_1x79l_114{background:var(--ink-primary);width:.35em;height:.35em;box-shadow:0 0 .4em var(--status-warning);border-radius:50%;animation:1.5s linear infinite _spark_1x79l_114;position:absolute;top:50%;left:-.5em}._overdue_1x79l_17._runway_1x79l_70 ._spark_1x79l_114{animation-duration:1s}._sparkTwo_1x79l_128{animation-delay:-.5s;display:none}._overdue_1x79l_17._runway_1x79l_70 ._sparkTwo_1x79l_128{display:block}._orbit_1x79l_135 ._visual_1x79l_8{border:1px solid var(--edge);border-radius:50%;width:2.4em;height:2.4em}._orbit_1x79l_135 ._visual_1x79l_8:before{content:"";border:.12em solid #0000;border-top-color:var(--status-warning);transform:rotate(var(--running-degrees));border-radius:50%;position:absolute;inset:.18em}._orbitCore_1x79l_151{background:var(--status-warning);box-shadow:0 0 .45em var(--status-warning);border-radius:50%;position:absolute;inset:.75em}._overdue_1x79l_17 ._orbitCore_1x79l_151{background:var(--status-serious);box-shadow:0 0 .55em var(--status-serious);animation:1.15s ease-in-out infinite alternate _reactor-breathe_1x79l_1}._particle_1x79l_163{background:var(--ink-primary);transform-origin:.16em .95em;border-radius:50%;width:.32em;height:.32em;animation:1.8s linear infinite _orbit_1x79l_135;position:absolute;top:.25em;left:calc(50% - .16em)}._particleTwo_1x79l_174{background:var(--status-warning);animation-delay:-.9s}._overdue_1x79l_17._orbit_1x79l_135 ._visual_1x79l_8:after{content:"";border:.08em solid color-mix(in srgb, var(--status-serious) 75%, transparent);box-shadow:0 0 .6em color-mix(in srgb, var(--status-serious) 55%, transparent);border-radius:50%;animation:1.15s ease-in-out infinite alternate _gravity-well_1x79l_1;position:absolute;inset:.42em}._overdue_1x79l_17._orbit_1x79l_135 ._particle_1x79l_163{transform-origin:.16em .7em;animation-duration:.95s}._indeterminate_1x79l_191 ._visual_1x79l_8{background-image:repeating-linear-gradient(135deg, color-mix(in srgb, var(--status-warning) 70%, transparent) 0 .25em, var(--edge) .25em .5em);animation:1s linear infinite _shift_1x79l_1}._signalField_1x79l_199{flex:auto;grid-template-columns:minmax(0,1fr) auto;align-self:stretch;min-height:0;max-height:100%;display:grid;container-type:size}._signalField_1x79l_199 ._visual_1x79l_8{border:1px solid var(--edge);background:var(--surface);border-radius:999px;width:auto;height:1em;max-height:100%;overflow:hidden}._rail_1x79l_217{background:linear-gradient(90deg, var(--status-warning) var(--running-progress), var(--edge) 0);opacity:.75;position:absolute;inset:0}._lead_1x79l_223{top:-.2em;bottom:-.2em;left:calc(var(--running-progress) - .08em);background:var(--ink-primary);width:.16em;box-shadow:0 0 .5em var(--status-warning);border-radius:999px;position:absolute}._pulse_1x79l_233{background:var(--ink-primary);width:.3em;height:.3em;box-shadow:0 0 .4em var(--status-warning);border-radius:50%;animation:2.4s ease-in-out infinite alternate _pulse_1x79l_233;position:absolute;top:50%;left:-.5em}._pulseTwo_1x79l_244{animation-delay:-1.2s}._tracks_1x79l_247{display:none}@container panel (width>=26rem){._runway_1x79l_70 ._visual_1x79l_8{width:auto;height:clamp(1.1em,7cqw,2.7em);box-shadow:inset 0 0 1em color-mix(in srgb, var(--status-warning) 16%, transparent);flex:auto}._runway_1x79l_70 ._visual_1x79l_8:after{left:calc(var(--running-progress) - .08em);width:.16em}._spark_1x79l_114{animation-name:_sparkWide_1x79l_1}}@container panel (width<=18rem){._signalField_1x79l_199{flex:0 auto;min-height:0}._signalField_1x79l_199 ._visual_1x79l_8{width:2.65em;height:1.15em}._signalField_1x79l_199 ._rail_1x79l_217{background:var(--edge)}._signalField_1x79l_199 ._lead_1x79l_223{border-radius:50%;width:.38em;top:.2em;bottom:.2em}._pulse_1x79l_233{display:none}}@container panel (height<=5rem){._signalField_1x79l_199{flex:0 auto;min-height:0}._signalField_1x79l_199 ._visual_1x79l_8{width:2.65em;height:1.15em}._signalField_1x79l_199 ._rail_1x79l_217{background:var(--edge)}._signalField_1x79l_199 ._lead_1x79l_223{border-radius:50%;width:.38em;top:.2em;bottom:.2em}._pulse_1x79l_233{display:none}}@container panel (width>=26rem){._signalField_1x79l_199 ._visual_1x79l_8{background:linear-gradient(180deg, color-mix(in srgb, var(--edge) 60%, transparent), transparent);border-radius:.25em;height:100%;min-height:0}._signalField_1x79l_199 ._visual_1x79l_8:before{content:"";width:var(--running-progress);background:repeating-linear-gradient(0deg, transparent 0 .55em, color-mix(in srgb, var(--status-warning) 16%, transparent) .55em .6em), linear-gradient(90deg, color-mix(in srgb, var(--status-warning) 19%, transparent), color-mix(in srgb, var(--status-warning) 7%, transparent));box-shadow:inset -.8em 0 1em color-mix(in srgb, var(--status-warning) 22%, transparent);position:absolute;inset:0 auto 0 0}._signalField_1x79l_199 ._rail_1x79l_217{height:1px;top:50%;bottom:auto}._signalField_1x79l_199 ._lead_1x79l_223{height:.9em;top:calc(50% - .45em);bottom:auto}._pulse_1x79l_233{display:none}._tracks_1x79l_247{flex-direction:column;justify-content:space-between;display:flex;position:absolute;inset:.8em 0}._track_1x79l_247{background:linear-gradient(90deg, transparent, color-mix(in srgb, var(--edge) 85%, transparent), transparent);height:1px;position:relative}._markerAnchor_1x79l_371{width:.38em;height:.22em}._markerBody_1x79l_375{background:var(--status-warning);box-shadow:0 0 .4em var(--status-warning);border-radius:.06em}._track_1x79l_247:nth-child(2) ._markerBody_1x79l_375{opacity:.7;animation-delay:-.8s}._track_1x79l_247:nth-child(3) ._markerBody_1x79l_375{opacity:.45;animation-delay:-1.7s}._track_1x79l_247:nth-child(4) ._markerBody_1x79l_375{opacity:.7;animation-delay:-2.4s}._track_1x79l_247:nth-child(5) ._markerBody_1x79l_375{opacity:.55;animation-delay:-.35s}}._overdue_1x79l_17._signalField_1x79l_199 ._rail_1x79l_217{background:linear-gradient(90deg, var(--status-serious) 0 100%);opacity:.42}._overdue_1x79l_17._signalField_1x79l_199 ._lead_1x79l_223{background:var(--status-serious);box-shadow:0 0 .7em var(--status-serious);animation:1.2s ease-in-out infinite alternate _endpoint-pulse_1x79l_1}._overdue_1x79l_17._signalField_1x79l_199 ._markerBody_1x79l_375{--phased-marker-travel:-10em;background:var(--status-serious);box-shadow:0 0 .55em var(--status-serious);animation-duration:.68s;animation-timing-function:ease-in-out}._short_1x79l_413 ._signalField_1x79l_199 ._visual_1x79l_8{height:1em}@keyframes _sweep_1x79l_1{to{transform:rotate(360deg)}}@keyframes _alarm-ring_1x79l_1{0%{opacity:.45;transform:scale(.92)}to{opacity:1;transform:scale(1.08)}}@keyframes _reactor-breathe_1x79l_1{0%{opacity:.7;transform:scale(.84)}to{opacity:1;transform:scale(1.12)}}@keyframes _barrier-pulse_1x79l_1{0%{opacity:.55}to{opacity:1}}@keyframes _gravity-well_1x79l_1{0%{opacity:.45;transform:scale(.82)}to{opacity:.95;transform:scale(1.08)}}@keyframes _endpoint-pulse_1x79l_1{0%{opacity:.65;transform:scaleY(.75)}to{opacity:1;transform:scaleY(1.15)}}@keyframes _spark_1x79l_114{to{transform:translate(13em)}}@keyframes _sparkWide_1x79l_1{to{transform:translate(100cqw)}}@keyframes _orbit_1x79l_135{to{transform:rotate(360deg)}}@keyframes _shift_1x79l_1{to{background-position:1em 0}}@keyframes _pulse_1x79l_233{0%{transform:translate(-.5em,-50%)}to{transform:translate(calc(var(--running-progress) + .5em), -50%)}}@media (prefers-reduced-motion:reduce){._radial_1x79l_31 ._visual_1x79l_8:after,._overdue_1x79l_17._radial_1x79l_31 ._visual_1x79l_8:before,._overdue_1x79l_17 ._radialCore_1x79l_58,._spark_1x79l_114,._runway_1x79l_70 ._visual_1x79l_8:after,._overdue_1x79l_17._runway_1x79l_70 ._visual_1x79l_8:before,._overdue_1x79l_17._runway_1x79l_70 ._visual_1x79l_8:after,._particle_1x79l_163,._overdue_1x79l_17._orbit_1x79l_135 ._visual_1x79l_8:after,._pulse_1x79l_233,._lead_1x79l_223,._overdue_1x79l_17._signalField_1x79l_199 ._lead_1x79l_223,._overdue_1x79l_17._signalField_1x79l_199 ._markerBody_1x79l_375,._signalField_1x79l_199 ._visual_1x79l_8:before,._indeterminate_1x79l_191 ._visual_1x79l_8{animation:none}}._details_1isu9_1{display:contents}@container panel (width>=48rem){[data-display=primary][data-shallow=true] ._details_1isu9_1>*{margin:0}}._error_yx1g9_1{max-width:60ch;color:var(--ink-primary);margin:0 auto;padding:2rem}._error_yx1g9_1 pre{border-radius:var(--radius);border:1px solid var(--status-critical);background:var(--surface-raised);color:var(--ink-secondary);white-space:pre-wrap;overflow-wrap:anywhere;padding:1rem;font-size:.75em}:root{--surface:#12140f;--surface-raised:#1a1a19;--ink-primary:#fff;--ink-secondary:#c3c2b7;--ink-muted:#898781;--edge:#2f312b;--status-good:#0ca30c;--status-warning:#fab219;--status-serious:#ec835a;--status-critical:#d03b3b;--gap:1rem;--radius:.5rem;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*{box-sizing:border-box}html,body{height:100%;margin:0}body{background:var(--surface);color:var(--ink-primary);font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Helvetica,Arial,sans-serif;font-size:clamp(16px,1.1vw + .5rem,28px);line-height:1.4;overflow-x:hidden}.screen-reader-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}
package/client/index.html CHANGED
@@ -11,8 +11,8 @@
11
11
  <title>Trust Dashboard</title>
12
12
 
13
13
  <script type="importmap">{"imports":{"react":"https://esm.sh/react@19.2.8","react/":"https://esm.sh/react@19.2.8/","react-dom":"https://esm.sh/react-dom@19.2.8","react-dom/":"https://esm.sh/react-dom@19.2.8/","scheduler":"https://esm.sh/scheduler@0.27.0","scheduler/":"https://esm.sh/scheduler@0.27.0/","zod":"https://esm.sh/zod@4.4.3","zod/":"https://esm.sh/zod@4.4.3/"}}</script>
14
- <script type="module" crossorigin src="/__ASSET_PATH__/assets/index-B1CYozDH.js"></script>
15
- <link rel="stylesheet" crossorigin href="/__ASSET_PATH__/assets/index-BVFmOmLK.css">
14
+ <script type="module" crossorigin src="/__ASSET_PATH__/assets/index-1YsIVWxe.js"></script>
15
+ <link rel="stylesheet" crossorigin href="/__ASSET_PATH__/assets/index-BRONWQIP.css">
16
16
  </head>
17
17
  <body>
18
18
  <div id="root"></div>
@@ -1,4 +1,5 @@
1
1
  import { type BootstrapConfig, type BootstrapConsistency, type BootstrapKind } from './bootstrap.js';
2
+ import { type BootstrapRemediation } from './remediation.js';
2
3
  export type BootstrapResourceDifference = {
3
4
  path?: string;
4
5
  differenceType?: string;
@@ -32,6 +33,7 @@ export type BootstrapCheck = {
32
33
  ok: boolean;
33
34
  packageVersion: string;
34
35
  stacks: BootstrapStackCheck[];
36
+ remediation: BootstrapRemediation;
35
37
  };
36
38
  export type BootstrapCheckDependencies = {
37
39
  execute(command: string, args: string[]): Promise<string>;
@@ -1,4 +1,5 @@
1
1
  import { type ComputeMode } from './compute-mode.js';
2
+ import { type BootstrapRemediation } from './remediation.js';
2
3
  export { type ComputeMode, computeMode, resolveComputeMode } from './compute-mode.js';
3
4
  export type BootstrapKind = 'core' | 'github-oidc';
4
5
  export type CloudFormationParameterValue = {
@@ -55,6 +56,7 @@ export type BootstrapPlan = {
55
56
  packageTemplates: BootstrapTemplateInspection[];
56
57
  configuration: BootstrapConfig;
57
58
  notes: string[];
59
+ remediation: BootstrapRemediation;
58
60
  };
59
61
  export type BootstrapConsistency = {
60
62
  ok: boolean;
package/dist/cli.js CHANGED
@@ -159,6 +159,46 @@ function sha256(value2) {
159
159
  return createHash("sha256").update(value2).digest("hex");
160
160
  }
161
161
 
162
+ // packages/aws/src/remediation.ts
163
+ var safetyNote = "AWS mutations are emitted for explicit administrator review and invocation; this library never executes them.";
164
+ function bootstrapRemediation(config, input = {}) {
165
+ const affectedStacks = input.affectedStacks ?? [
166
+ ["core", config.core?.stackName],
167
+ ["github-oidc", config.githubOidc?.stackName]
168
+ ].filter((entry) => Boolean(entry[1])).map(([kind, stackName2]) => ({ kind, stackName: stackName2 }));
169
+ const configPath = input.configPath ?? "manifest.json";
170
+ const checkCommand = `ze-great-dashboard-aws bootstrap check --config ${configPath} --format json`;
171
+ const issues = input.issues ?? [];
172
+ const summary = input.summary ?? (issues.length ? `Bootstrap validation found ${issues.length} issue${issues.length === 1 ? "" : "s"}.` : "Bootstrap validation is ready for the next reviewed operation.");
173
+ return {
174
+ failureSummary: summary,
175
+ affectedStacks,
176
+ immediateSteps: [
177
+ ...issues.length ? ["Review each reported mismatch, access error, or drift finding."] : [],
178
+ input.nextOperation ?? "Run the next bootstrap operation from the generated handoff.",
179
+ "Capture the resulting CloudFormation stack output for the next validation step."
180
+ ],
181
+ upgradeSteps: [
182
+ "If the contract or template revision is stale, generate parameters from this installed package and create a reviewed UPDATE change set for each affected stack.",
183
+ "Review IAM actions, retained resources, parameters, and the change set before an administrator executes it."
184
+ ],
185
+ revalidateCommand: checkCommand,
186
+ safetyNote
187
+ };
188
+ }
189
+ function formatBootstrapRemediationText(remediation) {
190
+ return [
191
+ `Remediation: ${remediation.failureSummary}`,
192
+ `Affected stacks: ${remediation.affectedStacks.length ? remediation.affectedStacks.map(({ kind, stackName: stackName2, issue }) => `${kind}=${stackName2}${issue ? ` (${issue})` : ""}`).join(", ") : "none identified"}`,
193
+ "Immediate steps:",
194
+ ...remediation.immediateSteps.map((step, index) => ` ${index + 1}. ${step}`),
195
+ "Upgrade steps:",
196
+ ...remediation.upgradeSteps.map((step, index) => ` ${index + 1}. ${step}`),
197
+ `Revalidate: ${remediation.revalidateCommand}`,
198
+ `Safety: ${remediation.safetyNote}`
199
+ ];
200
+ }
201
+
162
202
  // packages/aws/src/bootstrap.ts
163
203
  var templates = {
164
204
  core: {
@@ -231,7 +271,10 @@ async function bootstrapPlan(config) {
231
271
  "Templates are owned by the installed npm package; package.json and package-lock.json pin the source version.",
232
272
  "Generated CloudFormation parameter files and describe-stacks captures are deployment artifacts, not source configuration.",
233
273
  "This plan performs no AWS or GitHub mutations."
234
- ]
274
+ ],
275
+ remediation: bootstrapRemediation(config, {
276
+ nextOperation: "Review the installed templates, then run bootstrap preflight before creating a change set."
277
+ })
235
278
  };
236
279
  }
237
280
  function capturedStack(input) {
@@ -1118,6 +1161,7 @@ function formatBootstrapCheckText(result) {
1118
1161
  );
1119
1162
  }
1120
1163
  }
1164
+ lines.push("", ...formatBootstrapRemediationText(result.remediation));
1121
1165
  return `${lines.join("\n")}
1122
1166
  `;
1123
1167
  }
@@ -1337,12 +1381,30 @@ async function checkBootstrap(config, options, dependencies) {
1337
1381
  return checked;
1338
1382
  })
1339
1383
  );
1384
+ const failed = stacks.filter(
1385
+ ({ consistency, resourceDrift: resourceDrift2 }) => !consistency.ok || Boolean(resourceDrift2 && !resourceDrift2.ok)
1386
+ );
1340
1387
  return {
1341
1388
  ok: stacks.every(
1342
1389
  ({ consistency, resourceDrift: drift }) => consistency.ok && (!drift || drift.ok)
1343
1390
  ),
1344
1391
  packageVersion: plan.packageVersion,
1345
- stacks
1392
+ stacks,
1393
+ remediation: bootstrapRemediation(config, {
1394
+ summary: failed.length ? `Bootstrap validation failed for ${failed.length} stack${failed.length === 1 ? "" : "s"}.` : "Bootstrap stacks are consistent and ready for the deployment check.",
1395
+ affectedStacks: (failed.length ? failed : stacks).map(
1396
+ ({ kind, stackName: stackName2, consistency, resourceDrift: resourceDrift2 }) => ({
1397
+ kind,
1398
+ stackName: stackName2,
1399
+ ...!consistency.ok ? { issue: consistency.mismatches[0] ?? "consistency mismatch" } : resourceDrift2 && !resourceDrift2.ok ? { issue: `resource drift: ${resourceDrift2.status}` } : {}
1400
+ })
1401
+ ),
1402
+ nextOperation: failed.length ? "Apply only reviewed administrator-approved bootstrap updates, then capture both stacks again." : "Run the deployment or release check that consumes these bootstrap outputs.",
1403
+ issues: failed.flatMap(({ consistency, resourceDrift: resourceDrift2 }) => [
1404
+ ...consistency.mismatches,
1405
+ ...resourceDrift2 && !resourceDrift2.ok ? [`resource drift: ${resourceDrift2.status}`] : []
1406
+ ])
1407
+ })
1346
1408
  };
1347
1409
  }
1348
1410
 
@@ -1559,6 +1621,10 @@ async function bootstrapHandoff(input) {
1559
1621
  templatePath,
1560
1622
  parameterPath: workFile(input.workDir, "core-bootstrap.json"),
1561
1623
  workDir: input.workDir
1624
+ }),
1625
+ remediation: bootstrapRemediation(input.config, {
1626
+ configPath: input.configPath,
1627
+ nextOperation: "Review and execute the core bootstrap change set, then capture the core stack."
1562
1628
  })
1563
1629
  };
1564
1630
  }
@@ -1602,7 +1668,11 @@ async function bootstrapHandoff(input) {
1602
1668
  prerequisite: await (input.provider ?? githubOidcProvider).prerequisite(
1603
1669
  input.config,
1604
1670
  input.runner
1605
- )
1671
+ ),
1672
+ remediation: bootstrapRemediation(input.config, {
1673
+ configPath: input.configPath,
1674
+ nextOperation: "Review and execute the GitHub OIDC change set, then capture the GitHub OIDC stack."
1675
+ })
1606
1676
  };
1607
1677
  }
1608
1678
  const prerequisite = await (input.provider ?? githubOidcProvider).prerequisite(
@@ -1620,7 +1690,12 @@ async function bootstrapHandoff(input) {
1620
1690
  "A GitHub administrator must complete and verify the immutable-subject migration before deployments."
1621
1691
  ],
1622
1692
  commands: [],
1623
- prerequisite
1693
+ prerequisite,
1694
+ remediation: bootstrapRemediation(input.config, {
1695
+ configPath: input.configPath,
1696
+ summary: "The GitHub Environment immutable-subject prerequisite is not verified.",
1697
+ nextOperation: "A GitHub administrator must complete and verify the immutable-subject migration, then rerun bootstrap handoff."
1698
+ })
1624
1699
  };
1625
1700
  return {
1626
1701
  phase: "application-gateway",
@@ -1631,7 +1706,11 @@ async function bootstrapHandoff(input) {
1631
1706
  "Consumer owns gateway selection, private Lambda permission, authentication, and smoke tests."
1632
1707
  ],
1633
1708
  commands: [],
1634
- prerequisite
1709
+ prerequisite,
1710
+ remediation: bootstrapRemediation(input.config, {
1711
+ configPath: input.configPath,
1712
+ nextOperation: "Configure and verify the consumer gateway, then run bootstrap verify and the deployment check."
1713
+ })
1635
1714
  };
1636
1715
  }
1637
1716
  function assertEqual(actual, expected, label) {
@@ -1751,7 +1830,10 @@ async function verifyBootstrap(input) {
1751
1830
  "--body",
1752
1831
  executionRole
1753
1832
  ]
1754
- ]
1833
+ ],
1834
+ remediation: bootstrapRemediation(input.config, {
1835
+ nextOperation: "Set the reviewed GitHub Environment variables, then run bootstrap check before deployment."
1836
+ })
1755
1837
  };
1756
1838
  }
1757
1839
 
@@ -1869,7 +1951,16 @@ async function bootstrapPreflight(input) {
1869
1951
  checks.push(
1870
1952
  missing.length ? { name: "manifest", status: "missing", detail: `Missing: ${missing.join(", ")}` } : { name: "manifest", status: "ready", detail: "Manifest has all bootstrap fields." }
1871
1953
  );
1872
- if (missing.length) return { ready: false, checks };
1954
+ if (missing.length)
1955
+ return {
1956
+ ready: false,
1957
+ checks,
1958
+ remediation: bootstrapRemediation(input.config, {
1959
+ summary: "Bootstrap manifest configuration is incomplete.",
1960
+ issues: missing,
1961
+ nextOperation: "Complete the missing manifest fields, then rerun bootstrap preflight."
1962
+ })
1963
+ };
1873
1964
  const runner = input.runner;
1874
1965
  const identityRaw = await optional(runner, "aws", [
1875
1966
  "sts",
@@ -1977,9 +2068,15 @@ async function bootstrapPreflight(input) {
1977
2068
  status: subject.status === "immutable-subject-required" ? "mismatch" : subject.status,
1978
2069
  detail: subject.detail
1979
2070
  });
2071
+ const ready = !checks.some(({ status }) => status === "missing" || status === "mismatch");
1980
2072
  return {
1981
- ready: !checks.some(({ status }) => status === "missing" || status === "mismatch"),
1982
- checks
2073
+ ready,
2074
+ checks,
2075
+ remediation: bootstrapRemediation(input.config, {
2076
+ summary: ready ? "Bootstrap preflight is ready." : "Bootstrap preflight found configuration or identity issues.",
2077
+ issues: checks.filter(({ status }) => status === "missing" || status === "mismatch").map(({ detail }) => detail),
2078
+ nextOperation: ready ? "Run bootstrap plan, then create and review the next bootstrap change set." : "Resolve the reported configuration or identity issues, then rerun bootstrap preflight."
2079
+ })
1983
2080
  };
1984
2081
  }
1985
2082
  function quote(args2) {
@@ -2024,6 +2121,7 @@ async function bootstrapGuide(input) {
2024
2121
  );
2025
2122
  for (const command of verified.githubEnvironmentInstructions) lines.push(quote(command));
2026
2123
  }
2124
+ lines.push("", ...formatBootstrapRemediationText(plan.remediation));
2027
2125
  return `${lines.join("\n")}
2028
2126
  `;
2029
2127
  }
@@ -2357,7 +2455,15 @@ async function runDoctor(options, dependencies = actualDependencies) {
2357
2455
  checkResult.detail = `WARNING: ${checkResult.detail}`;
2358
2456
  }
2359
2457
  }
2360
- return checks;
2458
+ const remediation = bootstrapRemediation(
2459
+ {},
2460
+ {
2461
+ summary: checks.some(({ ok }) => !ok) ? "Deployment doctor found issues that require operator review." : "Deployment doctor is healthy; proceed to the deployment check.",
2462
+ issues: checks.filter(({ ok }) => !ok).map(({ detail }) => detail),
2463
+ nextOperation: checks.some(({ ok }) => !ok) ? "Resolve failed checks, then rerun the deployment doctor and bootstrap check." : "Run bootstrap check before deploying the release."
2464
+ }
2465
+ );
2466
+ return checks.map((check2) => ({ ...check2, remediation }));
2361
2467
  }
2362
2468
 
2363
2469
  // packages/aws/src/cli.ts
@@ -2451,6 +2557,20 @@ function bootstrapStackName(kind, config) {
2451
2557
  function shellCommand(command) {
2452
2558
  return command.map((argument) => `'${argument.replaceAll("'", `'\\"'\\"'`)}'`).join(" ");
2453
2559
  }
2560
+ function outputFormat(defaultFormat = "json") {
2561
+ if (args.includes("--format-shell")) return "shell";
2562
+ const format = option("--format", defaultFormat);
2563
+ if (format !== "json" && format !== "text") throw new Error("--format must be json or text");
2564
+ return format;
2565
+ }
2566
+ function printBootstrap(value2, text, shell, defaultFormat = "json") {
2567
+ const format = outputFormat(defaultFormat);
2568
+ if (format === "shell") {
2569
+ if (!shell) throw new Error("--format-shell is only supported for command handoffs");
2570
+ console.log(shell);
2571
+ } else if (format === "text") console.log(text);
2572
+ else console.log(JSON.stringify(value2));
2573
+ }
2454
2574
  async function templateParameters(mode = "lambda") {
2455
2575
  const template = await cloudFormationTemplate(mode);
2456
2576
  const block = template.match(/^Parameters:\n[\s\S]*?(?=^[A-Za-z][A-Za-z0-9]*:\s*$)/m)?.[0];
@@ -2586,10 +2706,14 @@ try {
2586
2706
  packageVersion
2587
2707
  }
2588
2708
  );
2589
- for (const check of checks)
2590
- console.log(
2591
- `${check.warning ? "WARN" : check.ok ? "PASS" : "FAIL"} ${check.name}: ${check.detail}`
2592
- );
2709
+ const remediation = checks[0]?.remediation;
2710
+ if (outputFormat("text") === "text") {
2711
+ for (const check of checks)
2712
+ console.log(
2713
+ `${check.warning ? "WARN" : check.ok ? "PASS" : "FAIL"} ${check.name}: ${check.detail}`
2714
+ );
2715
+ if (remediation) console.log(formatBootstrapRemediationText(remediation).join("\n"));
2716
+ } else console.log(JSON.stringify({ checks, remediation }));
2593
2717
  if (checks.some(({ ok }) => !ok)) process.exitCode = 1;
2594
2718
  } else if (args[0] === "parameters") {
2595
2719
  const output = option("--output", "aws-dashboard-parameters.json") ?? "aws-dashboard-parameters.json";
@@ -2636,7 +2760,7 @@ try {
2636
2760
  });
2637
2761
  await writeFile3(output, `${JSON.stringify(parameters, null, 2)}
2638
2762
  `);
2639
- console.log(JSON.stringify({ output }));
2763
+ printBootstrap({ output }, `Wrote ${output}. Next: run the generated deployment handoff.`);
2640
2764
  } else if (args[0] === "bootstrap") {
2641
2765
  const action = args[1];
2642
2766
  if (action === "init") {
@@ -2670,7 +2794,10 @@ try {
2670
2794
  });
2671
2795
  await writeFile3(output, `${JSON.stringify(manifest, null, 2)}
2672
2796
  `, { flag: "wx" });
2673
- console.log(JSON.stringify({ output, manifest }));
2797
+ printBootstrap(
2798
+ { output, manifest, remediation: (await bootstrapPlan(manifest)).remediation },
2799
+ `Wrote ${output}. Next: run bootstrap preflight, then bootstrap handoff.`
2800
+ );
2674
2801
  } else {
2675
2802
  const config = await bootstrapConfig();
2676
2803
  if (action === "preflight") {
@@ -2692,10 +2819,16 @@ try {
2692
2819
  }
2693
2820
  };
2694
2821
  const result = await bootstrapPreflight({ config, runner });
2695
- if (option("--format") === "text")
2696
- for (const check of result.checks)
2697
- console.log(`${check.status.toUpperCase()} ${check.name}: ${check.detail}`);
2698
- else console.log(JSON.stringify(result));
2822
+ printBootstrap(
2823
+ result,
2824
+ [
2825
+ ...result.checks.map(
2826
+ (check) => `${check.status.toUpperCase()} ${check.name}: ${check.detail}`
2827
+ ),
2828
+ "",
2829
+ ...formatBootstrapRemediationText(result.remediation)
2830
+ ].join("\n")
2831
+ );
2699
2832
  if (!result.ready) process.exitCode = 1;
2700
2833
  } else if (action === "guide") {
2701
2834
  const configPath = requiredOption("--config");
@@ -2708,17 +2841,31 @@ try {
2708
2841
  return (await promisify3(execFile3)(command, commandArgs)).stdout.trim();
2709
2842
  }
2710
2843
  };
2711
- process.stdout.write(
2712
- await bootstrapGuide({
2713
- config,
2714
- configPath,
2715
- workDir: option("--work-dir"),
2716
- coreStack: coreStackPath ? JSON.parse(await readFile5(coreStackPath, "utf8")) : void 0,
2717
- coreStackPath,
2718
- githubOidcStack: githubStackPath ? JSON.parse(await readFile5(githubStackPath, "utf8")) : void 0,
2719
- githubOidcStackPath: githubStackPath,
2720
- runner
2721
- })
2844
+ const handoff = await bootstrapHandoff({
2845
+ config,
2846
+ configPath,
2847
+ workDir: option("--work-dir"),
2848
+ coreStack: coreStackPath ? JSON.parse(await readFile5(coreStackPath, "utf8")) : void 0,
2849
+ coreStackPath,
2850
+ githubOidcStack: githubStackPath ? JSON.parse(await readFile5(githubStackPath, "utf8")) : void 0,
2851
+ githubOidcStackPath: githubStackPath,
2852
+ runner
2853
+ });
2854
+ const guide = await bootstrapGuide({
2855
+ config,
2856
+ configPath,
2857
+ workDir: option("--work-dir"),
2858
+ coreStack: coreStackPath ? JSON.parse(await readFile5(coreStackPath, "utf8")) : void 0,
2859
+ coreStackPath,
2860
+ githubOidcStack: githubStackPath ? JSON.parse(await readFile5(githubStackPath, "utf8")) : void 0,
2861
+ githubOidcStackPath: githubStackPath,
2862
+ runner
2863
+ });
2864
+ printBootstrap(
2865
+ { handoff, guide, remediation: handoff.remediation },
2866
+ guide,
2867
+ void 0,
2868
+ "text"
2722
2869
  );
2723
2870
  } else if (action === "handoff") {
2724
2871
  const configPath = requiredOption("--config");
@@ -2731,48 +2878,57 @@ try {
2731
2878
  return (await promisify3(execFile3)(command, commandArgs)).stdout.trim();
2732
2879
  }
2733
2880
  };
2734
- console.log(
2735
- JSON.stringify(
2736
- await bootstrapHandoff({
2737
- config,
2738
- configPath,
2739
- workDir: option("--work-dir"),
2740
- coreStack: coreStackPath ? JSON.parse(await readFile5(coreStackPath, "utf8")) : void 0,
2741
- coreStackPath,
2742
- githubOidcStack: githubStackPath ? JSON.parse(await readFile5(githubStackPath, "utf8")) : void 0,
2743
- githubOidcStackPath: githubStackPath,
2744
- runner
2745
- })
2746
- )
2881
+ const handoff = await bootstrapHandoff({
2882
+ config,
2883
+ configPath,
2884
+ workDir: option("--work-dir"),
2885
+ coreStack: coreStackPath ? JSON.parse(await readFile5(coreStackPath, "utf8")) : void 0,
2886
+ coreStackPath,
2887
+ githubOidcStack: githubStackPath ? JSON.parse(await readFile5(githubStackPath, "utf8")) : void 0,
2888
+ githubOidcStackPath: githubStackPath,
2889
+ runner
2890
+ });
2891
+ printBootstrap(
2892
+ handoff,
2893
+ `${JSON.stringify(handoff, null, 2)}
2894
+ ${formatBootstrapRemediationText(handoff.remediation).join("\n")}`
2747
2895
  );
2748
2896
  } else if (action === "verify") {
2749
2897
  requiredOption("--config");
2750
2898
  const coreStackPath = requiredOption("--core-stack-json");
2751
2899
  const githubStackPath = requiredOption("--github-oidc-stack-json");
2752
- console.log(
2753
- JSON.stringify(
2754
- await verifyBootstrap({
2755
- config,
2756
- coreStack: JSON.parse(await readFile5(coreStackPath, "utf8")),
2757
- githubOidcStack: JSON.parse(await readFile5(githubStackPath, "utf8"))
2758
- })
2759
- )
2900
+ const verified = await verifyBootstrap({
2901
+ config,
2902
+ coreStack: JSON.parse(await readFile5(coreStackPath, "utf8")),
2903
+ githubOidcStack: JSON.parse(await readFile5(githubStackPath, "utf8"))
2904
+ });
2905
+ printBootstrap(
2906
+ verified,
2907
+ `Bootstrap verified.
2908
+ ${formatBootstrapRemediationText(verified.remediation).join("\n")}`
2760
2909
  );
2761
2910
  } else if (action === "template") {
2762
2911
  const kind = bootstrapKind();
2763
2912
  const mode = requireComputeMode(config, option("--mode"));
2764
- console.log(
2765
- JSON.stringify({
2766
- kind,
2767
- mode,
2768
- template: await bootstrapTemplatePath(kind, mode),
2769
- contractVersion: bootstrapContractVersion(await bootstrapTemplate(kind, mode))
2913
+ const template = {
2914
+ kind,
2915
+ mode,
2916
+ template: await bootstrapTemplatePath(kind, mode),
2917
+ contractVersion: bootstrapContractVersion(await bootstrapTemplate(kind, mode)),
2918
+ remediation: bootstrapRemediation(config, {
2919
+ nextOperation: `Review the ${kind} template, then run bootstrap parameters and create a reviewed change set.`
2770
2920
  })
2921
+ };
2922
+ printBootstrap(
2923
+ template,
2924
+ `Template: ${template.template}
2925
+ Contract: ${template.contractVersion}
2926
+ ${formatBootstrapRemediationText(template.remediation).join("\n")}`
2771
2927
  );
2772
2928
  } else if (action === "plan") {
2773
2929
  requiredOption("--config");
2774
2930
  const plan = await bootstrapPlan(config);
2775
- if (option("--format") === "text") {
2931
+ if (outputFormat() === "text") {
2776
2932
  console.log("AWS bootstrap plan (read-only)");
2777
2933
  console.log(`Package version: ${plan.packageVersion}`);
2778
2934
  for (const template of plan.packageTemplates) {
@@ -2788,6 +2944,7 @@ ${template.kind}: ${template.path}`);
2788
2944
  }
2789
2945
  console.log(`
2790
2946
  ${plan.notes.join("\n")}`);
2947
+ console.log(formatBootstrapRemediationText(plan.remediation).join("\n"));
2791
2948
  } else console.log(JSON.stringify(plan));
2792
2949
  } else if (action === "check") {
2793
2950
  requiredOption("--config");
@@ -2802,7 +2959,7 @@ ${plan.notes.join("\n")}`);
2802
2959
  }
2803
2960
  }
2804
2961
  );
2805
- if (option("--format") === "text") process.stdout.write(formatBootstrapCheckText(result));
2962
+ if (outputFormat() === "text") process.stdout.write(formatBootstrapCheckText(result));
2806
2963
  else console.log(JSON.stringify(result));
2807
2964
  if (!result.ok) process.exitCode = 1;
2808
2965
  } else if (action === "parameters") {
@@ -2840,8 +2997,15 @@ ${plan.notes.join("\n")}`);
2840
2997
  }
2841
2998
  await writeFile3(output, `${JSON.stringify(parameters, null, 2)}
2842
2999
  `);
2843
- console.log(
2844
- JSON.stringify({ output, kind, preservedDeployedValues: Boolean(deployedStackPath) })
3000
+ printBootstrap(
3001
+ {
3002
+ output,
3003
+ kind,
3004
+ preservedDeployedValues: Boolean(deployedStackPath),
3005
+ remediation: (await bootstrapPlan(config)).remediation
3006
+ },
3007
+ `Wrote ${output}. Next: review and execute the generated ${kind} change set.
3008
+ ${formatBootstrapRemediationText((await bootstrapPlan(config)).remediation).join("\n")}`
2845
3009
  );
2846
3010
  } else if (action === "change-set") {
2847
3011
  const kind = bootstrapKind();
@@ -2871,17 +3035,22 @@ ${plan.notes.join("\n")}`);
2871
3035
  ...region2 ? ["--region", region2] : [],
2872
3036
  "--no-cli-pager"
2873
3037
  ];
2874
- console.log(
2875
- JSON.stringify({
2876
- kind,
2877
- packageVersion: plan.packageVersion,
2878
- contractVersion: template?.contractVersion,
2879
- templateRevision: template?.templateRevision,
2880
- templateSha256: template?.sha256,
2881
- reviewRequired: true,
2882
- awsCommand,
2883
- shellCommand: args.includes("--format-shell") ? shellCommand(awsCommand) : void 0
2884
- })
3038
+ const handoff = {
3039
+ kind,
3040
+ packageVersion: plan.packageVersion,
3041
+ contractVersion: template?.contractVersion,
3042
+ templateRevision: template?.templateRevision,
3043
+ templateSha256: template?.sha256,
3044
+ reviewRequired: true,
3045
+ awsCommand,
3046
+ shellCommand: args.includes("--format-shell") ? shellCommand(awsCommand) : void 0,
3047
+ remediation: (await bootstrapPlan(config)).remediation
3048
+ };
3049
+ printBootstrap(
3050
+ handoff,
3051
+ `Run the reviewed change set command:
3052
+ ${shellCommand(awsCommand)}`,
3053
+ shellCommand(awsCommand)
2885
3054
  );
2886
3055
  } else {
2887
3056
  throw new Error(
package/dist/doctor.d.ts CHANGED
@@ -1,8 +1,10 @@
1
+ import { type BootstrapRemediation } from './remediation.js';
1
2
  export type DoctorCheck = {
2
3
  name: string;
3
4
  ok: boolean;
4
5
  detail: string;
5
6
  warning?: boolean;
7
+ remediation?: BootstrapRemediation;
6
8
  };
7
9
  export type DoctorDependencies = {
8
10
  execute(command: string, args: string[]): Promise<string>;
package/dist/guided.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { type BootstrapConfig, type ComputeMode } from './bootstrap.js';
2
2
  import { type BootstrapProvider, bootstrapHandoff, type CommandRunner } from './handoff.js';
3
+ import { type BootstrapRemediation } from './remediation.js';
3
4
  export type BootstrapCheckStatus = 'ready' | 'missing' | 'mismatch' | 'unverified';
4
5
  export type BootstrapPreflightCheck = {
5
6
  name: string;
@@ -9,6 +10,7 @@ export type BootstrapPreflightCheck = {
9
10
  export type BootstrapPreflight = {
10
11
  ready: boolean;
11
12
  checks: BootstrapPreflightCheck[];
13
+ remediation: BootstrapRemediation;
12
14
  };
13
15
  export type BootstrapInitInput = {
14
16
  mode?: ComputeMode;
package/dist/handoff.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type BootstrapConfig } from './bootstrap.js';
2
+ import { type BootstrapRemediation } from './remediation.js';
2
3
  export type BootstrapPhase = 'core' | 'github-oidc' | 'github-environment' | 'application-gateway';
3
4
  export type CommandRunner = {
4
5
  execute(command: string, args: string[]): Promise<string>;
@@ -30,6 +31,7 @@ export type BootstrapHandoff = {
30
31
  reviewCheckpoints: string[];
31
32
  commands: HandoffCommand[];
32
33
  prerequisite?: ProviderPrerequisite;
34
+ remediation: BootstrapRemediation;
33
35
  };
34
36
  export type BootstrapVerification = {
35
37
  verified: true;
@@ -43,6 +45,7 @@ export type BootstrapVerification = {
43
45
  cloudFormationExecutionRoleArn: string;
44
46
  };
45
47
  githubEnvironmentInstructions: string[][];
48
+ remediation: BootstrapRemediation;
46
49
  };
47
50
  export declare const githubOidcProvider: BootstrapProvider;
48
51
  export declare function bootstrapHandoff(input: {