@dadado/agent-kit-cli 4.8.3 → 4.8.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.
- package/dashboard/dashboard.html +364 -55
- package/package.json +1 -1
package/dashboard/dashboard.html
CHANGED
|
@@ -503,6 +503,9 @@ a:focus-visible,
|
|
|
503
503
|
background: var(--border);
|
|
504
504
|
}
|
|
505
505
|
.nav-more-group-label {
|
|
506
|
+
display: flex;
|
|
507
|
+
align-items: center;
|
|
508
|
+
gap: var(--mc-chrome-label-gap);
|
|
506
509
|
padding: 6px 10px 2px;
|
|
507
510
|
font-size: var(--mc-chrome-subtitle-size);
|
|
508
511
|
font-weight: var(--mc-chrome-subtitle-weight);
|
|
@@ -800,25 +803,122 @@ a:focus-visible,
|
|
|
800
803
|
}
|
|
801
804
|
.terminal-item:hover { background: var(--bg-card-hover); }
|
|
802
805
|
|
|
803
|
-
/* =====
|
|
806
|
+
/* ===== Healthcenter ===== */
|
|
807
|
+
.healthcenter {
|
|
808
|
+
display: flex;
|
|
809
|
+
flex-direction: column;
|
|
810
|
+
gap: 10px;
|
|
811
|
+
}
|
|
812
|
+
.healthcenter-presence {
|
|
813
|
+
display: flex;
|
|
814
|
+
align-items: center;
|
|
815
|
+
gap: 8px;
|
|
816
|
+
font-size: 11px;
|
|
817
|
+
color: var(--text-muted);
|
|
818
|
+
}
|
|
819
|
+
.healthcenter-presence .dot-pulse {
|
|
820
|
+
animation: pulse 1.6s ease-in-out infinite;
|
|
821
|
+
}
|
|
804
822
|
.health-grid {
|
|
805
823
|
display: grid;
|
|
806
|
-
grid-template-columns: repeat(auto-fill, minmax(
|
|
824
|
+
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
807
825
|
gap: 8px;
|
|
808
826
|
}
|
|
827
|
+
.health-card {
|
|
828
|
+
display: flex;
|
|
829
|
+
flex-direction: column;
|
|
830
|
+
gap: 0;
|
|
831
|
+
border-radius: var(--mc-radius-sm, 6px);
|
|
832
|
+
background: var(--bg-card);
|
|
833
|
+
border: 1px solid var(--border);
|
|
834
|
+
overflow: hidden;
|
|
835
|
+
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
|
836
|
+
}
|
|
837
|
+
.health-card:hover,
|
|
838
|
+
.health-card.is-expanded {
|
|
839
|
+
border-color: var(--border-active);
|
|
840
|
+
}
|
|
841
|
+
.health-card[data-severity="ok"] { border-left: 3px solid var(--green, #3fb950); }
|
|
842
|
+
.health-card[data-severity="warning"] { border-left: 3px solid var(--yellow, #d29922); }
|
|
843
|
+
.health-card[data-severity="degraded"] { border-left: 3px solid var(--orange, #db6d28); }
|
|
844
|
+
.health-card[data-severity="error"] { border-left: 3px solid var(--red, #f85149); }
|
|
809
845
|
.health-item {
|
|
810
846
|
display: flex;
|
|
811
847
|
align-items: center;
|
|
812
848
|
gap: 8px;
|
|
813
|
-
padding:
|
|
814
|
-
border-radius: 6px;
|
|
815
|
-
background: var(--bg-card);
|
|
816
|
-
border: 1px solid var(--border);
|
|
849
|
+
padding: 10px 12px;
|
|
817
850
|
font-size: 12px;
|
|
818
851
|
color: var(--text-secondary);
|
|
819
|
-
|
|
852
|
+
cursor: pointer;
|
|
853
|
+
background: transparent;
|
|
854
|
+
border: none;
|
|
855
|
+
width: 100%;
|
|
856
|
+
text-align: left;
|
|
857
|
+
font-family: inherit;
|
|
858
|
+
transition: opacity 0.3s ease, transform 0.3s ease, background 0.15s ease;
|
|
859
|
+
}
|
|
860
|
+
.health-item:hover { background: var(--bg-card-hover); }
|
|
861
|
+
.health-item-label {
|
|
862
|
+
flex: 1;
|
|
863
|
+
min-width: 0;
|
|
864
|
+
color: var(--text-primary);
|
|
865
|
+
}
|
|
866
|
+
.health-item-sev {
|
|
867
|
+
font-size: 10px;
|
|
868
|
+
text-transform: uppercase;
|
|
869
|
+
letter-spacing: 0.04em;
|
|
870
|
+
color: var(--text-muted);
|
|
871
|
+
flex-shrink: 0;
|
|
872
|
+
}
|
|
873
|
+
.health-item-chevron {
|
|
874
|
+
color: var(--text-muted);
|
|
875
|
+
font-size: 10px;
|
|
876
|
+
transition: transform 0.15s ease;
|
|
877
|
+
flex-shrink: 0;
|
|
878
|
+
}
|
|
879
|
+
.health-card.is-expanded .health-item-chevron {
|
|
880
|
+
transform: rotate(180deg);
|
|
881
|
+
}
|
|
882
|
+
.health-detail {
|
|
883
|
+
display: none;
|
|
884
|
+
padding: 0 12px 12px;
|
|
885
|
+
border-top: 1px solid var(--border);
|
|
886
|
+
background: var(--bg-secondary);
|
|
887
|
+
}
|
|
888
|
+
.health-card.is-expanded .health-detail {
|
|
889
|
+
display: block;
|
|
890
|
+
animation: fadeIn 0.2s ease;
|
|
891
|
+
}
|
|
892
|
+
.health-detail-copy {
|
|
893
|
+
font-size: 11px;
|
|
894
|
+
color: var(--text-secondary);
|
|
895
|
+
margin: 10px 0 8px;
|
|
896
|
+
line-height: 1.4;
|
|
897
|
+
}
|
|
898
|
+
.health-detail-actions {
|
|
899
|
+
display: flex;
|
|
900
|
+
flex-wrap: wrap;
|
|
901
|
+
gap: 6px;
|
|
902
|
+
}
|
|
903
|
+
.health-autofix-btn {
|
|
904
|
+
font-size: 11px;
|
|
905
|
+
padding: 4px 10px;
|
|
906
|
+
border-radius: 4px;
|
|
907
|
+
border: 1px solid var(--border-active);
|
|
908
|
+
background: var(--bg-card);
|
|
909
|
+
color: var(--text-primary);
|
|
910
|
+
cursor: pointer;
|
|
911
|
+
font-family: inherit;
|
|
912
|
+
}
|
|
913
|
+
.health-autofix-btn:hover {
|
|
914
|
+
background: var(--bg-card-hover);
|
|
915
|
+
}
|
|
916
|
+
html[data-dashboard-skin="cursor"] .health-card {
|
|
917
|
+
border-radius: 8px;
|
|
918
|
+
}
|
|
919
|
+
html[data-dashboard-skin="legacy"] .health-card {
|
|
920
|
+
border-radius: 4px;
|
|
820
921
|
}
|
|
821
|
-
.health-item:hover { border-color: var(--border-active); }
|
|
822
922
|
|
|
823
923
|
/* ===== Git ===== */
|
|
824
924
|
.git-info {
|
|
@@ -1448,7 +1548,7 @@ a:focus-visible,
|
|
|
1448
1548
|
vertical-align: middle;
|
|
1449
1549
|
}
|
|
1450
1550
|
|
|
1451
|
-
/* ===== Health Investigation Message ===== */
|
|
1551
|
+
/* ===== Health Investigation Message (legacy; Healthcenter uses .health-detail) ===== */
|
|
1452
1552
|
.health-message {
|
|
1453
1553
|
font-size: 11px;
|
|
1454
1554
|
color: var(--text-secondary);
|
|
@@ -2031,8 +2131,8 @@ a:focus-visible,
|
|
|
2031
2131
|
grid-template-columns: 1fr 1fr;
|
|
2032
2132
|
grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
|
|
2033
2133
|
grid-template-areas:
|
|
2034
|
-
"now
|
|
2035
|
-
"
|
|
2134
|
+
"now attention"
|
|
2135
|
+
"checklist monitor";
|
|
2036
2136
|
}
|
|
2037
2137
|
|
|
2038
2138
|
#section-overview.active #now-execution-panel,
|
|
@@ -2662,10 +2762,10 @@ a:focus-visible,
|
|
|
2662
2762
|
font: inherit;
|
|
2663
2763
|
line-height: 1.4;
|
|
2664
2764
|
}
|
|
2765
|
+
/* Base hover/focus: keyboard-visible ring; kind rules below set colors (no unset --accent → yellow). */
|
|
2665
2766
|
.flight-log-card:hover,
|
|
2666
2767
|
.flight-log-card:focus-visible {
|
|
2667
|
-
|
|
2668
|
-
outline: 2px solid var(--accent, var(--yellow));
|
|
2768
|
+
outline: 2px solid var(--border);
|
|
2669
2769
|
outline-offset: 1px;
|
|
2670
2770
|
}
|
|
2671
2771
|
.flight-log-card-current {
|
|
@@ -2679,6 +2779,11 @@ a:focus-visible,
|
|
|
2679
2779
|
.flight-log-card-current.flight-log-kind-residual .flight-log-card-label {
|
|
2680
2780
|
color: var(--yellow);
|
|
2681
2781
|
}
|
|
2782
|
+
.flight-log-card-current.flight-log-kind-residual:hover,
|
|
2783
|
+
.flight-log-card-current.flight-log-kind-residual:focus-visible {
|
|
2784
|
+
border-color: var(--yellow);
|
|
2785
|
+
outline-color: var(--yellow);
|
|
2786
|
+
}
|
|
2682
2787
|
.flight-log-card-current.flight-log-kind-advice {
|
|
2683
2788
|
border-color: var(--blue);
|
|
2684
2789
|
background: var(--blue-bg);
|
|
@@ -2686,6 +2791,11 @@ a:focus-visible,
|
|
|
2686
2791
|
.flight-log-card-current.flight-log-kind-advice .flight-log-card-label {
|
|
2687
2792
|
color: var(--blue);
|
|
2688
2793
|
}
|
|
2794
|
+
.flight-log-card-current.flight-log-kind-advice:hover,
|
|
2795
|
+
.flight-log-card-current.flight-log-kind-advice:focus-visible {
|
|
2796
|
+
border-color: var(--blue);
|
|
2797
|
+
outline-color: var(--blue);
|
|
2798
|
+
}
|
|
2689
2799
|
.flight-log-card-current.flight-log-kind-ok {
|
|
2690
2800
|
border-color: color-mix(in srgb, var(--green) 55%, var(--border));
|
|
2691
2801
|
background: color-mix(in srgb, var(--green-bg) 40%, var(--bg-elevated, var(--bg-card)));
|
|
@@ -2693,6 +2803,11 @@ a:focus-visible,
|
|
|
2693
2803
|
.flight-log-card-current.flight-log-kind-ok .flight-log-card-label {
|
|
2694
2804
|
color: var(--green);
|
|
2695
2805
|
}
|
|
2806
|
+
.flight-log-card-current.flight-log-kind-ok:hover,
|
|
2807
|
+
.flight-log-card-current.flight-log-kind-ok:focus-visible {
|
|
2808
|
+
border-color: var(--green);
|
|
2809
|
+
outline-color: var(--green);
|
|
2810
|
+
}
|
|
2696
2811
|
.flight-log-card-current.flight-log-kind-warning {
|
|
2697
2812
|
border-color: color-mix(in srgb, var(--orange, var(--yellow)) 70%, var(--border));
|
|
2698
2813
|
background: color-mix(in srgb, var(--orange-bg, var(--yellow-bg)) 55%, var(--bg-elevated, var(--bg-card)));
|
|
@@ -2700,6 +2815,11 @@ a:focus-visible,
|
|
|
2700
2815
|
.flight-log-card-current.flight-log-kind-warning .flight-log-card-label {
|
|
2701
2816
|
color: var(--orange, var(--yellow));
|
|
2702
2817
|
}
|
|
2818
|
+
.flight-log-card-current.flight-log-kind-warning:hover,
|
|
2819
|
+
.flight-log-card-current.flight-log-kind-warning:focus-visible {
|
|
2820
|
+
border-color: var(--orange, var(--yellow));
|
|
2821
|
+
outline-color: var(--orange, var(--yellow));
|
|
2822
|
+
}
|
|
2703
2823
|
.flight-log-card-past {
|
|
2704
2824
|
padding: 8px 10px;
|
|
2705
2825
|
font-size: 11px;
|
|
@@ -2709,15 +2829,35 @@ a:focus-visible,
|
|
|
2709
2829
|
.flight-log-card-past.flight-log-kind-residual {
|
|
2710
2830
|
border-color: color-mix(in srgb, var(--yellow) 35%, var(--border));
|
|
2711
2831
|
}
|
|
2832
|
+
.flight-log-card-past.flight-log-kind-residual:hover,
|
|
2833
|
+
.flight-log-card-past.flight-log-kind-residual:focus-visible {
|
|
2834
|
+
border-color: color-mix(in srgb, var(--yellow) 55%, var(--border));
|
|
2835
|
+
outline-color: color-mix(in srgb, var(--yellow) 55%, var(--border));
|
|
2836
|
+
}
|
|
2712
2837
|
.flight-log-card-past.flight-log-kind-advice {
|
|
2713
2838
|
border-color: color-mix(in srgb, var(--blue) 35%, var(--border));
|
|
2714
2839
|
}
|
|
2840
|
+
.flight-log-card-past.flight-log-kind-advice:hover,
|
|
2841
|
+
.flight-log-card-past.flight-log-kind-advice:focus-visible {
|
|
2842
|
+
border-color: color-mix(in srgb, var(--blue) 55%, var(--border));
|
|
2843
|
+
outline-color: color-mix(in srgb, var(--blue) 55%, var(--border));
|
|
2844
|
+
}
|
|
2715
2845
|
.flight-log-card-past.flight-log-kind-ok {
|
|
2716
2846
|
border-color: color-mix(in srgb, var(--green) 30%, var(--border));
|
|
2717
2847
|
}
|
|
2848
|
+
.flight-log-card-past.flight-log-kind-ok:hover,
|
|
2849
|
+
.flight-log-card-past.flight-log-kind-ok:focus-visible {
|
|
2850
|
+
border-color: color-mix(in srgb, var(--green) 50%, var(--border));
|
|
2851
|
+
outline-color: color-mix(in srgb, var(--green) 50%, var(--border));
|
|
2852
|
+
}
|
|
2718
2853
|
.flight-log-card-past.flight-log-kind-warning {
|
|
2719
2854
|
border-color: color-mix(in srgb, var(--orange, var(--yellow)) 30%, var(--border));
|
|
2720
2855
|
}
|
|
2856
|
+
.flight-log-card-past.flight-log-kind-warning:hover,
|
|
2857
|
+
.flight-log-card-past.flight-log-kind-warning:focus-visible {
|
|
2858
|
+
border-color: color-mix(in srgb, var(--orange, var(--yellow)) 50%, var(--border));
|
|
2859
|
+
outline-color: color-mix(in srgb, var(--orange, var(--yellow)) 50%, var(--border));
|
|
2860
|
+
}
|
|
2721
2861
|
.flight-log-card-warning {
|
|
2722
2862
|
padding: 10px 12px;
|
|
2723
2863
|
border-color: color-mix(in srgb, var(--orange, var(--yellow)) 70%, var(--border));
|
|
@@ -2728,6 +2868,11 @@ a:focus-visible,
|
|
|
2728
2868
|
.flight-log-card-warning .flight-log-card-label {
|
|
2729
2869
|
color: var(--orange, var(--yellow));
|
|
2730
2870
|
}
|
|
2871
|
+
.flight-log-card-warning:hover,
|
|
2872
|
+
.flight-log-card-warning:focus-visible {
|
|
2873
|
+
border-color: var(--orange, var(--yellow));
|
|
2874
|
+
outline-color: var(--orange, var(--yellow));
|
|
2875
|
+
}
|
|
2731
2876
|
.flight-log-card-label {
|
|
2732
2877
|
display: block;
|
|
2733
2878
|
font-weight: 600;
|
|
@@ -2894,7 +3039,7 @@ a:focus-visible,
|
|
|
2894
3039
|
</a>
|
|
2895
3040
|
<div class="nav-more-separator" role="separator"></div>
|
|
2896
3041
|
<div class="nav-more-group" role="group" aria-labelledby="navSkinsLabel">
|
|
2897
|
-
<div class="nav-more-group-label" id="navSkinsLabel">Skins</div>
|
|
3042
|
+
<div class="nav-more-group-label" id="navSkinsLabel" data-icon="skins">Skins</div>
|
|
2898
3043
|
<button type="button" class="nav-more-item" role="menuitemradio" aria-checked="true" data-dashboard-skin-option="legacy" tabindex="0" onclick="return setDashboardSkin('legacy')">
|
|
2899
3044
|
Legacy
|
|
2900
3045
|
</button>
|
|
@@ -2914,18 +3059,18 @@ a:focus-visible,
|
|
|
2914
3059
|
<div class="top-tabs-row">
|
|
2915
3060
|
<div class="cockpit-anchors" role="navigation" aria-label="Cockpit sections">
|
|
2916
3061
|
<a class="top-nav-anchor active" href="#now-execution-panel" data-anchor="now-execution-panel" data-icon="current-mission" onclick="return goCockpitAnchor('now-execution-panel')" aria-current="true">
|
|
2917
|
-
<span class="top-nav-anchor-label">
|
|
3062
|
+
<span class="top-nav-anchor-label">Current mission</span>
|
|
2918
3063
|
<span class="top-tab-badge" id="navOverviewBadge">0</span>
|
|
2919
3064
|
</a>
|
|
2920
|
-
<a class="top-nav-anchor" href="#hero-activity" data-anchor="hero-activity" data-icon="monitor" onclick="return goCockpitAnchor('hero-activity')">
|
|
2921
|
-
<span class="top-nav-anchor-label">Crew Monitor</span>
|
|
2922
|
-
</a>
|
|
2923
3065
|
<a class="top-nav-anchor" href="#attention-panel" data-anchor="attention-panel" data-icon="field-report" onclick="return goCockpitAnchor('attention-panel')">
|
|
2924
3066
|
<span class="top-nav-anchor-label">Flight Log</span>
|
|
2925
3067
|
</a>
|
|
2926
3068
|
<a class="top-nav-anchor" href="#recent-plans-panel" data-anchor="recent-plans-panel" data-icon="checklist" onclick="return goCockpitAnchor('recent-plans-panel')">
|
|
2927
3069
|
<span class="top-nav-anchor-label">Checklist</span>
|
|
2928
3070
|
</a>
|
|
3071
|
+
<a class="top-nav-anchor" href="#hero-activity" data-anchor="hero-activity" data-icon="monitor" onclick="return goCockpitAnchor('hero-activity')">
|
|
3072
|
+
<span class="top-nav-anchor-label">Crew Monitor</span>
|
|
3073
|
+
</a>
|
|
2929
3074
|
</div>
|
|
2930
3075
|
</div>
|
|
2931
3076
|
</nav>
|
|
@@ -3295,6 +3440,11 @@ function injectCockpitNavIcons() {
|
|
|
3295
3440
|
if (!kind) return;
|
|
3296
3441
|
el.insertAdjacentHTML('afterbegin', spaceIconSvg(kind, { decorative: true }));
|
|
3297
3442
|
});
|
|
3443
|
+
// Skins group label: palette glyph (distinct from Skills gear).
|
|
3444
|
+
const skinsLabel = document.getElementById('navSkinsLabel');
|
|
3445
|
+
if (skinsLabel && !skinsLabel.querySelector('.space-icon')) {
|
|
3446
|
+
skinsLabel.insertAdjacentHTML('afterbegin', spaceIconSvg('skins', { decorative: true }));
|
|
3447
|
+
}
|
|
3298
3448
|
}
|
|
3299
3449
|
|
|
3300
3450
|
// ===== Cockpit nav + more-menu keyboard / outside click =====
|
|
@@ -4481,9 +4631,85 @@ function toggleAgentDetails(id) {
|
|
|
4481
4631
|
}
|
|
4482
4632
|
}
|
|
4483
4633
|
|
|
4484
|
-
// =====
|
|
4634
|
+
// ===== Healthcenter: per-check expand + Autofix map (copy-only) =====
|
|
4635
|
+
/** Fixed v1 check set: plans, handoff, agents, commands, memory, git, config. */
|
|
4636
|
+
const HEALTH_CHECK_META = {
|
|
4637
|
+
plans: {
|
|
4638
|
+
okDetail: 'Plans directory is present with at least one plan file.',
|
|
4639
|
+
failDetail: 'No plans under .cursor/plans/, or the plans directory is missing.',
|
|
4640
|
+
autofix: { text: '/start-project', subject: '/start-project', destination: 'chatInput', label: 'Autofix' },
|
|
4641
|
+
},
|
|
4642
|
+
handoff: {
|
|
4643
|
+
okDetail: 'HANDOFF.md is present and parseable (idle Plan is still healthy).',
|
|
4644
|
+
failDetail: 'HANDOFF.md is missing or not parseable.',
|
|
4645
|
+
autofix: { text: '/continue-plan', subject: '/continue-plan', destination: 'chatInput', label: 'Autofix' },
|
|
4646
|
+
},
|
|
4647
|
+
agents: {
|
|
4648
|
+
okDetail: 'At least one agent is cataloged under .cursor/agents/.',
|
|
4649
|
+
failDetail: 'No agents found. Kit install or onboard may be incomplete.',
|
|
4650
|
+
autofix: { text: '/agent-kit-onboard', subject: '/agent-kit-onboard', destination: 'chatInput', label: 'Autofix' },
|
|
4651
|
+
},
|
|
4652
|
+
commands: {
|
|
4653
|
+
okDetail: 'Slash commands are available under .cursor/commands/.',
|
|
4654
|
+
failDetail: 'No commands under .cursor/commands/.',
|
|
4655
|
+
autofix: { text: '.cursor/commands/', subject: 'path .cursor/commands/', destination: 'filePicker', label: 'Copy path' },
|
|
4656
|
+
},
|
|
4657
|
+
memory: {
|
|
4658
|
+
okDetail: 'Memory has recorded errors and/or decisions.',
|
|
4659
|
+
failDetail: 'Memory index has no errors or decisions yet (optional until first WRITE).',
|
|
4660
|
+
autofix: { text: '/agent-kit-onboard', subject: '/agent-kit-onboard', destination: 'chatInput', label: 'Autofix' },
|
|
4661
|
+
},
|
|
4662
|
+
git: {
|
|
4663
|
+
okDetail: 'Git branch signal is available.',
|
|
4664
|
+
failDetail: 'Git repository signal missing (no branch).',
|
|
4665
|
+
autofix: { text: 'git status', subject: 'git status', destination: 'terminal', label: 'Autofix' },
|
|
4666
|
+
},
|
|
4667
|
+
config: {
|
|
4668
|
+
okDetail: 'Workspace config is loaded.',
|
|
4669
|
+
failDetail: 'Workspace config is missing or not loaded.',
|
|
4670
|
+
autofix: { text: 'agent-kit doctor', subject: 'agent-kit doctor', destination: 'terminal', label: 'Autofix' },
|
|
4671
|
+
},
|
|
4672
|
+
};
|
|
4673
|
+
|
|
4674
|
+
function healthCheckSeverity(check, aggregateStatus) {
|
|
4675
|
+
if (check && check.ok) return 'ok';
|
|
4676
|
+
if (aggregateStatus === 'degraded') return 'degraded';
|
|
4677
|
+
if (aggregateStatus === 'error') return 'error';
|
|
4678
|
+
return 'warning';
|
|
4679
|
+
}
|
|
4680
|
+
|
|
4681
|
+
function healthSeverityLabel(sev) {
|
|
4682
|
+
if (sev === 'ok') return 'ok';
|
|
4683
|
+
if (sev === 'warning') return 'warn';
|
|
4684
|
+
if (sev === 'degraded') return 'degraded';
|
|
4685
|
+
if (sev === 'error') return 'error';
|
|
4686
|
+
return sev || 'unknown';
|
|
4687
|
+
}
|
|
4688
|
+
|
|
4689
|
+
function healthDotClass(sev) {
|
|
4690
|
+
if (sev === 'ok') return 'dot-green';
|
|
4691
|
+
if (sev === 'warning') return 'dot-yellow';
|
|
4692
|
+
if (sev === 'degraded') return 'dot-yellow';
|
|
4693
|
+
return 'dot-red';
|
|
4694
|
+
}
|
|
4695
|
+
|
|
4696
|
+
function toggleHealthCheck(checkId) {
|
|
4697
|
+
const card = document.getElementById('health-card-' + checkId);
|
|
4698
|
+
if (!card) return;
|
|
4699
|
+
const open = card.classList.toggle('is-expanded');
|
|
4700
|
+
const btn = card.querySelector('.health-item');
|
|
4701
|
+
if (btn) btn.setAttribute('aria-expanded', open ? 'true' : 'false');
|
|
4702
|
+
}
|
|
4703
|
+
|
|
4704
|
+
function healthCheckKeydown(event, checkId) {
|
|
4705
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
4706
|
+
event.preventDefault();
|
|
4707
|
+
toggleHealthCheck(checkId);
|
|
4708
|
+
}
|
|
4709
|
+
}
|
|
4710
|
+
|
|
4711
|
+
/** @deprecated Prefer toggleHealthCheck; kept for any leftover callers. */
|
|
4485
4712
|
function showHealthInfo(el, ok) {
|
|
4486
|
-
// Remove any existing message siblings
|
|
4487
4713
|
const parent = el.parentElement;
|
|
4488
4714
|
const existing = parent.querySelector('.health-message');
|
|
4489
4715
|
if (existing) { existing.remove(); return; }
|
|
@@ -5290,9 +5516,9 @@ function nowMetaIconSvg(kind, opts) {
|
|
|
5290
5516
|
/**
|
|
5291
5517
|
* Space-theme Cockpit/nav icon set (inline SVG, no font/fetch/dependency).
|
|
5292
5518
|
* Shared chrome SVG shell with header refresh / nowMetaIconSvg:
|
|
5293
|
-
* viewBox 0 0 16 16, stroke
|
|
5519
|
+
* viewBox 0 0 16 16, stroke 1.5, round caps/joins, CSS box via --mc-chrome-icon-size.
|
|
5294
5520
|
* Static path markup only; never concatenate untrusted text into the SVG.
|
|
5295
|
-
* @param {'current-mission'|'monitor'|'field-report'|'checklist'|'more-sections'|'overview'|'plans'|'activity'|'agents'|'skills'|'commands'|'health'|'git'|'memory'|'terminals'|'processes'|'config'} kind
|
|
5521
|
+
* @param {'current-mission'|'monitor'|'field-report'|'checklist'|'more-sections'|'overview'|'plans'|'activity'|'agents'|'skills'|'skins'|'commands'|'health'|'git'|'memory'|'terminals'|'processes'|'config'} kind
|
|
5296
5522
|
* @param {{ decorative?: boolean }} [opts] decorative true (default): aria-hidden next to a visible label.
|
|
5297
5523
|
* decorative false: role=img + aria-label + title for icon-only controls (e.g. more-sections).
|
|
5298
5524
|
*/
|
|
@@ -5310,6 +5536,7 @@ function spaceIconSvg(kind, opts) {
|
|
|
5310
5536
|
activity: 'Activity',
|
|
5311
5537
|
agents: 'Agents',
|
|
5312
5538
|
skills: 'Skills',
|
|
5539
|
+
skins: 'Skins',
|
|
5313
5540
|
commands: 'Commands',
|
|
5314
5541
|
health: 'Health',
|
|
5315
5542
|
git: 'Git',
|
|
@@ -5319,7 +5546,7 @@ function spaceIconSvg(kind, opts) {
|
|
|
5319
5546
|
config: 'Config',
|
|
5320
5547
|
};
|
|
5321
5548
|
const paths = {
|
|
5322
|
-
// Rocket (mission)
|
|
5549
|
+
// Rocket (mission)
|
|
5323
5550
|
'current-mission':
|
|
5324
5551
|
'<path d="M8 2c1.4 2 2.5 4 2.5 6a2.5 2.5 0 01-5 0C5.5 6 6.6 4 8 2z"/>' +
|
|
5325
5552
|
'<circle cx="8" cy="7.5" r=".9"/>' +
|
|
@@ -5336,20 +5563,20 @@ function spaceIconSvg(kind, opts) {
|
|
|
5336
5563
|
'<rect x="4.5" y="3.5" width="7" height="10" rx="1.2"/>' +
|
|
5337
5564
|
'<path d="M6.5 3.5V2.5a1.5 1.5 0 013 0v1"/>' +
|
|
5338
5565
|
'<path d="M6.5 7h3M6.5 9.5h3"/>',
|
|
5339
|
-
// Checklist lines
|
|
5566
|
+
// Checklist lines
|
|
5340
5567
|
checklist:
|
|
5341
5568
|
'<path d="M3.5 4.5h9M3.5 8h6.5M3.5 11.5h5.5"/>' +
|
|
5342
5569
|
'<path d="M10.5 10.5l1.2 1.2L14 9.5"/>',
|
|
5343
|
-
//
|
|
5570
|
+
// Ellipsis (more sections) — radii sized for stroke 1.5
|
|
5344
5571
|
'more-sections':
|
|
5345
|
-
'<circle cx="4" cy="8" r=".
|
|
5346
|
-
'<circle cx="8" cy="8" r=".
|
|
5347
|
-
'<circle cx="12" cy="8" r=".
|
|
5348
|
-
// House (overview / home)
|
|
5572
|
+
'<circle cx="4" cy="8" r="1.25"/>' +
|
|
5573
|
+
'<circle cx="8" cy="8" r="1.25"/>' +
|
|
5574
|
+
'<circle cx="12" cy="8" r="1.25"/>',
|
|
5575
|
+
// House (overview / home) — roof + walls + door as one coherent glyph
|
|
5349
5576
|
overview:
|
|
5350
|
-
'<path d="M2.5
|
|
5351
|
-
'<path d="M4.
|
|
5352
|
-
'<path d="
|
|
5577
|
+
'<path d="M2.5 7.5L8 2.75l5.5 4.75"/>' +
|
|
5578
|
+
'<path d="M4.25 7.75v6.5h7.5v-6.5"/>' +
|
|
5579
|
+
'<path d="M6.75 14.25v-3.25h2.5v3.25"/>',
|
|
5353
5580
|
// Document (plans)
|
|
5354
5581
|
plans:
|
|
5355
5582
|
'<path d="M4.5 2.5h5l4 4v8.5a1 1 0 01-1 1h-8a1 1 0 01-1-1v-12a1 1 0 011-1z"/>' +
|
|
@@ -5365,6 +5592,10 @@ function spaceIconSvg(kind, opts) {
|
|
|
5365
5592
|
skills:
|
|
5366
5593
|
'<circle cx="8" cy="8" r="2"/>' +
|
|
5367
5594
|
'<path d="M10.5 8a2.5 2.5 0 000-2.5l.8-.8M5.5 8a2.5 2.5 0 010 2.5l-.8.8M8 5.5l-.5-1M8 10.5l-.5 1M10.5 6.5l1-.5M5.5 9.5l-1 .5M10.5 9.5l1 .5M5.5 6.5l-1-.5"/>',
|
|
5595
|
+
// Overlapping swatches (skins) — distinct from Skills gear
|
|
5596
|
+
skins:
|
|
5597
|
+
'<rect x="2.5" y="3.5" width="7" height="7" rx="1.25"/>' +
|
|
5598
|
+
'<rect x="6.5" y="5.5" width="7" height="7" rx="1.25"/>',
|
|
5368
5599
|
// Terminal (commands)
|
|
5369
5600
|
commands:
|
|
5370
5601
|
'<path d="M2.5 3.5l5 5-5 5"/>' +
|
|
@@ -5405,7 +5636,7 @@ function spaceIconSvg(kind, opts) {
|
|
|
5405
5636
|
const a11y = decorative
|
|
5406
5637
|
? 'aria-hidden="true"'
|
|
5407
5638
|
: `role="img" aria-label="${label}" title="${label}"`;
|
|
5408
|
-
return `<svg class="space-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="
|
|
5639
|
+
return `<svg class="space-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" ${a11y}>${body}</svg>`;
|
|
5409
5640
|
}
|
|
5410
5641
|
|
|
5411
5642
|
/**
|
|
@@ -6266,6 +6497,10 @@ function renderUnsafe() {
|
|
|
6266
6497
|
<div class="overview-stack">
|
|
6267
6498
|
${renderNowExecutionPanel(d, !!(nowChanged || handoffChanged))}
|
|
6268
6499
|
|
|
6500
|
+
${renderAttentionPanel(d, !!attentionChanged)}
|
|
6501
|
+
|
|
6502
|
+
${renderRecentPlanCards(d)}
|
|
6503
|
+
|
|
6269
6504
|
<div class="section-hero" id="hero-activity">
|
|
6270
6505
|
<div class="live-activity-header">
|
|
6271
6506
|
<span class="card-title">${spaceIconSvg('monitor')}Crew Monitor</span>
|
|
@@ -6298,10 +6533,6 @@ function renderUnsafe() {
|
|
|
6298
6533
|
}).join('')}
|
|
6299
6534
|
</div>
|
|
6300
6535
|
</div>
|
|
6301
|
-
|
|
6302
|
-
${renderAttentionPanel(d, !!attentionChanged)}
|
|
6303
|
-
|
|
6304
|
-
${renderRecentPlanCards(d)}
|
|
6305
6536
|
</div>
|
|
6306
6537
|
</div>
|
|
6307
6538
|
`);
|
|
@@ -6394,30 +6625,108 @@ function renderUnsafe() {
|
|
|
6394
6625
|
</div>
|
|
6395
6626
|
`);
|
|
6396
6627
|
|
|
6397
|
-
// ===== Health =====
|
|
6628
|
+
// ===== Healthcenter (More → Health) =====
|
|
6398
6629
|
const checks = health.checks || [];
|
|
6630
|
+
const healthStatus = health.status || 'ok';
|
|
6631
|
+
const passing = checks.filter(c => c.ok).length;
|
|
6632
|
+
const isSnapshotError = healthStatus === 'error' && checks.length === 0;
|
|
6633
|
+
const isOffline = !isSnapshotError && checks.length === 0;
|
|
6634
|
+
const presenceTone = healthStatus === 'ok' ? 'green' : healthStatus === 'warning' ? 'yellow' : 'red';
|
|
6635
|
+
const presencePulse = healthStatus !== 'ok' ? ' dot-pulse' : '';
|
|
6636
|
+
const presenceLabel = isSnapshotError
|
|
6637
|
+
? 'Snapshot error'
|
|
6638
|
+
: isOffline
|
|
6639
|
+
? 'Health offline'
|
|
6640
|
+
: healthStatus === 'ok'
|
|
6641
|
+
? 'Live'
|
|
6642
|
+
: healthStatus === 'warning'
|
|
6643
|
+
? 'Warning'
|
|
6644
|
+
: healthStatus === 'degraded'
|
|
6645
|
+
? 'Degraded'
|
|
6646
|
+
: 'Error';
|
|
6647
|
+
const subtitle = isSnapshotError
|
|
6648
|
+
? 'Snapshot unavailable'
|
|
6649
|
+
: isOffline
|
|
6650
|
+
? 'No health data'
|
|
6651
|
+
: `${passing}/${checks.length} checks passing`;
|
|
6652
|
+
|
|
6653
|
+
let healthBody = '';
|
|
6654
|
+
if (isSnapshotError) {
|
|
6655
|
+
healthBody = renderEmptyStateCta({
|
|
6656
|
+
headline: 'Health snapshot error',
|
|
6657
|
+
support: (typeof d.error === 'string' && d.error)
|
|
6658
|
+
|| 'The dashboard could not load health checks (serve/snapshot failure). This is not a per-check fail.',
|
|
6659
|
+
iconKind: 'health',
|
|
6660
|
+
cta: {
|
|
6661
|
+
text: 'agent-kit doctor',
|
|
6662
|
+
subject: 'agent-kit doctor',
|
|
6663
|
+
destination: 'terminal',
|
|
6664
|
+
label: 'Autofix: copy agent-kit doctor',
|
|
6665
|
+
focusKey: 'cta-health-snapshot-error',
|
|
6666
|
+
},
|
|
6667
|
+
});
|
|
6668
|
+
} else if (isOffline) {
|
|
6669
|
+
healthBody = renderEmptyStateCta({
|
|
6670
|
+
headline: 'Health offline',
|
|
6671
|
+
support: 'No health data available yet. Refresh after the snapshot loads, or run doctor if the panel stays empty.',
|
|
6672
|
+
iconKind: 'health',
|
|
6673
|
+
cta: {
|
|
6674
|
+
text: 'agent-kit doctor',
|
|
6675
|
+
subject: 'agent-kit doctor',
|
|
6676
|
+
destination: 'terminal',
|
|
6677
|
+
label: 'Autofix: copy agent-kit doctor',
|
|
6678
|
+
focusKey: 'cta-health-offline',
|
|
6679
|
+
},
|
|
6680
|
+
});
|
|
6681
|
+
} else {
|
|
6682
|
+
healthBody = `
|
|
6683
|
+
<div class="health-grid" role="list">
|
|
6684
|
+
${checks.map(c => {
|
|
6685
|
+
const id = c.id || c.label || 'check';
|
|
6686
|
+
const meta = HEALTH_CHECK_META[id] || {
|
|
6687
|
+
okDetail: 'Check is passing.',
|
|
6688
|
+
failDetail: 'Check is failing. Review configuration for this item.',
|
|
6689
|
+
autofix: null,
|
|
6690
|
+
};
|
|
6691
|
+
const sev = healthCheckSeverity(c, healthStatus);
|
|
6692
|
+
const detail = c.ok ? meta.okDetail : meta.failDetail;
|
|
6693
|
+
const autofix = !c.ok && meta.autofix ? meta.autofix : null;
|
|
6694
|
+
const autofixBtn = autofix
|
|
6695
|
+
? `<button type="button" class="health-autofix-btn" data-focus-key="health-autofix-${escapeAttr(id)}" onclick="event.stopPropagation();${copyForPasteHandler(autofix.text, autofix.subject, autofix.destination)}" title="${escapeAttr(copyActionTitle(autofix.subject, autofix.destination))}">${escapeHtml(autofix.label || 'Autofix')}</button>`
|
|
6696
|
+
: (c.ok
|
|
6697
|
+
? `<span class="health-detail-copy" style="margin:0">No Autofix needed.</span>`
|
|
6698
|
+
: `<span class="health-detail-copy" style="margin:0">No Autofix mapped for this check.</span>`);
|
|
6699
|
+
return `
|
|
6700
|
+
<div class="health-card" role="listitem" id="health-card-${escapeAttr(id)}" data-check-id="${escapeAttr(id)}" data-severity="${escapeAttr(sev)}">
|
|
6701
|
+
<button type="button" class="health-item" aria-expanded="false" aria-controls="health-detail-${escapeAttr(id)}" aria-label="${escapeAttr(c.label)}: ${escapeAttr(healthSeverityLabel(sev))}" onclick="toggleHealthCheck('${escapeJsString(id)}')" onkeydown="healthCheckKeydown(event, '${escapeJsString(id)}')">
|
|
6702
|
+
<span class="dot ${healthDotClass(sev)}"></span>
|
|
6703
|
+
<span class="health-item-label">${escapeHtml(c.label)}</span>
|
|
6704
|
+
<span class="health-item-sev">${escapeHtml(healthSeverityLabel(sev))}</span>
|
|
6705
|
+
<span class="health-item-chevron" aria-hidden="true">▾</span>
|
|
6706
|
+
</button>
|
|
6707
|
+
<div class="health-detail" id="health-detail-${escapeAttr(id)}">
|
|
6708
|
+
<p class="health-detail-copy">${escapeHtml(detail)}</p>
|
|
6709
|
+
<div class="health-detail-actions">${autofixBtn}</div>
|
|
6710
|
+
</div>
|
|
6711
|
+
</div>`;
|
|
6712
|
+
}).join('')}
|
|
6713
|
+
</div>`;
|
|
6714
|
+
}
|
|
6715
|
+
|
|
6399
6716
|
parts.push(`
|
|
6400
6717
|
<div class="content-section" id="section-health">
|
|
6401
6718
|
<div class="section-title">
|
|
6402
|
-
<span class="dot dot-${
|
|
6719
|
+
<span class="dot dot-${presenceTone}${healthStatus !== 'ok' ? ' dot-pulse' : ''}"></span>
|
|
6403
6720
|
Health
|
|
6404
|
-
<span class="section-subtitle">${
|
|
6721
|
+
<span class="section-subtitle">${escapeHtml(subtitle)}</span>
|
|
6405
6722
|
</div>
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
${checks.map(c => `
|
|
6414
|
-
<div style="position:relative">
|
|
6415
|
-
<div class="health-item" role="button" tabindex="0" aria-label="Show info for ${escapeAttr(c.label)}" onclick="showHealthInfo(this, ${c.ok})">
|
|
6416
|
-
<span class="dot dot-${c.ok ? 'green' : 'red'}"></span>
|
|
6417
|
-
<span>${escapeHtml(c.label)}</span>
|
|
6418
|
-
</div>
|
|
6419
|
-
</div>
|
|
6420
|
-
`).join('')}
|
|
6723
|
+
<div class="healthcenter">
|
|
6724
|
+
<div class="healthcenter-presence" role="status" aria-live="polite">
|
|
6725
|
+
<span class="dot dot-${presenceTone}${presencePulse}"></span>
|
|
6726
|
+
<span>${escapeHtml(presenceLabel)}</span>
|
|
6727
|
+
<span>· same seven checks · copy-only Autofix</span>
|
|
6728
|
+
</div>
|
|
6729
|
+
${healthBody}
|
|
6421
6730
|
</div>
|
|
6422
6731
|
</div>
|
|
6423
6732
|
`);
|
package/package.json
CHANGED