@cortexkit/opencode-magic-context 0.15.0 → 0.15.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/cli/diagnostics.d.ts.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli.js +71 -82
- package/dist/features/magic-context/tool-definition-tokens.d.ts +45 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3333 -3273
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/data-path.d.ts +12 -0
- package/dist/shared/data-path.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +15 -5
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/data-path.test.ts +69 -0
- package/src/shared/data-path.ts +18 -0
- package/src/shared/models-dev-cache.ts +5 -10
- package/src/shared/rpc-types.ts +15 -5
- package/src/tui/data/context-db.ts +1 -0
- package/src/tui/index.tsx +13 -4
- package/src/tui/slots/sidebar-content.tsx +33 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAMzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAIlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AA0elE;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CA4GN"}
|
|
@@ -1,3 +1,15 @@
|
|
|
1
1
|
export declare function getDataDir(): string;
|
|
2
2
|
export declare function getOpenCodeStorageDir(): string;
|
|
3
|
+
/**
|
|
4
|
+
* Resolve OpenCode's cache base directory.
|
|
5
|
+
*
|
|
6
|
+
* OpenCode uses the `xdg-basedir` package, which — on every platform, including
|
|
7
|
+
* Windows — falls back to `<homedir>/.cache` when `XDG_CACHE_HOME` is unset.
|
|
8
|
+
* A previous Windows-specific branch that resolved to `%LOCALAPPDATA%` did not
|
|
9
|
+
* match OpenCode's own resolution and caused `doctor --force` to target a
|
|
10
|
+
* non-existent directory, leaving the real cache at `C:\Users\<user>\.cache`
|
|
11
|
+
* untouched.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getCacheDir(): string;
|
|
14
|
+
export declare function getOpenCodeCacheDir(): string;
|
|
3
15
|
//# sourceMappingURL=data-path.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-path.d.ts","sourceRoot":"","sources":["../../src/shared/data-path.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C"}
|
|
1
|
+
{"version":3,"file":"data-path.d.ts","sourceRoot":"","sources":["../../src/shared/data-path.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models-dev-cache.d.ts","sourceRoot":"","sources":["../../src/shared/models-dev-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"models-dev-cache.d.ts","sourceRoot":"","sources":["../../src/shared/models-dev-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AASH,UAAU,kBAAkB;IACxB,MAAM,EAAE;QACJ,SAAS,EAAE,MAAM,OAAO,CAAC;YAAE,IAAI,CAAC,EAAE;gBAAE,SAAS,CAAC,EAAE,OAAO,CAAA;aAAE,CAAA;SAAE,CAAC,CAAC;KAChE,CAAC;CACL;AAqND;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDzF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAchG;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAkBpB;AAED,4CAA4C;AAC5C,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED,oDAAoD;AACpD,wBAAgB,sBAAsB,IAAI;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACrB,CAOA"}
|
|
@@ -35,13 +35,23 @@ export interface SidebarSnapshot {
|
|
|
35
35
|
*/
|
|
36
36
|
toolCallTokens: number;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
38
|
+
* Measured token cost of tool schemas (description + JSON-schema
|
|
39
|
+
* parameters) OpenCode sends in the request `tools` parameter. Populated
|
|
40
|
+
* by the `tool.definition` plugin hook, keyed by
|
|
41
|
+
* `{providerID, modelID, agentName}`. Zero until the first turn after
|
|
42
|
+
* plugin startup measures the current agent's tool set. Display layer
|
|
43
|
+
* shows this as "Tool Definitions".
|
|
43
44
|
*/
|
|
44
45
|
toolDefinitionTokens: number;
|
|
46
|
+
/**
|
|
47
|
+
* Residual catch-all: provider-side wrapping not captured elsewhere —
|
|
48
|
+
* the JSON envelope around the `tools` array, tool-choice fields,
|
|
49
|
+
* provider-specific cache-control markers, tokenizer imprecision, etc.
|
|
50
|
+
* Computed as `inputTokens − systemPromptTokens − messagesBlock −
|
|
51
|
+
* toolCallTokens − toolDefinitionTokens` and clamped to ≥ 0. Display
|
|
52
|
+
* layer shows this as "Overhead".
|
|
53
|
+
*/
|
|
54
|
+
overheadTokens: number;
|
|
45
55
|
}
|
|
46
56
|
export interface StatusDetail extends SidebarSnapshot {
|
|
47
57
|
tagCounter: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB
|
|
1
|
+
{"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,oBAAoB,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC9C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAS9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAG/B;
|
|
1
|
+
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAS9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAG/B;AA4BD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAc1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAchE"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { getCacheDir, getDataDir, getOpenCodeCacheDir, getOpenCodeStorageDir } from "./data-path";
|
|
5
|
+
|
|
6
|
+
const savedEnv = {
|
|
7
|
+
XDG_CACHE_HOME: process.env.XDG_CACHE_HOME,
|
|
8
|
+
XDG_DATA_HOME: process.env.XDG_DATA_HOME,
|
|
9
|
+
LOCALAPPDATA: process.env.LOCALAPPDATA,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
describe("data-path", () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
process.env.XDG_CACHE_HOME = undefined;
|
|
15
|
+
process.env.XDG_DATA_HOME = undefined;
|
|
16
|
+
process.env.LOCALAPPDATA = undefined;
|
|
17
|
+
// Bun's env handling: explicit delete for unset
|
|
18
|
+
delete process.env.XDG_CACHE_HOME;
|
|
19
|
+
delete process.env.XDG_DATA_HOME;
|
|
20
|
+
delete process.env.LOCALAPPDATA;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
if (savedEnv.XDG_CACHE_HOME !== undefined)
|
|
25
|
+
process.env.XDG_CACHE_HOME = savedEnv.XDG_CACHE_HOME;
|
|
26
|
+
if (savedEnv.XDG_DATA_HOME !== undefined)
|
|
27
|
+
process.env.XDG_DATA_HOME = savedEnv.XDG_DATA_HOME;
|
|
28
|
+
if (savedEnv.LOCALAPPDATA !== undefined) process.env.LOCALAPPDATA = savedEnv.LOCALAPPDATA;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("getCacheDir falls back to <homedir>/.cache when XDG_CACHE_HOME is unset (all platforms)", () => {
|
|
32
|
+
// Matches OpenCode's xdg-basedir behavior on every platform, including
|
|
33
|
+
// Windows. A previous bug mapped Windows to %LOCALAPPDATA% and caused
|
|
34
|
+
// doctor --force to target a non-existent cache directory.
|
|
35
|
+
expect(getCacheDir()).toBe(path.join(os.homedir(), ".cache"));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("getCacheDir honors XDG_CACHE_HOME when set", () => {
|
|
39
|
+
process.env.XDG_CACHE_HOME = "/tmp/custom-cache";
|
|
40
|
+
expect(getCacheDir()).toBe("/tmp/custom-cache");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("getCacheDir ignores LOCALAPPDATA on Windows (must match OpenCode's xdg-basedir)", () => {
|
|
44
|
+
// Even with LOCALAPPDATA set, cache must go to ~/.cache to match
|
|
45
|
+
// OpenCode's own resolution. Otherwise doctor --force clears the
|
|
46
|
+
// wrong directory on Windows.
|
|
47
|
+
process.env.LOCALAPPDATA = "C:\\Users\\Test\\AppData\\Local";
|
|
48
|
+
expect(getCacheDir()).toBe(path.join(os.homedir(), ".cache"));
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("getOpenCodeCacheDir appends 'opencode' to the cache base", () => {
|
|
52
|
+
expect(getOpenCodeCacheDir()).toBe(path.join(os.homedir(), ".cache", "opencode"));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("getOpenCodeCacheDir with XDG_CACHE_HOME set", () => {
|
|
56
|
+
process.env.XDG_CACHE_HOME = "/tmp/custom-cache";
|
|
57
|
+
expect(getOpenCodeCacheDir()).toBe(path.join("/tmp/custom-cache", "opencode"));
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("getDataDir falls back to <homedir>/.local/share when XDG_DATA_HOME is unset", () => {
|
|
61
|
+
expect(getDataDir()).toBe(path.join(os.homedir(), ".local", "share"));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("getOpenCodeStorageDir composes correctly", () => {
|
|
65
|
+
expect(getOpenCodeStorageDir()).toBe(
|
|
66
|
+
path.join(os.homedir(), ".local", "share", "opencode", "storage"),
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
});
|
package/src/shared/data-path.ts
CHANGED
|
@@ -8,3 +8,21 @@ export function getDataDir(): string {
|
|
|
8
8
|
export function getOpenCodeStorageDir(): string {
|
|
9
9
|
return path.join(getDataDir(), "opencode", "storage");
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Resolve OpenCode's cache base directory.
|
|
14
|
+
*
|
|
15
|
+
* OpenCode uses the `xdg-basedir` package, which — on every platform, including
|
|
16
|
+
* Windows — falls back to `<homedir>/.cache` when `XDG_CACHE_HOME` is unset.
|
|
17
|
+
* A previous Windows-specific branch that resolved to `%LOCALAPPDATA%` did not
|
|
18
|
+
* match OpenCode's own resolution and caused `doctor --force` to target a
|
|
19
|
+
* non-existent directory, leaving the real cache at `C:\Users\<user>\.cache`
|
|
20
|
+
* untouched.
|
|
21
|
+
*/
|
|
22
|
+
export function getCacheDir(): string {
|
|
23
|
+
return process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), ".cache");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getOpenCodeCacheDir(): string {
|
|
27
|
+
return path.join(getCacheDir(), "opencode");
|
|
28
|
+
}
|
|
@@ -24,6 +24,7 @@ import { createHash } from "node:crypto";
|
|
|
24
24
|
import { existsSync, readFileSync } from "node:fs";
|
|
25
25
|
import { homedir, platform } from "node:os";
|
|
26
26
|
import { join } from "node:path";
|
|
27
|
+
import { getCacheDir } from "./data-path";
|
|
27
28
|
import { sessionLog } from "./logger";
|
|
28
29
|
|
|
29
30
|
interface OpencodeClientLike {
|
|
@@ -59,16 +60,10 @@ function getModelsJsonPath(): string {
|
|
|
59
60
|
const explicit = process.env.OPENCODE_MODELS_PATH?.trim();
|
|
60
61
|
if (explicit) return explicit;
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
cacheBase = xdgCache;
|
|
67
|
-
} else if (os === "win32") {
|
|
68
|
-
cacheBase = process.env.LOCALAPPDATA ?? join(homedir(), "AppData", "Local");
|
|
69
|
-
} else {
|
|
70
|
-
cacheBase = join(homedir(), ".cache");
|
|
71
|
-
}
|
|
63
|
+
// OpenCode uses `xdg-basedir`, which falls back to `<homedir>/.cache` on
|
|
64
|
+
// every platform (including Windows) when XDG_CACHE_HOME is unset. See
|
|
65
|
+
// shared/data-path.ts#getCacheDir for the shared helper.
|
|
66
|
+
const cacheBase = getCacheDir();
|
|
72
67
|
|
|
73
68
|
// 2. Custom models source → hashed filename (matches OpenCode).
|
|
74
69
|
// source === "https://models.dev" ? "models.json" : `models-${Hash.fast(source)}.json`
|
package/src/shared/rpc-types.ts
CHANGED
|
@@ -36,13 +36,23 @@ export interface SidebarSnapshot {
|
|
|
36
36
|
*/
|
|
37
37
|
toolCallTokens: number;
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
39
|
+
* Measured token cost of tool schemas (description + JSON-schema
|
|
40
|
+
* parameters) OpenCode sends in the request `tools` parameter. Populated
|
|
41
|
+
* by the `tool.definition` plugin hook, keyed by
|
|
42
|
+
* `{providerID, modelID, agentName}`. Zero until the first turn after
|
|
43
|
+
* plugin startup measures the current agent's tool set. Display layer
|
|
44
|
+
* shows this as "Tool Definitions".
|
|
44
45
|
*/
|
|
45
46
|
toolDefinitionTokens: number;
|
|
47
|
+
/**
|
|
48
|
+
* Residual catch-all: provider-side wrapping not captured elsewhere —
|
|
49
|
+
* the JSON envelope around the `tools` array, tool-choice fields,
|
|
50
|
+
* provider-specific cache-control markers, tokenizer imprecision, etc.
|
|
51
|
+
* Computed as `inputTokens − systemPromptTokens − messagesBlock −
|
|
52
|
+
* toolCallTokens − toolDefinitionTokens` and clamped to ≥ 0. Display
|
|
53
|
+
* layer shows this as "Overhead".
|
|
54
|
+
*/
|
|
55
|
+
overheadTokens: number;
|
|
46
56
|
}
|
|
47
57
|
|
|
48
58
|
export interface StatusDetail extends SidebarSnapshot {
|
package/src/tui/index.tsx
CHANGED
|
@@ -207,12 +207,19 @@ const StatusDialog = (props: { api: TuiPluginApi; s: StatusDetail }) => {
|
|
|
207
207
|
|
|
208
208
|
const elapsed = () => (s().lastResponseTime > 0 ? Date.now() - s().lastResponseTime : 0)
|
|
209
209
|
|
|
210
|
-
// Token breakdown segments — same colors as sidebar
|
|
210
|
+
// Token breakdown segments — same colors as sidebar. Kept in sync with
|
|
211
|
+
// slots/sidebar-content.tsx so the status dialog and sidebar read identically.
|
|
211
212
|
const COLORS = {
|
|
213
|
+
// Cool / structured — injected by the plugin into message[0]
|
|
212
214
|
system: "#c084fc",
|
|
213
215
|
compartments: "#60a5fa",
|
|
214
216
|
facts: "#fbbf24",
|
|
215
217
|
memories: "#34d399",
|
|
218
|
+
// Warm / user-facing — chat and tool traffic
|
|
219
|
+
conversation: "#f87171",
|
|
220
|
+
toolCalls: "#fb923c",
|
|
221
|
+
toolDefs: "#f472b6",
|
|
222
|
+
overhead: "#9ca3af",
|
|
216
223
|
}
|
|
217
224
|
|
|
218
225
|
const breakdownSegments = () => {
|
|
@@ -245,11 +252,13 @@ const StatusDialog = (props: { api: TuiPluginApi; s: StatusDetail }) => {
|
|
|
245
252
|
})
|
|
246
253
|
|
|
247
254
|
if (d.conversationTokens > 0)
|
|
248
|
-
segs.push({ label: "Conversation", tokens: d.conversationTokens, color:
|
|
255
|
+
segs.push({ label: "Conversation", tokens: d.conversationTokens, color: COLORS.conversation })
|
|
249
256
|
if (d.toolCallTokens > 0)
|
|
250
|
-
segs.push({ label: "Tool Calls", tokens: d.toolCallTokens, color:
|
|
257
|
+
segs.push({ label: "Tool Calls", tokens: d.toolCallTokens, color: COLORS.toolCalls })
|
|
251
258
|
if (d.toolDefinitionTokens > 0)
|
|
252
|
-
segs.push({ label: "Tool Defs
|
|
259
|
+
segs.push({ label: "Tool Defs", tokens: d.toolDefinitionTokens, color: COLORS.toolDefs })
|
|
260
|
+
if (d.overheadTokens > 0)
|
|
261
|
+
segs.push({ label: "Overhead", tokens: d.overheadTokens, color: COLORS.overhead })
|
|
253
262
|
|
|
254
263
|
return { segs, total }
|
|
255
264
|
}
|
|
@@ -23,11 +23,17 @@ function relativeTime(ms: number): string {
|
|
|
23
23
|
|
|
24
24
|
// Token breakdown segment colors (hardcoded hex values)
|
|
25
25
|
const COLORS = {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
// Cool / structured — injected by the plugin into message[0]
|
|
27
|
+
system: "#c084fc", // Purple
|
|
28
|
+
compartments: "#60a5fa", // Blue
|
|
29
|
+
facts: "#fbbf24", // Yellow/orange
|
|
30
|
+
memories: "#34d399", // Green
|
|
31
|
+
// Warm / user-facing — regular chat and tool traffic. Grouped visually
|
|
32
|
+
// by hue family so the user reads them as a related block.
|
|
33
|
+
conversation: "#f87171", // Red
|
|
34
|
+
toolCalls: "#fb923c", // Orange
|
|
35
|
+
toolDefs: "#f472b6", // Pink
|
|
36
|
+
overhead: "#9ca3af", // Gray — catch-all residual
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
interface TokenSegment {
|
|
@@ -95,7 +101,7 @@ const TokenBreakdown = (props: {
|
|
|
95
101
|
result.push({
|
|
96
102
|
key: "conv",
|
|
97
103
|
tokens: s.conversationTokens,
|
|
98
|
-
color:
|
|
104
|
+
color: COLORS.conversation,
|
|
99
105
|
label: "Conversation",
|
|
100
106
|
})
|
|
101
107
|
}
|
|
@@ -106,19 +112,35 @@ const TokenBreakdown = (props: {
|
|
|
106
112
|
result.push({
|
|
107
113
|
key: "tool-calls",
|
|
108
114
|
tokens: s.toolCallTokens,
|
|
109
|
-
color:
|
|
115
|
+
color: COLORS.toolCalls,
|
|
110
116
|
label: "Tool Calls",
|
|
111
117
|
})
|
|
112
118
|
}
|
|
113
119
|
|
|
114
|
-
// Tool Definitions =
|
|
115
|
-
//
|
|
120
|
+
// Tool Definitions = measured description + JSON-schema parameters for
|
|
121
|
+
// each tool OpenCode sends in the `tools` request parameter, populated
|
|
122
|
+
// by the `tool.definition` plugin hook keyed by {provider, model, agent}.
|
|
123
|
+
// Zero until the first turn measures the active agent's tool set.
|
|
116
124
|
if (s.toolDefinitionTokens > 0) {
|
|
117
125
|
result.push({
|
|
118
126
|
key: "tool-defs",
|
|
119
127
|
tokens: s.toolDefinitionTokens,
|
|
120
|
-
color: COLORS.
|
|
121
|
-
label: "Tool Defs
|
|
128
|
+
color: COLORS.toolDefs,
|
|
129
|
+
label: "Tool Defs",
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Overhead = residual between input tokens and everything measured above.
|
|
134
|
+
// Captures provider-side JSON wrapping around the tools array,
|
|
135
|
+
// tool_choice/cache-control markers, and tokenizer imprecision. Before
|
|
136
|
+
// the first turn's tool.definition measurement lands, the real tool
|
|
137
|
+
// schema cost also shows up here.
|
|
138
|
+
if (s.overheadTokens > 0) {
|
|
139
|
+
result.push({
|
|
140
|
+
key: "overhead",
|
|
141
|
+
tokens: s.overheadTokens,
|
|
142
|
+
color: COLORS.overhead,
|
|
143
|
+
label: "Overhead",
|
|
122
144
|
})
|
|
123
145
|
}
|
|
124
146
|
|