@glaicer/supercode-token-usage-panel 0.1.1 → 0.1.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.
@@ -0,0 +1,136 @@
1
+ import { createComponent as _$createComponent } from "@opentui/solid";
2
+ import { effect as _$effect } from "@opentui/solid";
3
+ import { insertNode as _$insertNode } from "@opentui/solid";
4
+ import { insert as _$insert } from "@opentui/solid";
5
+ import { memo as _$memo } from "@opentui/solid";
6
+ import { setProp as _$setProp } from "@opentui/solid";
7
+ import { createElement as _$createElement } from "@opentui/solid";
8
+ /**
9
+ * supercode.token-usage — TUI sidebar section showing the cumulative Token
10
+ * Usage of the current session family: token totals, cache rate, completed
11
+ * step count, generation speed/TTFT, and provisional diagnostics for the
12
+ * visible stream.
13
+ * Family totals include all subagent descendants; when they contribute the
14
+ * section title becomes "Token Usage (including subagents)".
15
+ *
16
+ * This file is only the View plus slot registration: it computes no numbers
17
+ * and formats nothing — all logic lives in ./usage-model.ts (the tested seam).
18
+ *
19
+ * Colors always come from the live host theme; collapse state is component
20
+ * memory, expanded by default and not persisted (spec: Out of Scope).
21
+ */
22
+ /** @jsxImportSource @opentui/solid */
23
+ import { createEffect, createMemo, createSignal, For, onCleanup, Show, untrack } from "solid-js";
24
+ import { USAGE_SECTION_TITLE, USAGE_SECTION_TITLE_WITH_SUBAGENTS, USAGE_STATUS_TEXT, createUsageModel } from "./usage-model.js";
25
+
26
+ /**
27
+ * The host rewrites this file's "solid-js" import to its own runtime. The
28
+ * model builds all of its signals on these exact primitives (see
29
+ * SolidRuntime), so the panel stays in the host's reactive graph even when
30
+ * installed as an npm package under node_modules.
31
+ */
32
+ const solid = {
33
+ createSignal,
34
+ createMemo,
35
+ createEffect,
36
+ onCleanup,
37
+ untrack
38
+ };
39
+ function Section(props) {
40
+ const theme = () => props.api.theme.current;
41
+ const [collapsed, setCollapsed] = createSignal(false);
42
+ const model = createUsageModel(props.api, () => props.session_id, solid);
43
+ return (() => {
44
+ var _el$ = _$createElement("box"),
45
+ _el$2 = _$createElement("box"),
46
+ _el$3 = _$createElement("text"),
47
+ _el$4 = _$createElement("text"),
48
+ _el$5 = _$createElement("b");
49
+ _$insertNode(_el$, _el$2);
50
+ _$insertNode(_el$2, _el$3);
51
+ _$insertNode(_el$2, _el$4);
52
+ _$setProp(_el$2, "flexDirection", "row");
53
+ _$setProp(_el$2, "gap", 1);
54
+ _$setProp(_el$2, "onMouseDown", () => setCollapsed(!collapsed()));
55
+ _$insert(_el$3, () => collapsed() ? "▶" : "▼");
56
+ _$insertNode(_el$4, _el$5);
57
+ _$insert(_el$5, () => model.includesSubagents() ? USAGE_SECTION_TITLE_WITH_SUBAGENTS : USAGE_SECTION_TITLE);
58
+ _$insert(_el$, _$createComponent(Show, {
59
+ get when() {
60
+ return !collapsed();
61
+ },
62
+ get children() {
63
+ return [_$createComponent(Show, {
64
+ get when() {
65
+ return model.status() !== "ready";
66
+ },
67
+ get children() {
68
+ var _el$6 = _$createElement("text");
69
+ _$insert(_el$6, () => USAGE_STATUS_TEXT[model.status()]);
70
+ _$effect(_$p => _$setProp(_el$6, "fg", theme().textMuted, _$p));
71
+ return _el$6;
72
+ }
73
+ }), _$createComponent(For, {
74
+ get each() {
75
+ return model.rows();
76
+ },
77
+ children: row => (() => {
78
+ var _el$7 = _$createElement("box"),
79
+ _el$8 = _$createElement("text"),
80
+ _el$9 = _$createElement("text");
81
+ _$insertNode(_el$7, _el$8);
82
+ _$insertNode(_el$7, _el$9);
83
+ _$setProp(_el$7, "flexDirection", "row");
84
+ _$setProp(_el$7, "justifyContent", "space-between");
85
+ _$insert(_el$8, () => row.label);
86
+ _$insert(_el$9, () => row.value);
87
+ _$effect(_p$ => {
88
+ var _v$3 = theme().textMuted,
89
+ _v$4 = theme().text;
90
+ _v$3 !== _p$.e && (_p$.e = _$setProp(_el$8, "fg", _v$3, _p$.e));
91
+ _v$4 !== _p$.t && (_p$.t = _$setProp(_el$9, "fg", _v$4, _p$.t));
92
+ return _p$;
93
+ }, {
94
+ e: undefined,
95
+ t: undefined
96
+ });
97
+ return _el$7;
98
+ })()
99
+ })];
100
+ }
101
+ }), null);
102
+ _$effect(_p$ => {
103
+ var _v$ = theme().text,
104
+ _v$2 = theme().text;
105
+ _v$ !== _p$.e && (_p$.e = _$setProp(_el$3, "fg", _v$, _p$.e));
106
+ _v$2 !== _p$.t && (_p$.t = _$setProp(_el$4, "fg", _v$2, _p$.t));
107
+ return _p$;
108
+ }, {
109
+ e: undefined,
110
+ t: undefined
111
+ });
112
+ return _el$;
113
+ })();
114
+ }
115
+ const tui = async api => {
116
+ // Order 150: internal sidebar sections sit at 100/200/300/400/500, so this
117
+ // lands right after the first block without moving any existing section.
118
+ api.slots.register({
119
+ order: 150,
120
+ slots: {
121
+ sidebar_content(_ctx, props) {
122
+ return _$createComponent(Section, {
123
+ api: api,
124
+ get session_id() {
125
+ return props.session_id;
126
+ }
127
+ });
128
+ }
129
+ }
130
+ });
131
+ };
132
+ const plugin = {
133
+ id: "supercode.token-usage",
134
+ tui
135
+ };
136
+ export default plugin;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@glaicer/supercode-token-usage-panel",
4
- "version": "0.1.1",
4
+ "version": "0.1.2",
5
5
  "description": "OpenCode TUI sidebar section: cumulative token usage and cost of the current session family.",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -21,19 +21,18 @@
21
21
  "generation-speed"
22
22
  ],
23
23
  "exports": {
24
- "./tui": "./src/usage-panel.tsx"
24
+ "./tui": "./dist/usage-panel.js"
25
25
  },
26
26
  "files": [
27
- "src",
28
- "!src/*.test.ts",
29
- "!src/fake-tui-api.ts",
30
- "!src/test-fixtures.ts",
31
- "!src/fixtures/**"
27
+ "dist"
32
28
  ],
33
29
  "publishConfig": {
34
30
  "access": "public"
35
31
  },
36
32
  "scripts": {
33
+ "build": "node scripts/build.mjs",
34
+ "check:package": "node scripts/check-package.mjs",
35
+ "prepack": "npm run build && npm run check:package",
37
36
  "test": "node --test --conditions browser 'src/**/*.test.ts'",
38
37
  "typecheck": "tsc --noEmit"
39
38
  },
@@ -44,8 +43,11 @@
44
43
  "solid-js": "1.9.12"
45
44
  },
46
45
  "devDependencies": {
46
+ "@babel/core": "7.28.0",
47
+ "@babel/preset-typescript": "7.27.1",
47
48
  "@opencode-ai/sdk": "1.18.21",
48
49
  "@types/node": "24.13.3",
50
+ "babel-preset-solid": "1.9.12",
49
51
  "typescript": "5.8.2"
50
52
  },
51
53
  "engines": {