@cortexkit/aft-opencode 0.26.1 → 0.26.2
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/index.js +21 -14
- package/dist/shared/status.d.ts +11 -0
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/tui.js +66 -16
- package/package.json +7 -7
- package/src/shared/status.ts +15 -0
- package/src/tui/sidebar.tsx +50 -5
package/dist/index.js
CHANGED
|
@@ -9382,15 +9382,6 @@ import { homedir as homedir3 } from "os";
|
|
|
9382
9382
|
var DEFAULT_IDLE_TIMEOUT_MS = Infinity;
|
|
9383
9383
|
var DEFAULT_MAX_POOL_SIZE = 8;
|
|
9384
9384
|
var CLEANUP_INTERVAL_MS = 60 * 1000;
|
|
9385
|
-
|
|
9386
|
-
class HomeProjectRootError extends Error {
|
|
9387
|
-
projectRoot;
|
|
9388
|
-
constructor(projectRoot) {
|
|
9389
|
-
super(`aft refuses to spawn a bridge with project_root=${projectRoot} (user home directory). ` + `Open OpenCode/Pi from a project subdirectory instead, or set the session's ` + `directory to a real project root.`);
|
|
9390
|
-
this.projectRoot = projectRoot;
|
|
9391
|
-
this.name = "HomeProjectRootError";
|
|
9392
|
-
}
|
|
9393
|
-
}
|
|
9394
9385
|
function canonicalHomeDir() {
|
|
9395
9386
|
try {
|
|
9396
9387
|
const home = homedir3();
|
|
@@ -9453,9 +9444,6 @@ class BridgePool {
|
|
|
9453
9444
|
}
|
|
9454
9445
|
getBridge(projectRoot) {
|
|
9455
9446
|
const key = normalizeKey(projectRoot);
|
|
9456
|
-
if (isHomeDirectoryRoot(key)) {
|
|
9457
|
-
throw new HomeProjectRootError(key);
|
|
9458
|
-
}
|
|
9459
9447
|
const existing = this.bridges.get(key);
|
|
9460
9448
|
if (existing) {
|
|
9461
9449
|
existing.lastUsed = Date.now();
|
|
@@ -9613,6 +9601,21 @@ function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
|
9613
9601
|
function normalizeBareVersion(version) {
|
|
9614
9602
|
return version.startsWith("v") ? version.slice(1) : version;
|
|
9615
9603
|
}
|
|
9604
|
+
function homeDirFromEnv(env) {
|
|
9605
|
+
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir4();
|
|
9606
|
+
}
|
|
9607
|
+
function cacheDirFromEnv(env) {
|
|
9608
|
+
if (process.platform === "win32") {
|
|
9609
|
+
const base2 = env.LOCALAPPDATA || env.APPDATA || join4(homeDirFromEnv(env), "AppData", "Local");
|
|
9610
|
+
return join4(base2, "aft", "bin");
|
|
9611
|
+
}
|
|
9612
|
+
const base = env.XDG_CACHE_HOME || join4(homeDirFromEnv(env), ".cache");
|
|
9613
|
+
return join4(base, "aft", "bin");
|
|
9614
|
+
}
|
|
9615
|
+
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
9616
|
+
const binaryPath = join4(cacheDirFromEnv(env), version, `aft${ext}`);
|
|
9617
|
+
return existsSync3(binaryPath) ? binaryPath : null;
|
|
9618
|
+
}
|
|
9616
9619
|
function isExpectedCachedBinary(binaryPath, expectedVersion) {
|
|
9617
9620
|
const expected = normalizeBareVersion(expectedVersion);
|
|
9618
9621
|
const actual = readBinaryVersion(binaryPath);
|
|
@@ -9634,6 +9637,7 @@ function platformKey(platform = process.platform, arch = process.arch) {
|
|
|
9634
9637
|
}
|
|
9635
9638
|
function findBinarySync(expectedVersion) {
|
|
9636
9639
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
9640
|
+
const env = { ...process.env };
|
|
9637
9641
|
const pluginVersion = expectedVersion ?? (() => {
|
|
9638
9642
|
try {
|
|
9639
9643
|
const req = createRequire(import.meta.url);
|
|
@@ -9644,7 +9648,7 @@ function findBinarySync(expectedVersion) {
|
|
|
9644
9648
|
})();
|
|
9645
9649
|
if (pluginVersion) {
|
|
9646
9650
|
const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
|
|
9647
|
-
const versionCached =
|
|
9651
|
+
const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
|
|
9648
9652
|
if (versionCached && isExpectedCachedBinary(versionCached, pluginVersion))
|
|
9649
9653
|
return versionCached;
|
|
9650
9654
|
}
|
|
@@ -9669,12 +9673,13 @@ function findBinarySync(expectedVersion) {
|
|
|
9669
9673
|
const whichCmd = process.platform === "win32" ? "where aft" : "which aft";
|
|
9670
9674
|
const result = execSync(whichCmd, {
|
|
9671
9675
|
encoding: "utf-8",
|
|
9676
|
+
env,
|
|
9672
9677
|
stdio: ["pipe", "pipe", "pipe"]
|
|
9673
9678
|
}).trim();
|
|
9674
9679
|
if (result)
|
|
9675
9680
|
return result;
|
|
9676
9681
|
} catch {}
|
|
9677
|
-
const cargoPath = join4(
|
|
9682
|
+
const cargoPath = join4(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
9678
9683
|
if (existsSync3(cargoPath))
|
|
9679
9684
|
return cargoPath;
|
|
9680
9685
|
return null;
|
|
@@ -27490,6 +27495,8 @@ function coerceAftStatus(response) {
|
|
|
27490
27495
|
project_root: readNullableString(response.project_root),
|
|
27491
27496
|
canonical_root: readNullableString(response.canonical_root),
|
|
27492
27497
|
cache_role: readString(response.cache_role, "not_initialized"),
|
|
27498
|
+
degraded: readBoolean(response.degraded),
|
|
27499
|
+
degraded_reasons: Array.isArray(response.degraded_reasons) ? response.degraded_reasons.filter((r) => typeof r === "string") : [],
|
|
27493
27500
|
features: {
|
|
27494
27501
|
format_on_edit: readBoolean(features.format_on_edit),
|
|
27495
27502
|
validate_on_edit: readString(features.validate_on_edit, "off"),
|
package/dist/shared/status.d.ts
CHANGED
|
@@ -3,6 +3,17 @@ export interface AftStatusSnapshot {
|
|
|
3
3
|
project_root: string | null;
|
|
4
4
|
canonical_root: string | null;
|
|
5
5
|
cache_role: string;
|
|
6
|
+
/**
|
|
7
|
+
* True when at least one heavy AFT subsystem has been auto-disabled for
|
|
8
|
+
* the current project root. `degraded_reasons` enumerates why (e.g.
|
|
9
|
+
* `["home_root"]`, `["search_too_many_files:20000"]`). The sidebar / TUI
|
|
10
|
+
* dialog surface this so users know `aft_search`, `aft_navigate` etc.
|
|
11
|
+
* won't return results from this session and can choose to open a
|
|
12
|
+
* project subdirectory instead.
|
|
13
|
+
*/
|
|
14
|
+
degraded: boolean;
|
|
15
|
+
/** Machine-readable degraded-mode reasons. Empty when `degraded === false`. */
|
|
16
|
+
degraded_reasons: string[];
|
|
6
17
|
features: {
|
|
7
18
|
format_on_edit: boolean;
|
|
8
19
|
validate_on_edit: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/shared/status.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE;QACR,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,wBAAwB,EAAE,OAAO,CAAC;QAClC,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;IACF,cAAc,EAAE;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAkCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/shared/status.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,+EAA+E;IAC/E,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE;QACR,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,wBAAwB,EAAE,OAAO,CAAC;QAClC,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;IACF,cAAc,EAAE;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAkCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,CAiEpF;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuE3E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA0EtE"}
|
package/dist/tui.js
CHANGED
|
@@ -4,7 +4,7 @@ import { createMemo as createMemo2, createSignal as createSignal2, onCleanup as
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@cortexkit/aft-opencode",
|
|
7
|
-
version: "0.26.
|
|
7
|
+
version: "0.26.2",
|
|
8
8
|
type: "module",
|
|
9
9
|
description: "OpenCode plugin for Agent File Tools (AFT) \u2014 tree-sitter and lsp powered code analysis",
|
|
10
10
|
main: "dist/index.js",
|
|
@@ -32,7 +32,7 @@ var package_default = {
|
|
|
32
32
|
},
|
|
33
33
|
dependencies: {
|
|
34
34
|
"@clack/prompts": "^1.2.0",
|
|
35
|
-
"@cortexkit/aft-bridge": "0.26.
|
|
35
|
+
"@cortexkit/aft-bridge": "0.26.2",
|
|
36
36
|
"@opencode-ai/plugin": "^1.14.39",
|
|
37
37
|
"@opencode-ai/sdk": "^1.14.39",
|
|
38
38
|
"comment-json": "^4.6.2",
|
|
@@ -40,11 +40,11 @@ var package_default = {
|
|
|
40
40
|
zod: "^4.1.8"
|
|
41
41
|
},
|
|
42
42
|
optionalDependencies: {
|
|
43
|
-
"@cortexkit/aft-darwin-arm64": "0.26.
|
|
44
|
-
"@cortexkit/aft-darwin-x64": "0.26.
|
|
45
|
-
"@cortexkit/aft-linux-arm64": "0.26.
|
|
46
|
-
"@cortexkit/aft-linux-x64": "0.26.
|
|
47
|
-
"@cortexkit/aft-win32-x64": "0.26.
|
|
43
|
+
"@cortexkit/aft-darwin-arm64": "0.26.2",
|
|
44
|
+
"@cortexkit/aft-darwin-x64": "0.26.2",
|
|
45
|
+
"@cortexkit/aft-linux-arm64": "0.26.2",
|
|
46
|
+
"@cortexkit/aft-linux-x64": "0.26.2",
|
|
47
|
+
"@cortexkit/aft-win32-x64": "0.26.2"
|
|
48
48
|
},
|
|
49
49
|
devDependencies: {
|
|
50
50
|
"@types/node": "^22.0.0",
|
|
@@ -334,6 +334,8 @@ function coerceAftStatus(response) {
|
|
|
334
334
|
project_root: readNullableString(response.project_root),
|
|
335
335
|
canonical_root: readNullableString(response.canonical_root),
|
|
336
336
|
cache_role: readString(response.cache_role, "not_initialized"),
|
|
337
|
+
degraded: readBoolean(response.degraded),
|
|
338
|
+
degraded_reasons: Array.isArray(response.degraded_reasons) ? response.degraded_reasons.filter((r) => typeof r === "string") : [],
|
|
337
339
|
features: {
|
|
338
340
|
format_on_edit: readBoolean(features.format_on_edit),
|
|
339
341
|
validate_on_edit: readString(features.validate_on_edit, "off"),
|
|
@@ -560,6 +562,25 @@ var SidebarContent = (props) => {
|
|
|
560
562
|
const semanticStatus = () => statusDisplay(s()?.semantic_index?.status ?? "disabled");
|
|
561
563
|
const trigramBytes = () => s()?.disk?.trigram_disk_bytes ?? 0;
|
|
562
564
|
const semanticBytes = () => s()?.disk?.semantic_disk_bytes ?? 0;
|
|
565
|
+
const degradedReasonLabel = (reason) => {
|
|
566
|
+
if (reason === "home_root") {
|
|
567
|
+
return "project root is your home directory";
|
|
568
|
+
}
|
|
569
|
+
if (reason.startsWith("search_too_many_files:")) {
|
|
570
|
+
const threshold = reason.split(":")[1] ?? "20000";
|
|
571
|
+
return `project exceeds ${threshold} files`;
|
|
572
|
+
}
|
|
573
|
+
return reason;
|
|
574
|
+
};
|
|
575
|
+
const degradedSummary = () => {
|
|
576
|
+
const snap = s();
|
|
577
|
+
if (!snap?.degraded)
|
|
578
|
+
return null;
|
|
579
|
+
const reasons = snap.degraded_reasons ?? [];
|
|
580
|
+
if (reasons.length === 0)
|
|
581
|
+
return null;
|
|
582
|
+
return reasons.map(degradedReasonLabel).join("; ");
|
|
583
|
+
};
|
|
563
584
|
return /* @__PURE__ */ jsxDEV("box", {
|
|
564
585
|
width: "100%",
|
|
565
586
|
flexDirection: "column",
|
|
@@ -576,16 +597,34 @@ var SidebarContent = (props) => {
|
|
|
576
597
|
alignItems: "center",
|
|
577
598
|
children: [
|
|
578
599
|
/* @__PURE__ */ jsxDEV("box", {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
600
|
+
flexDirection: "row",
|
|
601
|
+
alignItems: "center",
|
|
602
|
+
children: [
|
|
603
|
+
/* @__PURE__ */ jsxDEV("box", {
|
|
604
|
+
paddingLeft: 1,
|
|
605
|
+
paddingRight: 1,
|
|
606
|
+
backgroundColor: props.theme.accent,
|
|
607
|
+
children: /* @__PURE__ */ jsxDEV("text", {
|
|
608
|
+
fg: props.theme.background,
|
|
609
|
+
children: /* @__PURE__ */ jsxDEV("b", {
|
|
610
|
+
children: "AFT"
|
|
611
|
+
}, undefined, false, undefined, this)
|
|
612
|
+
}, undefined, false, undefined, this)
|
|
613
|
+
}, undefined, false, undefined, this),
|
|
614
|
+
s()?.degraded && /* @__PURE__ */ jsxDEV("box", {
|
|
615
|
+
paddingLeft: 1,
|
|
616
|
+
paddingRight: 1,
|
|
617
|
+
marginLeft: 1,
|
|
618
|
+
backgroundColor: props.theme.warning,
|
|
619
|
+
children: /* @__PURE__ */ jsxDEV("text", {
|
|
620
|
+
fg: props.theme.background,
|
|
621
|
+
children: /* @__PURE__ */ jsxDEV("b", {
|
|
622
|
+
children: "DEGRADED"
|
|
623
|
+
}, undefined, false, undefined, this)
|
|
624
|
+
}, undefined, false, undefined, this)
|
|
586
625
|
}, undefined, false, undefined, this)
|
|
587
|
-
|
|
588
|
-
}, undefined,
|
|
626
|
+
]
|
|
627
|
+
}, undefined, true, undefined, this),
|
|
589
628
|
/* @__PURE__ */ jsxDEV("text", {
|
|
590
629
|
fg: props.theme.textMuted,
|
|
591
630
|
children: [
|
|
@@ -595,6 +634,17 @@ var SidebarContent = (props) => {
|
|
|
595
634
|
}, undefined, true, undefined, this)
|
|
596
635
|
]
|
|
597
636
|
}, undefined, true, undefined, this),
|
|
637
|
+
s()?.degraded && degradedSummary() && /* @__PURE__ */ jsxDEV("box", {
|
|
638
|
+
marginTop: 1,
|
|
639
|
+
width: "100%",
|
|
640
|
+
children: /* @__PURE__ */ jsxDEV("text", {
|
|
641
|
+
fg: props.theme.warning,
|
|
642
|
+
children: [
|
|
643
|
+
"\u26A0 ",
|
|
644
|
+
degradedSummary()
|
|
645
|
+
]
|
|
646
|
+
}, undefined, true, undefined, this)
|
|
647
|
+
}, undefined, false, undefined, this),
|
|
598
648
|
/* @__PURE__ */ jsxDEV(SectionHeader, {
|
|
599
649
|
theme: props.theme,
|
|
600
650
|
title: "Search Index"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/aft-opencode",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@clack/prompts": "^1.2.0",
|
|
31
|
-
"@cortexkit/aft-bridge": "0.26.
|
|
31
|
+
"@cortexkit/aft-bridge": "0.26.2",
|
|
32
32
|
"@opencode-ai/plugin": "^1.14.39",
|
|
33
33
|
"@opencode-ai/sdk": "^1.14.39",
|
|
34
34
|
"comment-json": "^4.6.2",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"zod": "^4.1.8"
|
|
37
37
|
},
|
|
38
38
|
"optionalDependencies": {
|
|
39
|
-
"@cortexkit/aft-darwin-arm64": "0.26.
|
|
40
|
-
"@cortexkit/aft-darwin-x64": "0.26.
|
|
41
|
-
"@cortexkit/aft-linux-arm64": "0.26.
|
|
42
|
-
"@cortexkit/aft-linux-x64": "0.26.
|
|
43
|
-
"@cortexkit/aft-win32-x64": "0.26.
|
|
39
|
+
"@cortexkit/aft-darwin-arm64": "0.26.2",
|
|
40
|
+
"@cortexkit/aft-darwin-x64": "0.26.2",
|
|
41
|
+
"@cortexkit/aft-linux-arm64": "0.26.2",
|
|
42
|
+
"@cortexkit/aft-linux-x64": "0.26.2",
|
|
43
|
+
"@cortexkit/aft-win32-x64": "0.26.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^22.0.0",
|
package/src/shared/status.ts
CHANGED
|
@@ -3,6 +3,17 @@ export interface AftStatusSnapshot {
|
|
|
3
3
|
project_root: string | null;
|
|
4
4
|
canonical_root: string | null;
|
|
5
5
|
cache_role: string;
|
|
6
|
+
/**
|
|
7
|
+
* True when at least one heavy AFT subsystem has been auto-disabled for
|
|
8
|
+
* the current project root. `degraded_reasons` enumerates why (e.g.
|
|
9
|
+
* `["home_root"]`, `["search_too_many_files:20000"]`). The sidebar / TUI
|
|
10
|
+
* dialog surface this so users know `aft_search`, `aft_navigate` etc.
|
|
11
|
+
* won't return results from this session and can choose to open a
|
|
12
|
+
* project subdirectory instead.
|
|
13
|
+
*/
|
|
14
|
+
degraded: boolean;
|
|
15
|
+
/** Machine-readable degraded-mode reasons. Empty when `degraded === false`. */
|
|
16
|
+
degraded_reasons: string[];
|
|
6
17
|
features: {
|
|
7
18
|
format_on_edit: boolean;
|
|
8
19
|
validate_on_edit: string;
|
|
@@ -112,6 +123,10 @@ export function coerceAftStatus(response: Record<string, unknown>): AftStatusSna
|
|
|
112
123
|
project_root: readNullableString(response.project_root),
|
|
113
124
|
canonical_root: readNullableString(response.canonical_root),
|
|
114
125
|
cache_role: readString(response.cache_role, "not_initialized"),
|
|
126
|
+
degraded: readBoolean(response.degraded),
|
|
127
|
+
degraded_reasons: Array.isArray(response.degraded_reasons)
|
|
128
|
+
? response.degraded_reasons.filter((r): r is string => typeof r === "string")
|
|
129
|
+
: [],
|
|
115
130
|
features: {
|
|
116
131
|
format_on_edit: readBoolean(features.format_on_edit),
|
|
117
132
|
validate_on_edit: readString(features.validate_on_edit, "off"),
|
package/src/tui/sidebar.tsx
CHANGED
|
@@ -226,6 +226,28 @@ const SidebarContent = (props: {
|
|
|
226
226
|
const trigramBytes = () => s()?.disk?.trigram_disk_bytes ?? 0;
|
|
227
227
|
const semanticBytes = () => s()?.disk?.semantic_disk_bytes ?? 0;
|
|
228
228
|
|
|
229
|
+
// Degraded-mode reason → human-readable hint. Distinct strings per reason
|
|
230
|
+
// because the UX direction is different: "home_root" tells the user to
|
|
231
|
+
// open a real project subdirectory, "search_too_many_files" tells them the
|
|
232
|
+
// tree is too big for full indexing.
|
|
233
|
+
const degradedReasonLabel = (reason: string): string => {
|
|
234
|
+
if (reason === "home_root") {
|
|
235
|
+
return "project root is your home directory";
|
|
236
|
+
}
|
|
237
|
+
if (reason.startsWith("search_too_many_files:")) {
|
|
238
|
+
const threshold = reason.split(":")[1] ?? "20000";
|
|
239
|
+
return `project exceeds ${threshold} files`;
|
|
240
|
+
}
|
|
241
|
+
return reason; // unknown reason — surface verbatim so users can grep logs
|
|
242
|
+
};
|
|
243
|
+
const degradedSummary = () => {
|
|
244
|
+
const snap = s();
|
|
245
|
+
if (!snap?.degraded) return null;
|
|
246
|
+
const reasons = snap.degraded_reasons ?? [];
|
|
247
|
+
if (reasons.length === 0) return null;
|
|
248
|
+
return reasons.map(degradedReasonLabel).join("; ");
|
|
249
|
+
};
|
|
250
|
+
|
|
229
251
|
return (
|
|
230
252
|
<box
|
|
231
253
|
width="100%"
|
|
@@ -237,16 +259,39 @@ const SidebarContent = (props: {
|
|
|
237
259
|
paddingLeft={1}
|
|
238
260
|
paddingRight={1}
|
|
239
261
|
>
|
|
240
|
-
{/* Header: AFT badge + binary version */}
|
|
262
|
+
{/* Header: AFT badge + binary version + degraded badge (when active) */}
|
|
241
263
|
<box flexDirection="row" justifyContent="space-between" alignItems="center">
|
|
242
|
-
<box
|
|
243
|
-
<
|
|
244
|
-
<
|
|
245
|
-
|
|
264
|
+
<box flexDirection="row" alignItems="center">
|
|
265
|
+
<box paddingLeft={1} paddingRight={1} backgroundColor={props.theme.accent}>
|
|
266
|
+
<text fg={props.theme.background}>
|
|
267
|
+
<b>AFT</b>
|
|
268
|
+
</text>
|
|
269
|
+
</box>
|
|
270
|
+
{s()?.degraded && (
|
|
271
|
+
<box
|
|
272
|
+
paddingLeft={1}
|
|
273
|
+
paddingRight={1}
|
|
274
|
+
marginLeft={1}
|
|
275
|
+
backgroundColor={props.theme.warning}
|
|
276
|
+
>
|
|
277
|
+
<text fg={props.theme.background}>
|
|
278
|
+
<b>DEGRADED</b>
|
|
279
|
+
</text>
|
|
280
|
+
</box>
|
|
281
|
+
)}
|
|
246
282
|
</box>
|
|
247
283
|
<text fg={props.theme.textMuted}>v{s()?.version ?? props.pluginVersion}</text>
|
|
248
284
|
</box>
|
|
249
285
|
|
|
286
|
+
{/* Degraded reason — explains why heavy tools (aft_search, aft_navigate)
|
|
287
|
+
are disabled. Surface this prominently so users know to open a real
|
|
288
|
+
project subdirectory if they want full features. */}
|
|
289
|
+
{s()?.degraded && degradedSummary() && (
|
|
290
|
+
<box marginTop={1} width="100%">
|
|
291
|
+
<text fg={props.theme.warning}>⚠ {degradedSummary()}</text>
|
|
292
|
+
</box>
|
|
293
|
+
)}
|
|
294
|
+
|
|
250
295
|
{/* Search index */}
|
|
251
296
|
<SectionHeader theme={props.theme} title="Search Index" />
|
|
252
297
|
<StatRow
|