opencode-mask-j0k3r-dev-rgl 2.0.15 → 2.0.17
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/components.tsx +54 -39
- package/package.json +1 -1
- package/tui.tsx +2 -0
package/components.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/** @jsxImportSource @opentui/solid */
|
|
3
3
|
import type { TuiThemeCurrent, TuiSidebarFileItem, TuiSidebarMcpItem, TuiSidebarLspItem, TuiSidebarTodoItem } from "@opencode-ai/plugin/tui"
|
|
4
|
+
import type { Message } from "@opencode-ai/sdk/v2"
|
|
4
5
|
import type { Cfg } from "./config"
|
|
5
6
|
import { getOSName, getProviders } from "./detection"
|
|
6
7
|
import {
|
|
@@ -48,7 +49,6 @@ export const HomeLogo = (props: { theme: TuiThemeCurrent }) => {
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
// ─── Progress bar helper ──────────────────────────────────────────────────────
|
|
51
|
-
// Renders a ASCII bar like: [████░░░░░░] 40%
|
|
52
52
|
const ProgressBar = (props: {
|
|
53
53
|
value: number // 0–100
|
|
54
54
|
width?: number
|
|
@@ -83,32 +83,52 @@ export const SidebarArch = (props: {
|
|
|
83
83
|
mcpItems?: ReadonlyArray<TuiSidebarMcpItem>
|
|
84
84
|
lspItems?: ReadonlyArray<TuiSidebarLspItem>
|
|
85
85
|
todos?: ReadonlyArray<TuiSidebarTodoItem>
|
|
86
|
+
messages?: ReadonlyArray<Message>
|
|
86
87
|
}) => {
|
|
87
88
|
if (!props.config.show_sidebar) return null
|
|
88
89
|
|
|
89
90
|
const t = props.theme
|
|
90
91
|
|
|
91
|
-
// ──
|
|
92
|
+
// ── Files ─────────────────────────────────────────────────────────────────
|
|
92
93
|
const files = props.files ?? []
|
|
93
|
-
const todos = props.todos ?? []
|
|
94
|
-
const mcpItems = props.mcpItems ?? []
|
|
95
|
-
const lspItems = props.lspItems ?? []
|
|
96
|
-
|
|
97
94
|
const totalAdditions = files.reduce((s, f) => s + f.additions, 0)
|
|
98
95
|
const totalDeletions = files.reduce((s, f) => s + f.deletions, 0)
|
|
99
96
|
const totalChanges = totalAdditions + totalDeletions
|
|
100
97
|
|
|
98
|
+
// ── Todos ─────────────────────────────────────────────────────────────────
|
|
99
|
+
const todos = props.todos ?? []
|
|
101
100
|
const doneTodos = todos.filter(t => t.status === "completed").length
|
|
102
101
|
const totalTodos = todos.length
|
|
103
102
|
const todoPct = totalTodos > 0 ? Math.round((doneTodos / totalTodos) * 100) : 0
|
|
104
103
|
|
|
104
|
+
// ── MCP ───────────────────────────────────────────────────────────────────
|
|
105
|
+
const mcpItems = props.mcpItems ?? []
|
|
105
106
|
const mcpConnected = mcpItems.filter(m => m.status === "connected").length
|
|
106
107
|
const mcpTotal = mcpItems.length
|
|
107
108
|
const mcpPct = mcpTotal > 0 ? Math.round((mcpConnected / mcpTotal) * 100) : 0
|
|
108
109
|
|
|
110
|
+
// ── LSP ───────────────────────────────────────────────────────────────────
|
|
111
|
+
const lspItems = props.lspItems ?? []
|
|
109
112
|
const lspActive = lspItems.filter(l => l.status === "idle" || l.status === "running").length
|
|
110
113
|
const lspTotal = lspItems.length
|
|
111
114
|
|
|
115
|
+
// ── Tokens & Cost — sumados de los AssistantMessages ─────────────────────
|
|
116
|
+
const messages = props.messages ?? []
|
|
117
|
+
const assistantMsgs = messages.filter(m => m.role === "assistant")
|
|
118
|
+
const totalTokens = assistantMsgs.reduce((s, m) => s + (m.tokens?.total ?? (m.tokens?.input ?? 0) + (m.tokens?.output ?? 0)), 0)
|
|
119
|
+
const totalCost = assistantMsgs.reduce((s, m) => s + (m.cost ?? 0), 0)
|
|
120
|
+
|
|
121
|
+
// Context window: OpenCode muestra "% used" basado en el modelo.
|
|
122
|
+
// Usamos 200_000 como referencia (Claude 3.5 Sonnet / GPT-4o max).
|
|
123
|
+
const CONTEXT_LIMIT = 200_000
|
|
124
|
+
const contextPct = Math.min(100, Math.round((totalTokens / CONTEXT_LIMIT) * 100))
|
|
125
|
+
|
|
126
|
+
const fmtTokens = (n: number) => n >= 1000 ? `${(n / 1000).toFixed(1)}k` : `${n}`
|
|
127
|
+
const fmtCost = (n: number) => `$${n.toFixed(2)}`
|
|
128
|
+
|
|
129
|
+
// Color del context bar: verde → amarillo → rojo según el %
|
|
130
|
+
const ctxColor = contextPct < 50 ? "#00e5a0" : contextPct < 80 ? "#ffd166" : "#ff2d78"
|
|
131
|
+
|
|
112
132
|
return (
|
|
113
133
|
<box flexDirection="column" alignItems="center">
|
|
114
134
|
|
|
@@ -130,62 +150,57 @@ export const SidebarArch = (props: {
|
|
|
130
150
|
</box>
|
|
131
151
|
)}
|
|
132
152
|
|
|
133
|
-
{/*
|
|
134
|
-
{
|
|
153
|
+
{/* ── Context (tokens + % used + cost) ── */}
|
|
154
|
+
{totalTokens > 0 && (
|
|
135
155
|
<box flexDirection="column" marginTop={1}>
|
|
156
|
+
<text fg={t.textMuted} bold={true}>Context</text>
|
|
157
|
+
|
|
158
|
+
{/* tokens */}
|
|
159
|
+
<box flexDirection="row" gap={1}>
|
|
160
|
+
<text fg={t.text}>{fmtTokens(totalTokens)}</text>
|
|
161
|
+
<text fg={t.textMuted}>tokens</text>
|
|
162
|
+
</box>
|
|
163
|
+
<ProgressBar value={contextPct} width={12} fillColor={ctxColor} emptyColor="#3a3a3a" theme={t} />
|
|
164
|
+
|
|
165
|
+
{/* % used */}
|
|
136
166
|
<box flexDirection="row" gap={1}>
|
|
137
|
-
<text fg={
|
|
138
|
-
<text fg={t.textMuted}>
|
|
167
|
+
<text fg={ctxColor}>{contextPct}%</text>
|
|
168
|
+
<text fg={t.textMuted}>used</text>
|
|
139
169
|
</box>
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
|
|
170
|
+
<ProgressBar value={contextPct} width={12} fillColor={ctxColor} emptyColor="#3a3a3a" theme={t} />
|
|
171
|
+
|
|
172
|
+
{/* $ spent */}
|
|
173
|
+
<box flexDirection="row" gap={1}>
|
|
174
|
+
<text fg="#ffd166">{fmtCost(totalCost)}</text>
|
|
175
|
+
<text fg={t.textMuted}>spent</text>
|
|
143
176
|
</box>
|
|
144
|
-
<ProgressBar
|
|
145
|
-
value={totalChanges > 0 ? Math.min(100, (totalAdditions / totalChanges) * 100) : 0}
|
|
146
|
-
width={12}
|
|
147
|
-
fillColor="#00e5a0"
|
|
148
|
-
emptyColor="#ff2d78"
|
|
149
|
-
theme={t}
|
|
150
|
-
/>
|
|
177
|
+
<ProgressBar value={Math.min(100, totalCost * 100)} width={12} fillColor="#ffd166" emptyColor="#3a3a3a" theme={t} />
|
|
151
178
|
</box>
|
|
152
179
|
)}
|
|
153
180
|
|
|
154
|
-
{/* Todos
|
|
181
|
+
{/* ── Todos ── */}
|
|
155
182
|
{totalTodos > 0 && (
|
|
156
183
|
<box flexDirection="column" marginTop={1}>
|
|
157
184
|
<box flexDirection="row" gap={1}>
|
|
158
185
|
<text fg={t.textMuted}>todos</text>
|
|
159
|
-
<text fg={t.
|
|
186
|
+
<text fg={t.text}>{doneTodos}/{totalTodos}</text>
|
|
160
187
|
</box>
|
|
161
|
-
<ProgressBar
|
|
162
|
-
value={todoPct}
|
|
163
|
-
width={12}
|
|
164
|
-
fillColor="#9d4edd"
|
|
165
|
-
emptyColor="#3a3a3a"
|
|
166
|
-
theme={t}
|
|
167
|
-
/>
|
|
188
|
+
<ProgressBar value={todoPct} width={12} fillColor="#9d4edd" emptyColor="#3a3a3a" theme={t} />
|
|
168
189
|
</box>
|
|
169
190
|
)}
|
|
170
191
|
|
|
171
|
-
{/* MCP
|
|
192
|
+
{/* ── MCP ── */}
|
|
172
193
|
{mcpTotal > 0 && (
|
|
173
194
|
<box flexDirection="column" marginTop={1}>
|
|
174
195
|
<box flexDirection="row" gap={1}>
|
|
175
196
|
<text fg={t.textMuted}>mcp</text>
|
|
176
|
-
<text fg={t.
|
|
197
|
+
<text fg={t.text}>{mcpConnected}/{mcpTotal}</text>
|
|
177
198
|
</box>
|
|
178
|
-
<ProgressBar
|
|
179
|
-
value={mcpPct}
|
|
180
|
-
width={12}
|
|
181
|
-
fillColor="#00c8ff"
|
|
182
|
-
emptyColor="#3a3a3a"
|
|
183
|
-
theme={t}
|
|
184
|
-
/>
|
|
199
|
+
<ProgressBar value={mcpPct} width={12} fillColor="#00c8ff" emptyColor="#3a3a3a" theme={t} />
|
|
185
200
|
</box>
|
|
186
201
|
)}
|
|
187
202
|
|
|
188
|
-
{/* LSP
|
|
203
|
+
{/* ── LSP ── */}
|
|
189
204
|
{lspTotal > 0 && (
|
|
190
205
|
<box flexDirection="row" gap={1} marginTop={1}>
|
|
191
206
|
<text fg={t.textMuted}>lsp</text>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "opencode-mask-j0k3r-dev-rgl",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.17",
|
|
5
5
|
"description": "Arch Linux TUI mask for OpenCode — hot pink theme with prominent ASCII logo and j0k3r-dev-rgl@latest legend",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
package/tui.tsx
CHANGED
|
@@ -44,6 +44,7 @@ const tui: TuiPlugin = async (api, options) => {
|
|
|
44
44
|
const branch = api.state.vcs?.branch
|
|
45
45
|
const files = sessionID ? api.state.session.diff(sessionID) : []
|
|
46
46
|
const todos = sessionID ? api.state.session.todo(sessionID) : []
|
|
47
|
+
const messages = sessionID ? api.state.session.messages(sessionID) : []
|
|
47
48
|
const mcpItems = api.state.mcp()
|
|
48
49
|
const lspItems = api.state.lsp()
|
|
49
50
|
|
|
@@ -55,6 +56,7 @@ const tui: TuiPlugin = async (api, options) => {
|
|
|
55
56
|
branch={branch}
|
|
56
57
|
files={files}
|
|
57
58
|
todos={todos}
|
|
59
|
+
messages={messages}
|
|
58
60
|
mcpItems={mcpItems}
|
|
59
61
|
lspItems={lspItems}
|
|
60
62
|
/>
|