@bismawy/pi-arnative 0.1.0
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/LICENSE +21 -0
- package/README.md +108 -0
- package/extensions/footer.ts +627 -0
- package/extensions/section-headers.ts +734 -0
- package/extensions/timestamps.ts +224 -0
- package/extensions/tools.ts +942 -0
- package/extensions/ui-render-tweaks.ts +576 -0
- package/extensions/usage.ts +314 -0
- package/lib/ansi.ts +24 -0
- package/lib/box.ts +59 -0
- package/lib/usage-store.ts +354 -0
- package/package.json +43 -0
- package/themes/arnative-cyberpunk.json +94 -0
- package/themes/arnative-dracula.json +94 -0
- package/themes/arnative-emerald.json +94 -0
- package/themes/arnative-gruvbox.json +94 -0
- package/themes/arnative-matrix.json +94 -0
- package/themes/arnative-nord.json +94 -0
- package/themes/arnative-sun.json +94 -0
- package/themes/arnative-synthwave.json +94 -0
- package/themes/arnative-violet.json +94 -0
- package/themes/arnative-zinc.json +94 -0
- package/themes/arnative.json +94 -0
- package/themes/gen-themes.mjs +272 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token usage data layer — the single source for /usage and the Model tab.
|
|
3
|
+
* - Scans local Pi session history (~/.pi/agent/sessions/*.jsonl).
|
|
4
|
+
* - mtime+size keyed cache in ~/.pi/agent/arnative-usage-cache.json, read into
|
|
5
|
+
* memory once (parsing 4MB per header frame cost ~50ms and lagged long chats).
|
|
6
|
+
* - No double counting: the active session is already in its own file, so it is
|
|
7
|
+
* NOT re-added from sessionManager (that inflated the ↑↓ totals).
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { dirname, join } from "node:path";
|
|
11
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
12
|
+
|
|
13
|
+
export interface UsageEntry {
|
|
14
|
+
provider: string;
|
|
15
|
+
model: string;
|
|
16
|
+
input: number;
|
|
17
|
+
output: number;
|
|
18
|
+
cacheRead: number;
|
|
19
|
+
cost: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface FileCacheItem {
|
|
23
|
+
mtimeMs: number;
|
|
24
|
+
size: number;
|
|
25
|
+
v?: number;
|
|
26
|
+
entries: UsageEntry[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface UsageModelStats {
|
|
30
|
+
name: string;
|
|
31
|
+
sessions: number;
|
|
32
|
+
msgs: number;
|
|
33
|
+
input: number;
|
|
34
|
+
output: number;
|
|
35
|
+
cacheRead: number;
|
|
36
|
+
totalTokens: number;
|
|
37
|
+
cost: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface UsageProviderStats {
|
|
41
|
+
name: string;
|
|
42
|
+
sessions: number;
|
|
43
|
+
msgs: number;
|
|
44
|
+
input: number;
|
|
45
|
+
output: number;
|
|
46
|
+
cacheRead: number;
|
|
47
|
+
totalTokens: number;
|
|
48
|
+
cost: number;
|
|
49
|
+
models: UsageModelStats[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface UsageSummary {
|
|
53
|
+
providers: UsageProviderStats[];
|
|
54
|
+
totals: {
|
|
55
|
+
sessions: number;
|
|
56
|
+
msgs: number;
|
|
57
|
+
input: number;
|
|
58
|
+
output: number;
|
|
59
|
+
cacheRead: number;
|
|
60
|
+
totalTokens: number;
|
|
61
|
+
cost: number;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Token count with k/M/B units; 0 or negative = "-". */
|
|
66
|
+
export function formatTokens(n: number): string {
|
|
67
|
+
if (!n || n <= 0) return "-";
|
|
68
|
+
if (n < 1000) return String(n);
|
|
69
|
+
if (n < 1_000_000) {
|
|
70
|
+
const k = n / 1000;
|
|
71
|
+
return `${k < 10 ? k.toFixed(1) : Math.round(k)}k`;
|
|
72
|
+
}
|
|
73
|
+
if (n < 1_000_000_000) {
|
|
74
|
+
const m = n / 1_000_000;
|
|
75
|
+
return `${m.toFixed(1).replace(/\.0$/, "")}M`;
|
|
76
|
+
}
|
|
77
|
+
const b = n / 1_000_000_000;
|
|
78
|
+
return `${b.toFixed(1).replace(/\.0$/, "")}B`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const CACHE_FILE_PATH = join(getAgentDir(), "arnative-usage-cache.json");
|
|
82
|
+
const CACHE_VERSION = 2; // v2: per-entry cost
|
|
83
|
+
|
|
84
|
+
// Disk cache is memoized; save writes memory + disk together.
|
|
85
|
+
let diskMemo: Map<string, FileCacheItem> | null = null;
|
|
86
|
+
|
|
87
|
+
function loadDiskCache(): Map<string, FileCacheItem> {
|
|
88
|
+
if (diskMemo) return diskMemo;
|
|
89
|
+
diskMemo = new Map<string, FileCacheItem>();
|
|
90
|
+
try {
|
|
91
|
+
if (existsSync(CACHE_FILE_PATH)) {
|
|
92
|
+
const raw = JSON.parse(readFileSync(CACHE_FILE_PATH, "utf8")) as Record<string, FileCacheItem>;
|
|
93
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
94
|
+
diskMemo.set(k, v);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} catch {
|
|
98
|
+
// ignore
|
|
99
|
+
}
|
|
100
|
+
return diskMemo;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function saveDiskCache(map: Map<string, FileCacheItem>): void {
|
|
104
|
+
try {
|
|
105
|
+
const obj: Record<string, FileCacheItem> = {};
|
|
106
|
+
for (const [k, v] of map.entries()) {
|
|
107
|
+
obj[k] = v;
|
|
108
|
+
}
|
|
109
|
+
const dir = dirname(CACHE_FILE_PATH);
|
|
110
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
111
|
+
writeFileSync(CACHE_FILE_PATH, JSON.stringify(obj), "utf8");
|
|
112
|
+
} catch {
|
|
113
|
+
// ignore
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function scanSessionFiles(dir: string): string[] {
|
|
118
|
+
const files: string[] = [];
|
|
119
|
+
try {
|
|
120
|
+
if (!existsSync(dir)) return files;
|
|
121
|
+
const list = readdirSync(dir, { withFileTypes: true });
|
|
122
|
+
for (const ent of list) {
|
|
123
|
+
const full = join(dir, ent.name);
|
|
124
|
+
if (ent.isDirectory()) {
|
|
125
|
+
files.push(...scanSessionFiles(full));
|
|
126
|
+
} else if (ent.isFile() && ent.name.endsWith(".jsonl")) {
|
|
127
|
+
files.push(full);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
} catch {
|
|
131
|
+
// ignore
|
|
132
|
+
}
|
|
133
|
+
return files;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function parseSessionFile(filePath: string): UsageEntry[] {
|
|
137
|
+
const entries: UsageEntry[] = [];
|
|
138
|
+
try {
|
|
139
|
+
const content = readFileSync(filePath, "utf8");
|
|
140
|
+
const lines = content.split("\n");
|
|
141
|
+
for (const line of lines) {
|
|
142
|
+
if (!line || !line.includes('"role":"assistant"')) continue;
|
|
143
|
+
try {
|
|
144
|
+
const obj = JSON.parse(line);
|
|
145
|
+
const m = obj?.message;
|
|
146
|
+
if (m?.role === "assistant") {
|
|
147
|
+
const provider = String(m.provider || "unknown");
|
|
148
|
+
const model = String(m.model || "unknown");
|
|
149
|
+
const u = m.usage || {};
|
|
150
|
+
entries.push({
|
|
151
|
+
provider,
|
|
152
|
+
model,
|
|
153
|
+
input: Number(u.input) || 0,
|
|
154
|
+
output: Number(u.output) || 0,
|
|
155
|
+
cacheRead: Number(u.cacheRead) || 0,
|
|
156
|
+
cost: Number(u.cost?.total) || 0,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
} catch {
|
|
160
|
+
// unparsable line
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} catch {
|
|
164
|
+
// unreadable file
|
|
165
|
+
}
|
|
166
|
+
return entries;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let cachedSummary: UsageSummary | null = null;
|
|
170
|
+
let lastScanMs = 0;
|
|
171
|
+
|
|
172
|
+
export function collectUsageSummary(forceScan = false): UsageSummary {
|
|
173
|
+
const now = Date.now();
|
|
174
|
+
if (!forceScan && cachedSummary && now - lastScanMs < 5000) {
|
|
175
|
+
return cachedSummary;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const sessionsDir = join(getAgentDir(), "sessions");
|
|
179
|
+
const files = scanSessionFiles(sessionsDir);
|
|
180
|
+
const diskCache = loadDiskCache();
|
|
181
|
+
let cacheDirty = false;
|
|
182
|
+
|
|
183
|
+
const providerMap = new Map<
|
|
184
|
+
string,
|
|
185
|
+
{
|
|
186
|
+
sessions: Set<string>;
|
|
187
|
+
msgs: number;
|
|
188
|
+
input: number;
|
|
189
|
+
output: number;
|
|
190
|
+
cacheRead: number;
|
|
191
|
+
cost: number;
|
|
192
|
+
models: Map<string, { sessions: Set<string>; msgs: number; input: number; output: number; cacheRead: number; cost: number }>;
|
|
193
|
+
}
|
|
194
|
+
>();
|
|
195
|
+
|
|
196
|
+
for (const file of files) {
|
|
197
|
+
let stat;
|
|
198
|
+
try {
|
|
199
|
+
stat = statSync(file);
|
|
200
|
+
} catch {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
let fileEntries: UsageEntry[];
|
|
205
|
+
const cached = diskCache.get(file);
|
|
206
|
+
if (cached && cached.v === CACHE_VERSION && cached.mtimeMs === stat.mtimeMs && cached.size === stat.size) {
|
|
207
|
+
fileEntries = cached.entries;
|
|
208
|
+
} else {
|
|
209
|
+
fileEntries = parseSessionFile(file);
|
|
210
|
+
diskCache.set(file, {
|
|
211
|
+
mtimeMs: stat.mtimeMs,
|
|
212
|
+
size: stat.size,
|
|
213
|
+
v: CACHE_VERSION,
|
|
214
|
+
entries: fileEntries,
|
|
215
|
+
});
|
|
216
|
+
cacheDirty = true;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
for (const ent of fileEntries) {
|
|
220
|
+
if (!providerMap.has(ent.provider)) {
|
|
221
|
+
providerMap.set(ent.provider, {
|
|
222
|
+
sessions: new Set(),
|
|
223
|
+
msgs: 0,
|
|
224
|
+
input: 0,
|
|
225
|
+
output: 0,
|
|
226
|
+
cacheRead: 0,
|
|
227
|
+
cost: 0,
|
|
228
|
+
models: new Map(),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
const p = providerMap.get(ent.provider)!;
|
|
232
|
+
p.sessions.add(file);
|
|
233
|
+
p.msgs++;
|
|
234
|
+
p.input += ent.input;
|
|
235
|
+
p.output += ent.output;
|
|
236
|
+
p.cacheRead += ent.cacheRead;
|
|
237
|
+
p.cost += ent.cost;
|
|
238
|
+
|
|
239
|
+
if (!p.models.has(ent.model)) {
|
|
240
|
+
p.models.set(ent.model, {
|
|
241
|
+
sessions: new Set(),
|
|
242
|
+
msgs: 0,
|
|
243
|
+
input: 0,
|
|
244
|
+
output: 0,
|
|
245
|
+
cacheRead: 0,
|
|
246
|
+
cost: 0,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
const m = p.models.get(ent.model)!;
|
|
250
|
+
m.sessions.add(file);
|
|
251
|
+
m.msgs++;
|
|
252
|
+
m.input += ent.input;
|
|
253
|
+
m.output += ent.output;
|
|
254
|
+
m.cacheRead += ent.cacheRead;
|
|
255
|
+
m.cost += ent.cost;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (cacheDirty) {
|
|
260
|
+
saveDiskCache(diskCache);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Fold per-provider results into totals
|
|
264
|
+
let totalMsgs = 0;
|
|
265
|
+
let totalInp = 0;
|
|
266
|
+
let totalOut = 0;
|
|
267
|
+
let totalCache = 0;
|
|
268
|
+
let totalCost = 0;
|
|
269
|
+
|
|
270
|
+
const allSessions = new Set<string>();
|
|
271
|
+
const providers: UsageProviderStats[] = [];
|
|
272
|
+
|
|
273
|
+
for (const [pName, pData] of providerMap.entries()) {
|
|
274
|
+
for (const s of pData.sessions) allSessions.add(s);
|
|
275
|
+
totalMsgs += pData.msgs;
|
|
276
|
+
totalInp += pData.input;
|
|
277
|
+
totalOut += pData.output;
|
|
278
|
+
totalCache += pData.cacheRead;
|
|
279
|
+
totalCost += pData.cost;
|
|
280
|
+
|
|
281
|
+
const models: UsageModelStats[] = [];
|
|
282
|
+
for (const [mName, mData] of pData.models.entries()) {
|
|
283
|
+
models.push({
|
|
284
|
+
name: mName,
|
|
285
|
+
sessions: mData.sessions.size,
|
|
286
|
+
msgs: mData.msgs,
|
|
287
|
+
input: mData.input,
|
|
288
|
+
output: mData.output,
|
|
289
|
+
cacheRead: mData.cacheRead,
|
|
290
|
+
totalTokens: mData.input + mData.output,
|
|
291
|
+
cost: mData.cost,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
models.sort((a, b) => b.totalTokens - a.totalTokens);
|
|
295
|
+
|
|
296
|
+
providers.push({
|
|
297
|
+
name: pName,
|
|
298
|
+
sessions: pData.sessions.size,
|
|
299
|
+
msgs: pData.msgs,
|
|
300
|
+
input: pData.input,
|
|
301
|
+
output: pData.output,
|
|
302
|
+
cacheRead: pData.cacheRead,
|
|
303
|
+
totalTokens: pData.input + pData.output,
|
|
304
|
+
cost: pData.cost,
|
|
305
|
+
models,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
providers.sort((a, b) => b.totalTokens - a.totalTokens);
|
|
310
|
+
|
|
311
|
+
cachedSummary = {
|
|
312
|
+
providers,
|
|
313
|
+
totals: {
|
|
314
|
+
sessions: allSessions.size,
|
|
315
|
+
msgs: totalMsgs,
|
|
316
|
+
input: totalInp,
|
|
317
|
+
output: totalOut,
|
|
318
|
+
cacheRead: totalCache,
|
|
319
|
+
totalTokens: totalInp + totalOut,
|
|
320
|
+
cost: totalCost,
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
lastScanMs = now;
|
|
324
|
+
return cachedSummary;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Match model names across id shapes ("gemini-3.8-flash", "vendor/gemini-…").
|
|
328
|
+
const modelMatches = (mNameLower: string, targetLower: string): boolean =>
|
|
329
|
+
!targetLower ||
|
|
330
|
+
mNameLower === targetLower ||
|
|
331
|
+
mNameLower.endsWith("/" + targetLower) ||
|
|
332
|
+
mNameLower.split(":")[0] === targetLower ||
|
|
333
|
+
targetLower.endsWith("/" + mNameLower);
|
|
334
|
+
|
|
335
|
+
/** All-time usage for one model (same numbers as /usage; the active session is already in its own file). */
|
|
336
|
+
export function getModelAllTimeUsage(modelId?: string): { input: number; output: number; cacheRead: number } {
|
|
337
|
+
const summary = collectUsageSummary();
|
|
338
|
+
let inp = 0;
|
|
339
|
+
let out = 0;
|
|
340
|
+
let read = 0;
|
|
341
|
+
|
|
342
|
+
const target = (modelId || "").toLowerCase();
|
|
343
|
+
for (const p of summary.providers) {
|
|
344
|
+
for (const m of p.models) {
|
|
345
|
+
if (modelMatches(m.name.toLowerCase(), target)) {
|
|
346
|
+
inp += m.input;
|
|
347
|
+
out += m.output;
|
|
348
|
+
read += m.cacheRead;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return { input: inp, output: out, cacheRead: read };
|
|
354
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bismawy/pi-arnative",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Arnative look for Pi: 11 warm-neutral themes, rounded tool boxes, branded header with tabs, 2-line footer with git/model/status, transcript clock, and a /usage dashboard.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pi-package",
|
|
7
|
+
"pi-theme",
|
|
8
|
+
"pi-extension"
|
|
9
|
+
],
|
|
10
|
+
"type": "module",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/bismawy/pi-arnative.git"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/bismawy/pi-arnative#readme",
|
|
20
|
+
"files": [
|
|
21
|
+
"extensions",
|
|
22
|
+
"lib",
|
|
23
|
+
"themes",
|
|
24
|
+
"README.md"
|
|
25
|
+
],
|
|
26
|
+
"pi": {
|
|
27
|
+
"extensions": [
|
|
28
|
+
"./extensions/*.ts"
|
|
29
|
+
],
|
|
30
|
+
"themes": [
|
|
31
|
+
"./themes/*.json"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@earendil-works/pi-ai": "*",
|
|
36
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
37
|
+
"@earendil-works/pi-tui": "*"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"test": "node lib/box.ts && node lib/ansi.ts && node themes/gen-themes.mjs --check && node extensions/tools.ts && node extensions/footer.ts && node extensions/timestamps.ts && node extensions/section-headers.ts && node extensions/ui-render-tweaks.ts && node extensions/usage.ts",
|
|
41
|
+
"themes": "node themes/gen-themes.mjs"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
|
+
"name": "arnative-cyberpunk",
|
|
4
|
+
"vars": {
|
|
5
|
+
"cyan": "#00f0ff",
|
|
6
|
+
"blue": "#2a7fd4",
|
|
7
|
+
"green": "#00ff9f",
|
|
8
|
+
"red": "#ff4d6d",
|
|
9
|
+
"yellow": "#ffe600",
|
|
10
|
+
"text": "#eaeaf5",
|
|
11
|
+
"gray": "#8b88a8",
|
|
12
|
+
"dimGray": "#6f6a9a",
|
|
13
|
+
"darkGray": "#4a4763",
|
|
14
|
+
"accent": "#ff2e97",
|
|
15
|
+
"softCyan": "#7fd8f0",
|
|
16
|
+
"searchBg": "#5f3349",
|
|
17
|
+
"selectedBg": "#2b2350",
|
|
18
|
+
"userMsgBg": "#16131f",
|
|
19
|
+
"toolPendingBg": "#0d0b16",
|
|
20
|
+
"toolSuccessBg": "#0d2430",
|
|
21
|
+
"toolErrorBg": "#3a1524",
|
|
22
|
+
"customMsgBg": "#1a1329"
|
|
23
|
+
},
|
|
24
|
+
"colors": {
|
|
25
|
+
"accent": "accent",
|
|
26
|
+
"tint": "softCyan",
|
|
27
|
+
"border": "blue",
|
|
28
|
+
"borderAccent": "cyan",
|
|
29
|
+
"borderMuted": "darkGray",
|
|
30
|
+
"success": "green",
|
|
31
|
+
"error": "red",
|
|
32
|
+
"warning": "yellow",
|
|
33
|
+
"muted": "gray",
|
|
34
|
+
"dim": "dimGray",
|
|
35
|
+
"text": "text",
|
|
36
|
+
"thinkingText": "gray",
|
|
37
|
+
|
|
38
|
+
"selectedBg": "selectedBg",
|
|
39
|
+
"scrollbarTrack": "darkGray",
|
|
40
|
+
"scrollbarThumb": "softCyan",
|
|
41
|
+
"searchMatchBg": "searchBg",
|
|
42
|
+
"searchMatchText": "text",
|
|
43
|
+
"userMessageBg": "userMsgBg",
|
|
44
|
+
"userMessageText": "text",
|
|
45
|
+
"customMessageBg": "customMsgBg",
|
|
46
|
+
"customMessageText": "text",
|
|
47
|
+
"customMessageLabel": "#00f0ff",
|
|
48
|
+
"toolPendingBg": "toolPendingBg",
|
|
49
|
+
"toolSuccessBg": "toolSuccessBg",
|
|
50
|
+
"toolErrorBg": "toolErrorBg",
|
|
51
|
+
"toolTitle": "text",
|
|
52
|
+
"toolOutput": "gray",
|
|
53
|
+
|
|
54
|
+
"mdHeading": "#ffe600",
|
|
55
|
+
"mdLink": "#00f0ff",
|
|
56
|
+
"mdLinkUrl": "dimGray",
|
|
57
|
+
"mdCode": "accent",
|
|
58
|
+
"mdCodeBlock": "green",
|
|
59
|
+
"mdCodeBlockBorder": "gray",
|
|
60
|
+
"mdQuote": "gray",
|
|
61
|
+
"mdQuoteBorder": "gray",
|
|
62
|
+
"mdHr": "gray",
|
|
63
|
+
"mdListBullet": "accent",
|
|
64
|
+
|
|
65
|
+
"toolDiffAdded": "green",
|
|
66
|
+
"toolDiffRemoved": "red",
|
|
67
|
+
"toolDiffContext": "gray",
|
|
68
|
+
|
|
69
|
+
"syntaxComment": "#6f6a9a",
|
|
70
|
+
"syntaxKeyword": "#00f0ff",
|
|
71
|
+
"syntaxFunction": "#ffe600",
|
|
72
|
+
"syntaxVariable": "#ffd9f2",
|
|
73
|
+
"syntaxString": "#ff2e97",
|
|
74
|
+
"syntaxNumber": "#ff9a3c",
|
|
75
|
+
"syntaxType": "#00ff9f",
|
|
76
|
+
"syntaxOperator": "#c8c8e8",
|
|
77
|
+
"syntaxPunctuation": "#9a96c0",
|
|
78
|
+
|
|
79
|
+
"thinkingOff": "darkGray",
|
|
80
|
+
"thinkingMinimal": "#33285c",
|
|
81
|
+
"thinkingLow": "#4d3a94",
|
|
82
|
+
"thinkingMedium": "#7a4fd6",
|
|
83
|
+
"thinkingHigh": "#b84fe8",
|
|
84
|
+
"thinkingXhigh": "#ff4fc3",
|
|
85
|
+
"thinkingMax": "accent",
|
|
86
|
+
|
|
87
|
+
"bashMode": "green"
|
|
88
|
+
},
|
|
89
|
+
"export": {
|
|
90
|
+
"pageBg": "#0d0b16",
|
|
91
|
+
"cardBg": "#16131f",
|
|
92
|
+
"infoBg": "#3a2a10"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
|
+
"name": "arnative-dracula",
|
|
4
|
+
"vars": {
|
|
5
|
+
"cyan": "#8be9fd",
|
|
6
|
+
"blue": "#6272a4",
|
|
7
|
+
"green": "#50fa7b",
|
|
8
|
+
"red": "#ff6363",
|
|
9
|
+
"yellow": "#f1fa8c",
|
|
10
|
+
"text": "#f8f8f2",
|
|
11
|
+
"gray": "#8e96ba",
|
|
12
|
+
"dimGray": "#6272a4",
|
|
13
|
+
"darkGray": "#4a4e63",
|
|
14
|
+
"accent": "#bd93f9",
|
|
15
|
+
"softCyan": "#c9b8f2",
|
|
16
|
+
"searchBg": "#59427b",
|
|
17
|
+
"selectedBg": "#44475a",
|
|
18
|
+
"userMsgBg": "#343746",
|
|
19
|
+
"toolPendingBg": "#21222c",
|
|
20
|
+
"toolSuccessBg": "#26332e",
|
|
21
|
+
"toolErrorBg": "#412936",
|
|
22
|
+
"customMsgBg": "#383a52"
|
|
23
|
+
},
|
|
24
|
+
"colors": {
|
|
25
|
+
"accent": "accent",
|
|
26
|
+
"tint": "softCyan",
|
|
27
|
+
"border": "blue",
|
|
28
|
+
"borderAccent": "cyan",
|
|
29
|
+
"borderMuted": "darkGray",
|
|
30
|
+
"success": "green",
|
|
31
|
+
"error": "red",
|
|
32
|
+
"warning": "yellow",
|
|
33
|
+
"muted": "gray",
|
|
34
|
+
"dim": "dimGray",
|
|
35
|
+
"text": "text",
|
|
36
|
+
"thinkingText": "gray",
|
|
37
|
+
|
|
38
|
+
"selectedBg": "selectedBg",
|
|
39
|
+
"scrollbarTrack": "darkGray",
|
|
40
|
+
"scrollbarThumb": "softCyan",
|
|
41
|
+
"searchMatchBg": "searchBg",
|
|
42
|
+
"searchMatchText": "text",
|
|
43
|
+
"userMessageBg": "userMsgBg",
|
|
44
|
+
"userMessageText": "text",
|
|
45
|
+
"customMessageBg": "customMsgBg",
|
|
46
|
+
"customMessageText": "text",
|
|
47
|
+
"customMessageLabel": "#ff79c6",
|
|
48
|
+
"toolPendingBg": "toolPendingBg",
|
|
49
|
+
"toolSuccessBg": "toolSuccessBg",
|
|
50
|
+
"toolErrorBg": "toolErrorBg",
|
|
51
|
+
"toolTitle": "text",
|
|
52
|
+
"toolOutput": "gray",
|
|
53
|
+
|
|
54
|
+
"mdHeading": "#f1fa8c",
|
|
55
|
+
"mdLink": "#8be9fd",
|
|
56
|
+
"mdLinkUrl": "dimGray",
|
|
57
|
+
"mdCode": "accent",
|
|
58
|
+
"mdCodeBlock": "green",
|
|
59
|
+
"mdCodeBlockBorder": "gray",
|
|
60
|
+
"mdQuote": "gray",
|
|
61
|
+
"mdQuoteBorder": "gray",
|
|
62
|
+
"mdHr": "gray",
|
|
63
|
+
"mdListBullet": "accent",
|
|
64
|
+
|
|
65
|
+
"toolDiffAdded": "green",
|
|
66
|
+
"toolDiffRemoved": "red",
|
|
67
|
+
"toolDiffContext": "gray",
|
|
68
|
+
|
|
69
|
+
"syntaxComment": "#6272a4",
|
|
70
|
+
"syntaxKeyword": "#ff79c6",
|
|
71
|
+
"syntaxFunction": "#50fa7b",
|
|
72
|
+
"syntaxVariable": "#8be9fd",
|
|
73
|
+
"syntaxString": "#f1fa8c",
|
|
74
|
+
"syntaxNumber": "#bd93f9",
|
|
75
|
+
"syntaxType": "#8be9fd",
|
|
76
|
+
"syntaxOperator": "#ff79c6",
|
|
77
|
+
"syntaxPunctuation": "#f8f8f2",
|
|
78
|
+
|
|
79
|
+
"thinkingOff": "darkGray",
|
|
80
|
+
"thinkingMinimal": "#464a5d",
|
|
81
|
+
"thinkingLow": "#6272a4",
|
|
82
|
+
"thinkingMedium": "#7a6fd0",
|
|
83
|
+
"thinkingHigh": "#bd93f9",
|
|
84
|
+
"thinkingXhigh": "#ff79c6",
|
|
85
|
+
"thinkingMax": "accent",
|
|
86
|
+
|
|
87
|
+
"bashMode": "green"
|
|
88
|
+
},
|
|
89
|
+
"export": {
|
|
90
|
+
"pageBg": "#21222c",
|
|
91
|
+
"cardBg": "#282a36",
|
|
92
|
+
"infoBg": "#44475a"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
|
+
"name": "arnative-emerald",
|
|
4
|
+
"vars": {
|
|
5
|
+
"cyan": "#a7f3d0",
|
|
6
|
+
"blue": "#34b98a",
|
|
7
|
+
"green": "#b5bd68",
|
|
8
|
+
"red": "#d07272",
|
|
9
|
+
"yellow": "#ffff00",
|
|
10
|
+
"text": "#d4d4d4",
|
|
11
|
+
"gray": "#8d8d8d",
|
|
12
|
+
"dimGray": "#666666",
|
|
13
|
+
"darkGray": "#505050",
|
|
14
|
+
"accent": "#6ee7b7",
|
|
15
|
+
"softCyan": "#7eceaf",
|
|
16
|
+
"searchBg": "#356351",
|
|
17
|
+
"selectedBg": "#324840",
|
|
18
|
+
"userMsgBg": "#25312d",
|
|
19
|
+
"toolPendingBg": "#1f2925",
|
|
20
|
+
"toolSuccessBg": "#202828",
|
|
21
|
+
"toolErrorBg": "#342222",
|
|
22
|
+
"customMsgBg": "#1f3028"
|
|
23
|
+
},
|
|
24
|
+
"colors": {
|
|
25
|
+
"accent": "accent",
|
|
26
|
+
"tint": "softCyan",
|
|
27
|
+
"border": "blue",
|
|
28
|
+
"borderAccent": "cyan",
|
|
29
|
+
"borderMuted": "darkGray",
|
|
30
|
+
"success": "green",
|
|
31
|
+
"error": "red",
|
|
32
|
+
"warning": "yellow",
|
|
33
|
+
"muted": "gray",
|
|
34
|
+
"dim": "dimGray",
|
|
35
|
+
"text": "text",
|
|
36
|
+
"thinkingText": "gray",
|
|
37
|
+
|
|
38
|
+
"selectedBg": "selectedBg",
|
|
39
|
+
"scrollbarTrack": "darkGray",
|
|
40
|
+
"scrollbarThumb": "softCyan",
|
|
41
|
+
"searchMatchBg": "searchBg",
|
|
42
|
+
"searchMatchText": "text",
|
|
43
|
+
"userMessageBg": "userMsgBg",
|
|
44
|
+
"userMessageText": "text",
|
|
45
|
+
"customMessageBg": "customMsgBg",
|
|
46
|
+
"customMessageText": "text",
|
|
47
|
+
"customMessageLabel": "#9575cd",
|
|
48
|
+
"toolPendingBg": "toolPendingBg",
|
|
49
|
+
"toolSuccessBg": "toolSuccessBg",
|
|
50
|
+
"toolErrorBg": "toolErrorBg",
|
|
51
|
+
"toolTitle": "text",
|
|
52
|
+
"toolOutput": "gray",
|
|
53
|
+
|
|
54
|
+
"mdHeading": "#f0c674",
|
|
55
|
+
"mdLink": "#81a2be",
|
|
56
|
+
"mdLinkUrl": "dimGray",
|
|
57
|
+
"mdCode": "accent",
|
|
58
|
+
"mdCodeBlock": "green",
|
|
59
|
+
"mdCodeBlockBorder": "gray",
|
|
60
|
+
"mdQuote": "gray",
|
|
61
|
+
"mdQuoteBorder": "gray",
|
|
62
|
+
"mdHr": "gray",
|
|
63
|
+
"mdListBullet": "accent",
|
|
64
|
+
|
|
65
|
+
"toolDiffAdded": "green",
|
|
66
|
+
"toolDiffRemoved": "red",
|
|
67
|
+
"toolDiffContext": "gray",
|
|
68
|
+
|
|
69
|
+
"syntaxComment": "#6A9955",
|
|
70
|
+
"syntaxKeyword": "#569CD6",
|
|
71
|
+
"syntaxFunction": "#DCDCAA",
|
|
72
|
+
"syntaxVariable": "#9CDCFE",
|
|
73
|
+
"syntaxString": "#CE9178",
|
|
74
|
+
"syntaxNumber": "#B5CEA8",
|
|
75
|
+
"syntaxType": "#4EC9B0",
|
|
76
|
+
"syntaxOperator": "#D4D4D4",
|
|
77
|
+
"syntaxPunctuation": "#D4D4D4",
|
|
78
|
+
|
|
79
|
+
"thinkingOff": "darkGray",
|
|
80
|
+
"thinkingMinimal": "#305f4d",
|
|
81
|
+
"thinkingLow": "#3c8066",
|
|
82
|
+
"thinkingMedium": "#50aa87",
|
|
83
|
+
"thinkingHigh": "#41e1a4",
|
|
84
|
+
"thinkingXhigh": "#4af2b2",
|
|
85
|
+
"thinkingMax": "accent",
|
|
86
|
+
|
|
87
|
+
"bashMode": "green"
|
|
88
|
+
},
|
|
89
|
+
"export": {
|
|
90
|
+
"pageBg": "#18181e",
|
|
91
|
+
"cardBg": "#1e1e24",
|
|
92
|
+
"infoBg": "#3c3728"
|
|
93
|
+
}
|
|
94
|
+
}
|