@cortexkit/aft-opencode 0.26.4 → 0.27.1
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/bg-notifications.d.ts +3 -0
- package/dist/bg-notifications.d.ts.map +1 -1
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/configure-warnings.d.ts +2 -0
- package/dist/configure-warnings.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +639 -500
- package/dist/lsp-auto-install.d.ts +1 -1
- package/dist/lsp-auto-install.d.ts.map +1 -1
- package/dist/notifications.d.ts +2 -0
- package/dist/notifications.d.ts.map +1 -1
- package/dist/shared/status.d.ts +12 -0
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/dist/tui.js +94 -10
- package/package.json +8 -7
- package/src/shared/status.ts +34 -0
- package/src/tui/index.tsx +35 -2
- package/src/tui/sidebar.tsx +66 -2
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* installed, log a warning and keep the existing version.
|
|
20
20
|
* Otherwise skip + warn.
|
|
21
21
|
*
|
|
22
|
-
* 3. Spawn `
|
|
22
|
+
* 3. Spawn `npm install --no-save <pkg>@<version> --ignore-scripts`
|
|
23
23
|
* in the background. Drop a lockfile while running. Log progress.
|
|
24
24
|
*
|
|
25
25
|
* 4. The newly-installed binary will be picked up on the user's NEXT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lsp-auto-install.d.ts","sourceRoot":"","sources":["../src/lsp-auto-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAwBH,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,kGAAkG;IAClG,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gDAAgD;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;;;OAOG;IACH,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C;;;;;;;;;OASG;IACH,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAkDD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM/D;
|
|
1
|
+
{"version":3,"file":"lsp-auto-install.d.ts","sourceRoot":"","sources":["../src/lsp-auto-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAwBH,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,kGAAkG;IAClG,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gDAAgD;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;;;OAOG;IACH,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C;;;;;;;;;OASG;IACH,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAkDD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM/D;AAqXD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,iBAAiB,EACzB,SAAS,GAAE,OAAO,KAAa,GAC9B,iBAAiB,CAwEnB"}
|
package/dist/notifications.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* Messages are identified by markers and cleaned up on subsequent startups
|
|
14
14
|
* when no longer relevant (Desktop only — TUI toasts are inherently transient).
|
|
15
15
|
*/
|
|
16
|
+
import type { BinaryBridge } from "@cortexkit/aft-bridge";
|
|
16
17
|
type SdkMessage = {
|
|
17
18
|
info?: {
|
|
18
19
|
id?: string;
|
|
@@ -50,6 +51,7 @@ export interface ConfigureWarning {
|
|
|
50
51
|
export interface ConfigureWarningOptions {
|
|
51
52
|
client: unknown;
|
|
52
53
|
sessionId: string;
|
|
54
|
+
bridge: Pick<BinaryBridge, "send">;
|
|
53
55
|
storageDir: string;
|
|
54
56
|
pluginVersion: string;
|
|
55
57
|
projectRoot?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAmI1D,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACpE,CAAC;AAyBF,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBvB;AAqED,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,yBAAyB,GAAG,uBAAuB,GAAG,oBAAoB,CAAC;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW3F;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C1F;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA2Cf;AA4ED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,uBAAuB,EAC7B,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C9E"}
|
package/dist/shared/status.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
export interface StatusCompressionAggregate {
|
|
2
|
+
events: number;
|
|
3
|
+
original_tokens: number;
|
|
4
|
+
compressed_tokens: number;
|
|
5
|
+
savings_tokens: number;
|
|
6
|
+
}
|
|
7
|
+
export interface StatusCompression {
|
|
8
|
+
project: StatusCompressionAggregate;
|
|
9
|
+
session: StatusCompressionAggregate;
|
|
10
|
+
}
|
|
1
11
|
export interface AftStatusSnapshot {
|
|
2
12
|
version: string;
|
|
3
13
|
project_root: string | null;
|
|
@@ -57,6 +67,8 @@ export interface AftStatusSnapshot {
|
|
|
57
67
|
tracked_files: number;
|
|
58
68
|
checkpoints: number;
|
|
59
69
|
};
|
|
70
|
+
/** Compression aggregate passthrough; rendering is added separately. */
|
|
71
|
+
compression?: StatusCompression;
|
|
60
72
|
/**
|
|
61
73
|
* Human-readable explanation for a synthetic snapshot (e.g.
|
|
62
74
|
* `cache_role === "not_initialized"`). When the plugin returns a placeholder
|
|
@@ -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;;;;;;;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;IACF;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/shared/status.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,0BAA0B,CAAC;IACpC,OAAO,EAAE,0BAA0B,CAAC;CACrC;AAED,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;IACF,wEAAwE;IACxE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAqDD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,CAmEpF;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuE3E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA0EtE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuEjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AAqRtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA+JjE;
|
|
1
|
+
{"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuEjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AAqRtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA+JjE;AAmmCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAwB/E;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAgGnF"}
|
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.
|
|
7
|
+
version: "0.27.1",
|
|
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",
|
|
@@ -28,11 +28,12 @@ var package_default = {
|
|
|
28
28
|
test: "bun test",
|
|
29
29
|
"test:e2e": "bun test src/__tests__/e2e/",
|
|
30
30
|
lint: "biome check src",
|
|
31
|
+
schema: "bun scripts/build-schema.ts",
|
|
31
32
|
prepublishOnly: "bun run build"
|
|
32
33
|
},
|
|
33
34
|
dependencies: {
|
|
34
35
|
"@clack/prompts": "^1.2.0",
|
|
35
|
-
"@cortexkit/aft-bridge": "0.
|
|
36
|
+
"@cortexkit/aft-bridge": "0.27.1",
|
|
36
37
|
"@opencode-ai/plugin": "^1.15.5",
|
|
37
38
|
"@opencode-ai/sdk": "^1.15.5",
|
|
38
39
|
"comment-json": "^4.6.2",
|
|
@@ -40,11 +41,11 @@ var package_default = {
|
|
|
40
41
|
zod: "^4.1.8"
|
|
41
42
|
},
|
|
42
43
|
optionalDependencies: {
|
|
43
|
-
"@cortexkit/aft-darwin-arm64": "0.
|
|
44
|
-
"@cortexkit/aft-darwin-x64": "0.
|
|
45
|
-
"@cortexkit/aft-linux-arm64": "0.
|
|
46
|
-
"@cortexkit/aft-linux-x64": "0.
|
|
47
|
-
"@cortexkit/aft-win32-x64": "0.
|
|
44
|
+
"@cortexkit/aft-darwin-arm64": "0.27.1",
|
|
45
|
+
"@cortexkit/aft-darwin-x64": "0.27.1",
|
|
46
|
+
"@cortexkit/aft-linux-arm64": "0.27.1",
|
|
47
|
+
"@cortexkit/aft-linux-x64": "0.27.1",
|
|
48
|
+
"@cortexkit/aft-win32-x64": "0.27.1"
|
|
48
49
|
},
|
|
49
50
|
devDependencies: {
|
|
50
51
|
"@types/node": "^22.0.0",
|
|
@@ -304,6 +305,24 @@ function readNumber(value, fallback = 0) {
|
|
|
304
305
|
function readOptionalNumber(value) {
|
|
305
306
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
306
307
|
}
|
|
308
|
+
function readCompressionAggregate(value) {
|
|
309
|
+
const aggregate = asRecord(value);
|
|
310
|
+
return {
|
|
311
|
+
events: readNumber(aggregate.events),
|
|
312
|
+
original_tokens: readNumber(aggregate.original_tokens),
|
|
313
|
+
compressed_tokens: readNumber(aggregate.compressed_tokens),
|
|
314
|
+
savings_tokens: readNumber(aggregate.savings_tokens)
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function readCompression(value) {
|
|
318
|
+
if (typeof value !== "object" || value === null)
|
|
319
|
+
return;
|
|
320
|
+
const compression = asRecord(value);
|
|
321
|
+
return {
|
|
322
|
+
project: readCompressionAggregate(compression.project),
|
|
323
|
+
session: readCompressionAggregate(compression.session)
|
|
324
|
+
};
|
|
325
|
+
}
|
|
307
326
|
function formatBytes(bytes) {
|
|
308
327
|
if (!Number.isFinite(bytes) || bytes <= 0)
|
|
309
328
|
return "0 B";
|
|
@@ -376,13 +395,14 @@ function coerceAftStatus(response) {
|
|
|
376
395
|
tracked_files: readNumber(session.tracked_files),
|
|
377
396
|
checkpoints: readNumber(session.checkpoints)
|
|
378
397
|
},
|
|
398
|
+
compression: readCompression(response.compression),
|
|
379
399
|
message: readString(response.message, "")
|
|
380
400
|
};
|
|
381
401
|
}
|
|
382
402
|
|
|
383
403
|
// src/tui/sidebar.tsx
|
|
384
404
|
import { createEffect, createMemo, createSignal, on, onCleanup } from "solid-js";
|
|
385
|
-
import { jsxDEV } from "@opentui/solid/jsx-dev-runtime";
|
|
405
|
+
import { jsxDEV, Fragment } from "@opentui/solid/jsx-dev-runtime";
|
|
386
406
|
var SINGLE_BORDER = { type: "single" };
|
|
387
407
|
var REFRESH_DEBOUNCE_MS = 200;
|
|
388
408
|
var POLL_INTERVAL_MS = 1500;
|
|
@@ -406,6 +426,23 @@ function formatCount(n) {
|
|
|
406
426
|
return `${Math.round(n / 1000)}K`;
|
|
407
427
|
return String(n);
|
|
408
428
|
}
|
|
429
|
+
function appendScope(rows, label, scope) {
|
|
430
|
+
const savings = scope.savings_tokens;
|
|
431
|
+
const pct = scope.original_tokens > 0 ? Math.round(savings / scope.original_tokens * 100) : 0;
|
|
432
|
+
rows.push({ kind: "scope", label });
|
|
433
|
+
rows.push({ kind: "stat", label: "Tokens Saved", value: savings.toLocaleString("en-US") });
|
|
434
|
+
rows.push({ kind: "stat", label: "Compression Ratio", value: `${pct}%` });
|
|
435
|
+
}
|
|
436
|
+
function formatCompressionSidebarRows(compression) {
|
|
437
|
+
if (!compression || compression.project.events <= 0)
|
|
438
|
+
return [];
|
|
439
|
+
const rows = [];
|
|
440
|
+
if (compression.session.events > 0) {
|
|
441
|
+
appendScope(rows, "Session", compression.session);
|
|
442
|
+
}
|
|
443
|
+
appendScope(rows, "Project", compression.project);
|
|
444
|
+
return rows;
|
|
445
|
+
}
|
|
409
446
|
function statusDisplay(status) {
|
|
410
447
|
switch (status) {
|
|
411
448
|
case "ready":
|
|
@@ -474,7 +511,7 @@ function getClient(directory) {
|
|
|
474
511
|
return client;
|
|
475
512
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
476
513
|
const dataHome = process.env.XDG_DATA_HOME || `${home}/.local/share`;
|
|
477
|
-
const storageDir = `${dataHome}/
|
|
514
|
+
const storageDir = `${dataHome}/cortexkit/aft`;
|
|
478
515
|
client = new AftRpcClient(storageDir, directory);
|
|
479
516
|
sidebarClients.set(directory, client);
|
|
480
517
|
return client;
|
|
@@ -562,6 +599,7 @@ var SidebarContent = (props) => {
|
|
|
562
599
|
const semanticStatus = () => statusDisplay(s()?.semantic_index?.status ?? "disabled");
|
|
563
600
|
const trigramBytes = () => s()?.disk?.trigram_disk_bytes ?? 0;
|
|
564
601
|
const semanticBytes = () => s()?.disk?.semantic_disk_bytes ?? 0;
|
|
602
|
+
const compressionRows = () => formatCompressionSidebarRows(s()?.compression);
|
|
565
603
|
const degradedReasonLabel = (reason) => {
|
|
566
604
|
if (reason === "home_root") {
|
|
567
605
|
return "project root is your home directory";
|
|
@@ -703,6 +741,26 @@ var SidebarContent = (props) => {
|
|
|
703
741
|
value: formatBytes2(semanticBytes()),
|
|
704
742
|
tone: "muted"
|
|
705
743
|
}, undefined, false, undefined, this),
|
|
744
|
+
compressionRows().length > 0 && /* @__PURE__ */ jsxDEV(Fragment, {
|
|
745
|
+
children: [
|
|
746
|
+
/* @__PURE__ */ jsxDEV(SectionHeader, {
|
|
747
|
+
theme: props.theme,
|
|
748
|
+
title: "Compression"
|
|
749
|
+
}, undefined, false, undefined, this),
|
|
750
|
+
compressionRows().map((row) => row.kind === "scope" ? /* @__PURE__ */ jsxDEV("box", {
|
|
751
|
+
width: "100%",
|
|
752
|
+
children: /* @__PURE__ */ jsxDEV("text", {
|
|
753
|
+
fg: props.theme.text,
|
|
754
|
+
children: row.label
|
|
755
|
+
}, undefined, false, undefined, this)
|
|
756
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(StatRow, {
|
|
757
|
+
theme: props.theme,
|
|
758
|
+
label: row.label,
|
|
759
|
+
value: row.value,
|
|
760
|
+
tone: "muted"
|
|
761
|
+
}, undefined, false, undefined, this))
|
|
762
|
+
]
|
|
763
|
+
}, undefined, true, undefined, this),
|
|
706
764
|
s()?.semantic_index?.status === "failed" && s()?.semantic_index?.error && /* @__PURE__ */ jsxDEV("box", {
|
|
707
765
|
marginTop: 1,
|
|
708
766
|
width: "100%",
|
|
@@ -744,7 +802,7 @@ function getRpcClient(directory) {
|
|
|
744
802
|
return client;
|
|
745
803
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
746
804
|
const dataHome = process.env.XDG_DATA_HOME || `${home}/.local/share`;
|
|
747
|
-
const storageDir = `${dataHome}/
|
|
805
|
+
const storageDir = `${dataHome}/cortexkit/aft`;
|
|
748
806
|
client = new AftRpcClient(storageDir, directory);
|
|
749
807
|
rpcClients.set(directory, client);
|
|
750
808
|
return client;
|
|
@@ -834,6 +892,7 @@ var StatusDialog = (props) => {
|
|
|
834
892
|
}, POLL_INTERVAL_MS2);
|
|
835
893
|
onCleanup2(() => clearInterval(timer));
|
|
836
894
|
const cacheRoleTone = (role) => role === "main" ? "accent" : role === "worktree" ? "warn" : "muted";
|
|
895
|
+
const compressionAggregateRows = () => formatCompressionSidebarRows(status()?.compression);
|
|
837
896
|
return /* @__PURE__ */ jsxDEV2("box", {
|
|
838
897
|
flexDirection: "column",
|
|
839
898
|
width: "100%",
|
|
@@ -1110,6 +1169,31 @@ var StatusDialog = (props) => {
|
|
|
1110
1169
|
]
|
|
1111
1170
|
}, undefined, true, undefined, this)
|
|
1112
1171
|
}, undefined, false, undefined, this) : null,
|
|
1172
|
+
compressionAggregateRows().length > 0 ? /* @__PURE__ */ jsxDEV2("box", {
|
|
1173
|
+
flexDirection: "column",
|
|
1174
|
+
width: "100%",
|
|
1175
|
+
marginTop: 1,
|
|
1176
|
+
children: [
|
|
1177
|
+
/* @__PURE__ */ jsxDEV2("text", {
|
|
1178
|
+
fg: t().text,
|
|
1179
|
+
children: /* @__PURE__ */ jsxDEV2("b", {
|
|
1180
|
+
children: "Compression"
|
|
1181
|
+
}, undefined, false, undefined, this)
|
|
1182
|
+
}, undefined, false, undefined, this),
|
|
1183
|
+
compressionAggregateRows().map((row) => row.kind === "scope" ? /* @__PURE__ */ jsxDEV2("box", {
|
|
1184
|
+
width: "100%",
|
|
1185
|
+
children: /* @__PURE__ */ jsxDEV2("text", {
|
|
1186
|
+
fg: t().text,
|
|
1187
|
+
children: row.label
|
|
1188
|
+
}, undefined, false, undefined, this)
|
|
1189
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV2(R, {
|
|
1190
|
+
theme: t(),
|
|
1191
|
+
label: row.label,
|
|
1192
|
+
value: row.value,
|
|
1193
|
+
tone: "muted"
|
|
1194
|
+
}, undefined, false, undefined, this))
|
|
1195
|
+
]
|
|
1196
|
+
}, undefined, true, undefined, this) : null,
|
|
1113
1197
|
/* @__PURE__ */ jsxDEV2("box", {
|
|
1114
1198
|
marginTop: 1,
|
|
1115
1199
|
justifyContent: "flex-end",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/aft-opencode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.1",
|
|
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",
|
|
@@ -24,11 +24,12 @@
|
|
|
24
24
|
"test": "bun test",
|
|
25
25
|
"test:e2e": "bun test src/__tests__/e2e/",
|
|
26
26
|
"lint": "biome check src",
|
|
27
|
+
"schema": "bun scripts/build-schema.ts",
|
|
27
28
|
"prepublishOnly": "bun run build"
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
30
31
|
"@clack/prompts": "^1.2.0",
|
|
31
|
-
"@cortexkit/aft-bridge": "0.
|
|
32
|
+
"@cortexkit/aft-bridge": "0.27.1",
|
|
32
33
|
"@opencode-ai/plugin": "^1.15.5",
|
|
33
34
|
"@opencode-ai/sdk": "^1.15.5",
|
|
34
35
|
"comment-json": "^4.6.2",
|
|
@@ -36,11 +37,11 @@
|
|
|
36
37
|
"zod": "^4.1.8"
|
|
37
38
|
},
|
|
38
39
|
"optionalDependencies": {
|
|
39
|
-
"@cortexkit/aft-darwin-arm64": "0.
|
|
40
|
-
"@cortexkit/aft-darwin-x64": "0.
|
|
41
|
-
"@cortexkit/aft-linux-arm64": "0.
|
|
42
|
-
"@cortexkit/aft-linux-x64": "0.
|
|
43
|
-
"@cortexkit/aft-win32-x64": "0.
|
|
40
|
+
"@cortexkit/aft-darwin-arm64": "0.27.1",
|
|
41
|
+
"@cortexkit/aft-darwin-x64": "0.27.1",
|
|
42
|
+
"@cortexkit/aft-linux-arm64": "0.27.1",
|
|
43
|
+
"@cortexkit/aft-linux-x64": "0.27.1",
|
|
44
|
+
"@cortexkit/aft-win32-x64": "0.27.1"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@types/node": "^22.0.0",
|
package/src/shared/status.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
export interface StatusCompressionAggregate {
|
|
2
|
+
events: number;
|
|
3
|
+
original_tokens: number;
|
|
4
|
+
compressed_tokens: number;
|
|
5
|
+
savings_tokens: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface StatusCompression {
|
|
9
|
+
project: StatusCompressionAggregate;
|
|
10
|
+
session: StatusCompressionAggregate;
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
export interface AftStatusSnapshot {
|
|
2
14
|
version: string;
|
|
3
15
|
project_root: string | null;
|
|
@@ -57,6 +69,8 @@ export interface AftStatusSnapshot {
|
|
|
57
69
|
tracked_files: number;
|
|
58
70
|
checkpoints: number;
|
|
59
71
|
};
|
|
72
|
+
/** Compression aggregate passthrough; rendering is added separately. */
|
|
73
|
+
compression?: StatusCompression;
|
|
60
74
|
/**
|
|
61
75
|
* Human-readable explanation for a synthetic snapshot (e.g.
|
|
62
76
|
* `cache_role === "not_initialized"`). When the plugin returns a placeholder
|
|
@@ -91,6 +105,25 @@ function readOptionalNumber(value: unknown): number | null {
|
|
|
91
105
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
92
106
|
}
|
|
93
107
|
|
|
108
|
+
function readCompressionAggregate(value: unknown): StatusCompressionAggregate {
|
|
109
|
+
const aggregate = asRecord(value);
|
|
110
|
+
return {
|
|
111
|
+
events: readNumber(aggregate.events),
|
|
112
|
+
original_tokens: readNumber(aggregate.original_tokens),
|
|
113
|
+
compressed_tokens: readNumber(aggregate.compressed_tokens),
|
|
114
|
+
savings_tokens: readNumber(aggregate.savings_tokens),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function readCompression(value: unknown): StatusCompression | undefined {
|
|
119
|
+
if (typeof value !== "object" || value === null) return undefined;
|
|
120
|
+
const compression = asRecord(value);
|
|
121
|
+
return {
|
|
122
|
+
project: readCompressionAggregate(compression.project),
|
|
123
|
+
session: readCompressionAggregate(compression.session),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
94
127
|
function formatFlag(enabled: boolean): string {
|
|
95
128
|
return enabled ? "enabled" : "disabled";
|
|
96
129
|
}
|
|
@@ -178,6 +211,7 @@ export function coerceAftStatus(response: Record<string, unknown>): AftStatusSna
|
|
|
178
211
|
tracked_files: readNumber(session.tracked_files),
|
|
179
212
|
checkpoints: readNumber(session.checkpoints),
|
|
180
213
|
},
|
|
214
|
+
compression: readCompression(response.compression),
|
|
181
215
|
message: readString(response.message, ""),
|
|
182
216
|
};
|
|
183
217
|
}
|
package/src/tui/index.tsx
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
import type { TuiPlugin, TuiPluginApi, TuiThemeCurrent } from "@opencode-ai/plugin/tui";
|
|
5
5
|
import { createMemo, createSignal, onCleanup } from "solid-js";
|
|
6
|
+
|
|
6
7
|
import packageJson from "../../package.json";
|
|
7
8
|
import { AftRpcClient } from "../shared/rpc-client";
|
|
8
9
|
import { type AftStatusSnapshot, coerceAftStatus, formatBytes } from "../shared/status";
|
|
9
|
-
import { createAftSidebarSlot } from "./sidebar";
|
|
10
|
+
import { createAftSidebarSlot, formatCompressionSidebarRows } from "./sidebar";
|
|
10
11
|
|
|
11
12
|
// The TUI talks to the server plugin via AftRpcClient. The client reads the
|
|
12
13
|
// JSON port file written by AftRpcServer ({ port, token }) and includes that
|
|
@@ -22,9 +23,14 @@ function getRpcClient(directory: string): AftRpcClient {
|
|
|
22
23
|
let client = rpcClients.get(directory);
|
|
23
24
|
if (client) return client;
|
|
24
25
|
|
|
26
|
+
// v0.27 moved AFT storage to the CortexKit root. The TUI plugin must use
|
|
27
|
+
// the same path as the server plugin (`resolveCortexKitStorageRoot()`),
|
|
28
|
+
// otherwise it polls stale legacy port files written by older versions
|
|
29
|
+
// and never picks up the live RPC server, leaving the sidebar/dialog
|
|
30
|
+
// stuck on the "AFT is starting up" placeholder forever.
|
|
25
31
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
26
32
|
const dataHome = process.env.XDG_DATA_HOME || `${home}/.local/share`;
|
|
27
|
-
const storageDir = `${dataHome}/
|
|
33
|
+
const storageDir = `${dataHome}/cortexkit/aft`;
|
|
28
34
|
|
|
29
35
|
client = new AftRpcClient(storageDir, directory);
|
|
30
36
|
rpcClients.set(directory, client);
|
|
@@ -153,6 +159,11 @@ const StatusDialog = (props: StatusDialogProps) => {
|
|
|
153
159
|
// not_initialized is muted. Matches the sidebar convention.
|
|
154
160
|
const cacheRoleTone = (role: string): "accent" | "warn" | "muted" =>
|
|
155
161
|
role === "main" ? "accent" : role === "worktree" ? "warn" : "muted";
|
|
162
|
+
// Reuse the sidebar's label/value formatter so the dialog and sidebar
|
|
163
|
+
// render identical text (e.g. "Session" / "-174,489 tokens, 59% reduction").
|
|
164
|
+
// The earlier `formatCompressionDialogRows` returned padded strings that
|
|
165
|
+
// looked offset against neighboring sections.
|
|
166
|
+
const compressionAggregateRows = () => formatCompressionSidebarRows(status()?.compression);
|
|
156
167
|
|
|
157
168
|
return (
|
|
158
169
|
<box
|
|
@@ -374,6 +385,28 @@ const StatusDialog = (props: StatusDialogProps) => {
|
|
|
374
385
|
</box>
|
|
375
386
|
) : null}
|
|
376
387
|
|
|
388
|
+
{/* Compression aggregates — tabular layout matching Search/Semantic
|
|
389
|
+
Index. Each scope ("Session", "Project") renders as a subheader
|
|
390
|
+
followed by two <R> rows (Tokens Saved, Compression Ratio) so the
|
|
391
|
+
numbers stay right-aligned under the value column instead of
|
|
392
|
+
crowding the label. */}
|
|
393
|
+
{compressionAggregateRows().length > 0 ? (
|
|
394
|
+
<box flexDirection="column" width="100%" marginTop={1}>
|
|
395
|
+
<text fg={t().text}>
|
|
396
|
+
<b>Compression</b>
|
|
397
|
+
</text>
|
|
398
|
+
{compressionAggregateRows().map((row) =>
|
|
399
|
+
row.kind === "scope" ? (
|
|
400
|
+
<box width="100%">
|
|
401
|
+
<text fg={t().text}>{row.label}</text>
|
|
402
|
+
</box>
|
|
403
|
+
) : (
|
|
404
|
+
<R theme={t()} label={row.label} value={row.value} tone="muted" />
|
|
405
|
+
),
|
|
406
|
+
)}
|
|
407
|
+
</box>
|
|
408
|
+
) : null}
|
|
409
|
+
|
|
377
410
|
{/* Footer */}
|
|
378
411
|
<box marginTop={1} justifyContent="flex-end" width="100%">
|
|
379
412
|
<text fg={t().textMuted}>Enter or Esc to close</text>
|
package/src/tui/sidebar.tsx
CHANGED
|
@@ -11,7 +11,7 @@ import type { TuiPluginApi, TuiSlotPlugin, TuiThemeCurrent } from "@opencode-ai/
|
|
|
11
11
|
import { createEffect, createMemo, createSignal, on, onCleanup } from "solid-js";
|
|
12
12
|
|
|
13
13
|
import { AftRpcClient } from "../shared/rpc-client";
|
|
14
|
-
import { type AftStatusSnapshot, coerceAftStatus } from "../shared/status";
|
|
14
|
+
import { type AftStatusSnapshot, coerceAftStatus, type StatusCompression } from "../shared/status";
|
|
15
15
|
|
|
16
16
|
const SINGLE_BORDER = { type: "single" } as any;
|
|
17
17
|
const REFRESH_DEBOUNCE_MS = 200;
|
|
@@ -35,6 +35,46 @@ function formatCount(n: number | null | undefined): string {
|
|
|
35
35
|
return String(n);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/** Tagged rows for the Compression section. Each scope (Session / Project)
|
|
39
|
+
* emits a "scope" header followed by two "stat" rows — Tokens Saved and
|
|
40
|
+
* Compression Ratio — so the renderer can use the same StatRow layout as
|
|
41
|
+
* Search Index / Semantic Index above. Pi's monospace overlay and the
|
|
42
|
+
* OpenCode TUI dialog/sidebar all consume this same shape. */
|
|
43
|
+
export type CompressionRow =
|
|
44
|
+
| { kind: "scope"; label: string }
|
|
45
|
+
| { kind: "stat"; label: string; value: string };
|
|
46
|
+
|
|
47
|
+
function appendScope(
|
|
48
|
+
rows: CompressionRow[],
|
|
49
|
+
label: string,
|
|
50
|
+
scope: {
|
|
51
|
+
events: number;
|
|
52
|
+
original_tokens: number;
|
|
53
|
+
compressed_tokens: number;
|
|
54
|
+
savings_tokens: number;
|
|
55
|
+
},
|
|
56
|
+
): void {
|
|
57
|
+
const savings = scope.savings_tokens;
|
|
58
|
+
const pct = scope.original_tokens > 0 ? Math.round((savings / scope.original_tokens) * 100) : 0;
|
|
59
|
+
rows.push({ kind: "scope", label });
|
|
60
|
+
rows.push({ kind: "stat", label: "Tokens Saved", value: savings.toLocaleString("en-US") });
|
|
61
|
+
rows.push({ kind: "stat", label: "Compression Ratio", value: `${pct}%` });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function formatCompressionSidebarRows(
|
|
65
|
+
compression: StatusCompression | undefined,
|
|
66
|
+
): CompressionRow[] {
|
|
67
|
+
if (!compression || compression.project.events <= 0) return [];
|
|
68
|
+
|
|
69
|
+
const rows: CompressionRow[] = [];
|
|
70
|
+
if (compression.session.events > 0) {
|
|
71
|
+
appendScope(rows, "Session", compression.session);
|
|
72
|
+
}
|
|
73
|
+
appendScope(rows, "Project", compression.project);
|
|
74
|
+
|
|
75
|
+
return rows;
|
|
76
|
+
}
|
|
77
|
+
|
|
38
78
|
// Map index status → (label, theme color name). The label is what we want
|
|
39
79
|
// the user to see; the color encodes severity so the eye lands on warnings.
|
|
40
80
|
function statusDisplay(status: string): { label: string; tone: "ok" | "warn" | "err" | "muted" } {
|
|
@@ -104,7 +144,10 @@ function getClient(directory: string): AftRpcClient {
|
|
|
104
144
|
if (client) return client;
|
|
105
145
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
106
146
|
const dataHome = process.env.XDG_DATA_HOME || `${home}/.local/share`;
|
|
107
|
-
|
|
147
|
+
// v0.27 moved AFT storage to the CortexKit root. Must match the server
|
|
148
|
+
// plugin's `resolveCortexKitStorageRoot()` or the sidebar will poll a
|
|
149
|
+
// stale legacy port file and never connect to the live RPC server.
|
|
150
|
+
const storageDir = `${dataHome}/cortexkit/aft`;
|
|
108
151
|
client = new AftRpcClient(storageDir, directory);
|
|
109
152
|
sidebarClients.set(directory, client);
|
|
110
153
|
return client;
|
|
@@ -225,6 +268,7 @@ const SidebarContent = (props: {
|
|
|
225
268
|
const semanticStatus = () => statusDisplay(s()?.semantic_index?.status ?? "disabled");
|
|
226
269
|
const trigramBytes = () => s()?.disk?.trigram_disk_bytes ?? 0;
|
|
227
270
|
const semanticBytes = () => s()?.disk?.semantic_disk_bytes ?? 0;
|
|
271
|
+
const compressionRows = () => formatCompressionSidebarRows(s()?.compression);
|
|
228
272
|
|
|
229
273
|
// Degraded-mode reason → human-readable hint. Distinct strings per reason
|
|
230
274
|
// because the UX direction is different: "home_root" tells the user to
|
|
@@ -357,6 +401,26 @@ const SidebarContent = (props: {
|
|
|
357
401
|
)}
|
|
358
402
|
<StatRow theme={props.theme} label="Disk" value={formatBytes(semanticBytes())} tone="muted" />
|
|
359
403
|
|
|
404
|
+
{/* Compression aggregates. Tabular layout matching Search/Semantic
|
|
405
|
+
Index above: each scope ("Session", "Project") renders as a
|
|
406
|
+
subheader followed by two StatRows (Tokens Saved, Compression
|
|
407
|
+
Ratio). Keeps numbers right-aligned in the value column instead
|
|
408
|
+
of jamming them after the label on the same line. */}
|
|
409
|
+
{compressionRows().length > 0 && (
|
|
410
|
+
<>
|
|
411
|
+
<SectionHeader theme={props.theme} title="Compression" />
|
|
412
|
+
{compressionRows().map((row) =>
|
|
413
|
+
row.kind === "scope" ? (
|
|
414
|
+
<box width="100%">
|
|
415
|
+
<text fg={props.theme.text}>{row.label}</text>
|
|
416
|
+
</box>
|
|
417
|
+
) : (
|
|
418
|
+
<StatRow theme={props.theme} label={row.label} value={row.value} tone="muted" />
|
|
419
|
+
),
|
|
420
|
+
)}
|
|
421
|
+
</>
|
|
422
|
+
)}
|
|
423
|
+
|
|
360
424
|
{/* Surface failures clearly so users know to act (install ONNX,
|
|
361
425
|
fix config, etc.) rather than silently leaving the panel "off". */}
|
|
362
426
|
{s()?.semantic_index?.status === "failed" && s()?.semantic_index?.error && (
|