@cortexkit/aft-opencode 0.50.3 → 0.51.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/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +386 -154
- package/dist/shared/status.d.ts +15 -18
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/tools/_shared.d.ts.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/inspect.d.ts +28 -0
- package/dist/tools/inspect.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/shared/status.ts +79 -50
- package/src/tui/index.tsx +55 -45
- package/src/tui/sidebar.tsx +79 -55
- package/src/tui-compiled/index.tsx +87 -69
- package/src/tui-compiled/sidebar.tsx +102 -84
- package/dist/status-bar-inject.d.ts +0 -11
- package/dist/status-bar-inject.d.ts.map +0 -1
package/src/tui/sidebar.tsx
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
formatSemanticRefreshing,
|
|
18
18
|
type StatusBar,
|
|
19
19
|
type StatusCompression,
|
|
20
|
+
worktreeCacheRoleNote,
|
|
20
21
|
} from "../shared/status";
|
|
21
22
|
import { resolveCortexKitStorageRoot } from "../shared/storage-paths";
|
|
22
23
|
import { badgeTextColor } from "./badge-contrast";
|
|
@@ -193,7 +194,7 @@ export function collapsedCompressionValue(
|
|
|
193
194
|
return `${formatCount(savings_tokens)} / ${pct}%`;
|
|
194
195
|
}
|
|
195
196
|
|
|
196
|
-
export type HealthLightTone = "ok" | "warn" | "err";
|
|
197
|
+
export type HealthLightTone = "ok" | "warn" | "err" | "muted";
|
|
197
198
|
|
|
198
199
|
// Degraded-mode reason → human-readable hint. Distinct strings per reason
|
|
199
200
|
// because the UX direction is different: "home_root" tells the user to open a
|
|
@@ -215,26 +216,31 @@ export function degradedReasonLabel(reason: string): string {
|
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
export interface HealthLights {
|
|
218
|
-
// Diagnostics: red if any errors, yellow if any warnings, else green.
|
|
219
219
|
diagnostics: HealthLightTone;
|
|
220
|
-
// Code cruft: yellow if there is any dead code, unused export, or duplicate,
|
|
221
|
-
// green when zero. Never red — cruft is not a build failure.
|
|
222
220
|
code: HealthLightTone;
|
|
223
|
-
// TODOs: yellow if any, else green.
|
|
224
221
|
todos: HealthLightTone;
|
|
225
222
|
}
|
|
226
223
|
|
|
227
|
-
//
|
|
228
|
-
//
|
|
224
|
+
// Missing categories are intentionally muted: a green light requires an
|
|
225
|
+
// explicit zero for every category that feeds that light.
|
|
229
226
|
export function collapsedHealthLights(statusBar: StatusBar | undefined): HealthLights | null {
|
|
230
227
|
if (!statusBar) return null;
|
|
231
228
|
const diagnostics: HealthLightTone =
|
|
232
|
-
statusBar.errors
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
229
|
+
statusBar.errors !== undefined && statusBar.errors > 0
|
|
230
|
+
? "err"
|
|
231
|
+
: statusBar.warnings !== undefined && statusBar.warnings > 0
|
|
232
|
+
? "warn"
|
|
233
|
+
: statusBar.errors === 0 && statusBar.warnings === 0
|
|
234
|
+
? "ok"
|
|
235
|
+
: "muted";
|
|
236
|
+
const codeValues = [statusBar.dead_code, statusBar.unused_exports, statusBar.duplicates];
|
|
237
|
+
const code: HealthLightTone = codeValues.some((value) => value !== undefined && value > 0)
|
|
238
|
+
? "warn"
|
|
239
|
+
: codeValues.every((value) => value === 0)
|
|
240
|
+
? "ok"
|
|
241
|
+
: "muted";
|
|
242
|
+
const todos: HealthLightTone =
|
|
243
|
+
statusBar.todos === undefined ? "muted" : statusBar.todos > 0 ? "warn" : "ok";
|
|
238
244
|
return { diagnostics, code, todos };
|
|
239
245
|
}
|
|
240
246
|
|
|
@@ -561,6 +567,10 @@ const SidebarContent = (props: {
|
|
|
561
567
|
return reasons.map(degradedReasonLabel).join("; ");
|
|
562
568
|
};
|
|
563
569
|
|
|
570
|
+
// Worktree borrow is a shared-index arrangement, not a degraded_reasons
|
|
571
|
+
// entry. Keep this muted and separate from the DEGRADED badge above.
|
|
572
|
+
const worktreeNote = () => worktreeCacheRoleNote(s()?.cache_role);
|
|
573
|
+
|
|
564
574
|
return (
|
|
565
575
|
<box
|
|
566
576
|
width="100%"
|
|
@@ -627,6 +637,12 @@ const SidebarContent = (props: {
|
|
|
627
637
|
</box>
|
|
628
638
|
)}
|
|
629
639
|
|
|
640
|
+
{!notInitialized() && worktreeNote() && (
|
|
641
|
+
<box marginTop={1} width="100%">
|
|
642
|
+
<text fg={props.theme.textMuted}>{worktreeNote()}</text>
|
|
643
|
+
</box>
|
|
644
|
+
)}
|
|
645
|
+
|
|
630
646
|
{/* Lazy-bridge placeholder. AFT skips spawning the `aft` binary at
|
|
631
647
|
plugin init to keep memory/CPU low on OpenCode Desktop sessions
|
|
632
648
|
that have many projects pinned in the sidebar. The RPC server
|
|
@@ -755,54 +771,62 @@ const SidebarContent = (props: {
|
|
|
755
771
|
</>
|
|
756
772
|
)}
|
|
757
773
|
|
|
758
|
-
{/*
|
|
759
|
-
|
|
760
|
-
so it never shows fabricated zeros. Errors/warnings are live LSP
|
|
761
|
-
diagnostics; D/U/C/T come from the last background scan. A `~` on
|
|
762
|
-
the section header flags the Tier-2 counts as predating the latest
|
|
763
|
-
edit. */}
|
|
774
|
+
{/* Human health values are optional. A category stays absent until the
|
|
775
|
+
server proves it, rather than appearing as a clean zero. */}
|
|
764
776
|
{prefs().sections.codeHealth && statusBar() && (
|
|
765
777
|
<>
|
|
766
778
|
<SectionHeader
|
|
767
779
|
theme={props.theme}
|
|
768
780
|
title={statusBar()!.tier2_stale ? "Code Health ~" : "Code Health"}
|
|
769
781
|
/>
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
782
|
+
{statusBar()!.errors !== undefined && (
|
|
783
|
+
<StatRow
|
|
784
|
+
theme={props.theme}
|
|
785
|
+
label="Errors"
|
|
786
|
+
value={formatCount(statusBar()!.errors)}
|
|
787
|
+
tone={statusBar()!.errors! > 0 ? "err" : "muted"}
|
|
788
|
+
/>
|
|
789
|
+
)}
|
|
790
|
+
{statusBar()!.warnings !== undefined && (
|
|
791
|
+
<StatRow
|
|
792
|
+
theme={props.theme}
|
|
793
|
+
label="Warnings"
|
|
794
|
+
value={formatCount(statusBar()!.warnings)}
|
|
795
|
+
tone={statusBar()!.warnings! > 0 ? "warn" : "muted"}
|
|
796
|
+
/>
|
|
797
|
+
)}
|
|
798
|
+
{statusBar()!.dead_code !== undefined && (
|
|
799
|
+
<StatRow
|
|
800
|
+
theme={props.theme}
|
|
801
|
+
label="Dead Code"
|
|
802
|
+
value={formatCount(statusBar()!.dead_code)}
|
|
803
|
+
tone="muted"
|
|
804
|
+
/>
|
|
805
|
+
)}
|
|
806
|
+
{statusBar()!.unused_exports !== undefined && (
|
|
807
|
+
<StatRow
|
|
808
|
+
theme={props.theme}
|
|
809
|
+
label="Unused Exports"
|
|
810
|
+
value={formatCount(statusBar()!.unused_exports)}
|
|
811
|
+
tone="muted"
|
|
812
|
+
/>
|
|
813
|
+
)}
|
|
814
|
+
{statusBar()!.duplicates !== undefined && (
|
|
815
|
+
<StatRow
|
|
816
|
+
theme={props.theme}
|
|
817
|
+
label="Duplicates"
|
|
818
|
+
value={formatCount(statusBar()!.duplicates)}
|
|
819
|
+
tone="muted"
|
|
820
|
+
/>
|
|
821
|
+
)}
|
|
822
|
+
{statusBar()!.todos !== undefined && (
|
|
823
|
+
<StatRow
|
|
824
|
+
theme={props.theme}
|
|
825
|
+
label="TODOs"
|
|
826
|
+
value={formatCount(statusBar()!.todos)}
|
|
827
|
+
tone="muted"
|
|
828
|
+
/>
|
|
829
|
+
)}
|
|
806
830
|
</>
|
|
807
831
|
)}
|
|
808
832
|
|
|
@@ -12,7 +12,7 @@ import { createElement as _$createElement } from "opentui:runtime-module:%40open
|
|
|
12
12
|
import { createMemo, createSignal, onCleanup } from "opentui:runtime-module:solid-js";
|
|
13
13
|
import { version as packageVersion } from "../../package.json";
|
|
14
14
|
import { AftRpcClient } from "../shared/rpc-client";
|
|
15
|
-
import { coerceAftStatus, formatBytes, formatSemanticIndexStatus, formatSemanticRefreshing } from "../shared/status";
|
|
15
|
+
import { coerceAftStatus, formatBytes, formatCacheRoleLabel, formatSemanticIndexStatus, formatSemanticRefreshing } from "../shared/status";
|
|
16
16
|
import { createDebouncedStatusRefresh, refreshAftTuiSocketScope, startAftTuiSocket, stopAftTuiSocket, subscribeStatusInvalidations } from "./notification-socket";
|
|
17
17
|
import { createAftSidebarSlot, formatCompressionSidebarRows, isSnapshotForContext, resolveTuiStorageDir, shouldSuppressUninitializedDowngrade } from "./sidebar";
|
|
18
18
|
|
|
@@ -188,9 +188,9 @@ const StatusDialog = props => {
|
|
|
188
188
|
}
|
|
189
189
|
});
|
|
190
190
|
|
|
191
|
-
// Visual cache-role badge: main is accent
|
|
192
|
-
//
|
|
193
|
-
const cacheRoleTone = role => role === "main" ? "accent" :
|
|
191
|
+
// Visual cache-role badge: main is accent. Worktree/read_only borrow the
|
|
192
|
+
// shared repo index — muted, not warning, so it is not read as a failure.
|
|
193
|
+
const cacheRoleTone = role => role === "main" ? "accent" : "muted";
|
|
194
194
|
// Reuse the sidebar's label/value formatter so the dialog and sidebar
|
|
195
195
|
// render identical text (e.g. "Session" / "-174,489 tokens, 59% reduction").
|
|
196
196
|
// The earlier `formatCompressionDialogRows` returned padded strings that
|
|
@@ -288,7 +288,7 @@ const StatusDialog = props => {
|
|
|
288
288
|
},
|
|
289
289
|
label: "Cache role",
|
|
290
290
|
get value() {
|
|
291
|
-
return status().cache_role;
|
|
291
|
+
return formatCacheRoleLabel(status().cache_role);
|
|
292
292
|
},
|
|
293
293
|
get tone() {
|
|
294
294
|
return cacheRoleTone(status().cache_role);
|
|
@@ -696,70 +696,88 @@ const StatusDialog = props => {
|
|
|
696
696
|
_$setProp(_el$53, "marginTop", 1);
|
|
697
697
|
_$insertNode(_el$54, _el$55);
|
|
698
698
|
_$insert(_el$55, () => status().status_bar.tier2_stale ? "Code Health ~" : "Code Health");
|
|
699
|
-
_$insert(_el$53,
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
699
|
+
_$insert(_el$53, (() => {
|
|
700
|
+
var _c$14 = _$memo(() => status().status_bar.errors !== undefined);
|
|
701
|
+
return () => _c$14() ? _$createComponent(R, {
|
|
702
|
+
get theme() {
|
|
703
|
+
return t();
|
|
704
|
+
},
|
|
705
|
+
label: "Errors",
|
|
706
|
+
get value() {
|
|
707
|
+
return formatCountShort(status().status_bar.errors);
|
|
708
|
+
},
|
|
709
|
+
get tone() {
|
|
710
|
+
return status().status_bar.errors > 0 ? "err" : "muted";
|
|
711
|
+
}
|
|
712
|
+
}) : null;
|
|
713
|
+
})(), null);
|
|
714
|
+
_$insert(_el$53, (() => {
|
|
715
|
+
var _c$15 = _$memo(() => status().status_bar.warnings !== undefined);
|
|
716
|
+
return () => _c$15() ? _$createComponent(R, {
|
|
717
|
+
get theme() {
|
|
718
|
+
return t();
|
|
719
|
+
},
|
|
720
|
+
label: "Warnings",
|
|
721
|
+
get value() {
|
|
722
|
+
return formatCountShort(status().status_bar.warnings);
|
|
723
|
+
},
|
|
724
|
+
get tone() {
|
|
725
|
+
return status().status_bar.warnings > 0 ? "warn" : "muted";
|
|
726
|
+
}
|
|
727
|
+
}) : null;
|
|
728
|
+
})(), null);
|
|
729
|
+
_$insert(_el$53, (() => {
|
|
730
|
+
var _c$16 = _$memo(() => status().status_bar.dead_code !== undefined);
|
|
731
|
+
return () => _c$16() ? _$createComponent(R, {
|
|
732
|
+
get theme() {
|
|
733
|
+
return t();
|
|
734
|
+
},
|
|
735
|
+
label: "Dead Code",
|
|
736
|
+
get value() {
|
|
737
|
+
return formatCountShort(status().status_bar.dead_code);
|
|
738
|
+
},
|
|
739
|
+
tone: "muted"
|
|
740
|
+
}) : null;
|
|
741
|
+
})(), null);
|
|
742
|
+
_$insert(_el$53, (() => {
|
|
743
|
+
var _c$17 = _$memo(() => status().status_bar.unused_exports !== undefined);
|
|
744
|
+
return () => _c$17() ? _$createComponent(R, {
|
|
745
|
+
get theme() {
|
|
746
|
+
return t();
|
|
747
|
+
},
|
|
748
|
+
label: "Unused Exports",
|
|
749
|
+
get value() {
|
|
750
|
+
return formatCountShort(status().status_bar.unused_exports);
|
|
751
|
+
},
|
|
752
|
+
tone: "muted"
|
|
753
|
+
}) : null;
|
|
754
|
+
})(), null);
|
|
755
|
+
_$insert(_el$53, (() => {
|
|
756
|
+
var _c$18 = _$memo(() => status().status_bar.duplicates !== undefined);
|
|
757
|
+
return () => _c$18() ? _$createComponent(R, {
|
|
758
|
+
get theme() {
|
|
759
|
+
return t();
|
|
760
|
+
},
|
|
761
|
+
label: "Duplicates",
|
|
762
|
+
get value() {
|
|
763
|
+
return formatCountShort(status().status_bar.duplicates);
|
|
764
|
+
},
|
|
765
|
+
tone: "muted"
|
|
766
|
+
}) : null;
|
|
767
|
+
})(), null);
|
|
768
|
+
_$insert(_el$53, (() => {
|
|
769
|
+
var _c$19 = _$memo(() => status().status_bar.todos !== undefined);
|
|
770
|
+
return () => _c$19() ? _$createComponent(R, {
|
|
771
|
+
get theme() {
|
|
772
|
+
return t();
|
|
773
|
+
},
|
|
774
|
+
label: "TODOs",
|
|
775
|
+
get value() {
|
|
776
|
+
return formatCountShort(status().status_bar.todos);
|
|
777
|
+
},
|
|
778
|
+
tone: "muted"
|
|
779
|
+
}) : null;
|
|
780
|
+
})(), null);
|
|
763
781
|
_$effect(_$p => _$setProp(_el$54, "fg", t().text, _$p));
|
|
764
782
|
return _el$53;
|
|
765
783
|
})() : null;
|