tokmon 0.22.7 → 0.23.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.
Files changed (57) hide show
  1. package/README.md +1 -0
  2. package/dist/{bootstrap-ink-OHPQZKGB.js → bootstrap-ink-UD3KDTOB.js} +1113 -818
  3. package/dist/{chunk-EMQL5P5J.js → chunk-AON6GE7D.js} +368 -280
  4. package/dist/{chunk-TNIADJ3W.js → chunk-DJPUYMZM.js} +49 -16
  5. package/dist/chunk-HXDAOOSI.js +154 -0
  6. package/dist/{chunk-I4USANOF.js → chunk-PGQK7MOE.js} +879 -391
  7. package/dist/chunk-RM3ZE44Z.js +193 -0
  8. package/dist/cli.js +93 -54
  9. package/dist/{config-WLRQHLVJ.js → config-5CNJN3P7.js} +1 -1
  10. package/dist/daemon-QGCI46US.js +193 -0
  11. package/dist/daemon-handle-4F4TXGXJ.js +163 -0
  12. package/dist/server-4CDZMLH6.js +10 -0
  13. package/dist/web/assets/Area-DGo9K-U3.js +2 -0
  14. package/dist/web/assets/analytics-BOhbhV5Z.js +2 -0
  15. package/dist/web/assets/breakdown-CO04nSN-.js +4 -0
  16. package/dist/web/assets/chart-bNxdfXxA.js +69 -0
  17. package/dist/web/assets/explore-sZnmjzAj.js +22 -0
  18. package/dist/web/assets/index-DSj-Bxov.css +1 -0
  19. package/dist/web/assets/index-DnDr1VUr.js +83 -0
  20. package/dist/web/assets/models-Cl6D8VVF.js +2 -0
  21. package/dist/web/assets/overview-C18nvaAK.js +2 -0
  22. package/dist/web/assets/panel-DTjMnHaz.js +1 -0
  23. package/dist/web/assets/primitives-Dj_9YxTF.js +1 -0
  24. package/dist/web/assets/settings-sheet-0BGb5Ahv.js +1 -0
  25. package/dist/web/assets/share-sheet-BHtt-OmT.js +2 -0
  26. package/dist/web/assets/timeline-DmzB8Z3W.js +1 -0
  27. package/dist/web/assets/use-dialog-trap-DeXFtxx8.js +1 -0
  28. package/dist/web/index.html +3 -2
  29. package/package.json +9 -5
  30. package/dist/daemon-IP3UCTPB.js +0 -213
  31. package/dist/daemon-handle-HLSKLMWU.js +0 -142
  32. package/dist/server-GA2FKYDQ.js +0 -9
  33. package/dist/web/assets/breakdown-DU2j1sQ8.js +0 -4
  34. package/dist/web/assets/index-BCaPGYQA.css +0 -1
  35. package/dist/web/assets/index-ygZyXDLT.js +0 -173
  36. package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  37. package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  38. package/dist/web/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  39. package/dist/web/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  40. package/dist/web/assets/jetbrains-mono-cyrillic-700-normal-BWTpRfYl.woff2 +0 -0
  41. package/dist/web/assets/jetbrains-mono-cyrillic-700-normal-CEoEElIJ.woff +0 -0
  42. package/dist/web/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  43. package/dist/web/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  44. package/dist/web/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  45. package/dist/web/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  46. package/dist/web/assets/jetbrains-mono-greek-700-normal-C6CZE3T8.woff2 +0 -0
  47. package/dist/web/assets/jetbrains-mono-greek-700-normal-DEigVDxa.woff +0 -0
  48. package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  49. package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  50. package/dist/web/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  51. package/dist/web/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  52. package/dist/web/assets/jetbrains-mono-latin-ext-700-normal-CZipNAKV.woff2 +0 -0
  53. package/dist/web/assets/jetbrains-mono-latin-ext-700-normal-CxPITLHs.woff +0 -0
  54. package/dist/web/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  55. package/dist/web/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  56. package/dist/web/assets/jetbrains-mono-vietnamese-700-normal-BDLVIk2r.woff +0 -0
  57. package/dist/web/assets/timeline-CO2B2c-0.js +0 -1
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/config.ts
4
- import { readFile, writeFile, mkdir, rename } from "fs/promises";
5
- import { mkdirSync, renameSync, writeFileSync } from "fs";
4
+ import { chmod, readFile, writeFile, mkdir, rename, unlink } from "fs/promises";
5
+ import { chmodSync, mkdirSync, renameSync, unlinkSync, writeFileSync } from "fs";
6
6
  import { join, isAbsolute } from "path";
7
7
  import { homedir } from "os";
8
8
 
@@ -11,6 +11,7 @@ var PROVIDER_IDS = ["claude", "codex", "cursor", "copilot", "pi", "opencode", "a
11
11
 
12
12
  // src/config-schema.ts
13
13
  var DEFAULTS = {
14
+ revision: 0,
14
15
  interval: 2,
15
16
  billingInterval: 5,
16
17
  clearScreen: true,
@@ -199,6 +200,7 @@ function repairConfig(input) {
199
200
  }
200
201
  const config = {
201
202
  ...DEFAULTS,
203
+ revision: typeof parsed.revision === "number" && Number.isSafeInteger(parsed.revision) && parsed.revision >= 0 ? parsed.revision : DEFAULTS.revision,
202
204
  interval: clampNum(parsed.interval, DEFAULTS.interval, 1),
203
205
  billingInterval: clampNum(parsed.billingInterval, DEFAULTS.billingInterval, 1),
204
206
  clearScreen: typeof parsed.clearScreen === "boolean" ? parsed.clearScreen : DEFAULTS.clearScreen,
@@ -284,12 +286,22 @@ async function loadConfig() {
284
286
  } catch {
285
287
  return { ...DEFAULTS };
286
288
  }
289
+ try {
290
+ await chmod(configDir(), 448);
291
+ await chmod(configLocation(), 384);
292
+ } catch {
293
+ }
287
294
  let parsed;
288
295
  try {
289
296
  parsed = JSON.parse(raw);
290
297
  } catch {
291
298
  try {
292
- await writeFile(configLocation() + ".bak", raw);
299
+ const dir = configDir();
300
+ await mkdir(dir, { recursive: true, mode: 448 });
301
+ await chmod(dir, 448);
302
+ const backup = configLocation() + ".bak";
303
+ await writeFile(backup, raw, { mode: 384 });
304
+ await chmod(backup, 384);
293
305
  } catch {
294
306
  }
295
307
  return { ...DEFAULTS };
@@ -304,30 +316,51 @@ async function loadConfig() {
304
316
  return repaired.config;
305
317
  }
306
318
  var saveQueue = Promise.resolve();
319
+ var tempSequence = 0;
320
+ function configTempFile(dir) {
321
+ tempSequence = (tempSequence + 1) % Number.MAX_SAFE_INTEGER;
322
+ return join(dir, `config.json.${process.pid}.${Date.now()}.${tempSequence}.tmp`);
323
+ }
307
324
  function configJson(config) {
308
325
  return JSON.stringify(normalizeConfig(config), null, 2) + "\n";
309
326
  }
310
327
  function saveConfig(config) {
311
- saveQueue = saveQueue.then(async () => {
328
+ const write = async () => {
329
+ const dir = configDir();
330
+ await mkdir(dir, { recursive: true, mode: 448 });
331
+ await chmod(dir, 448);
332
+ const tmp = configTempFile(dir);
312
333
  try {
313
- const dir = configDir();
314
- await mkdir(dir, { recursive: true });
315
- const tmp = join(dir, `config.json.${process.pid}.tmp`);
316
- await writeFile(tmp, configJson(config));
334
+ await writeFile(tmp, configJson(config), { mode: 384 });
335
+ await chmod(tmp, 384);
317
336
  await rename(tmp, configLocation());
318
- } catch {
337
+ } catch (error) {
338
+ try {
339
+ await unlink(tmp);
340
+ } catch {
341
+ }
342
+ throw error;
319
343
  }
320
- });
321
- return saveQueue;
344
+ };
345
+ const operation = saveQueue.catch(() => void 0).then(write);
346
+ saveQueue = operation;
347
+ return operation;
322
348
  }
323
349
  function saveConfigSync(config) {
350
+ const dir = configDir();
351
+ mkdirSync(dir, { recursive: true, mode: 448 });
352
+ chmodSync(dir, 448);
353
+ const tmp = configTempFile(dir);
324
354
  try {
325
- const dir = configDir();
326
- mkdirSync(dir, { recursive: true });
327
- const tmp = join(dir, `config.json.${process.pid}.tmp`);
328
- writeFileSync(tmp, configJson(config));
355
+ writeFileSync(tmp, configJson(config), { mode: 384 });
356
+ chmodSync(tmp, 384);
329
357
  renameSync(tmp, configLocation());
330
- } catch {
358
+ } catch (error) {
359
+ try {
360
+ unlinkSync(tmp);
361
+ } catch {
362
+ }
363
+ throw error;
331
364
  }
332
365
  }
333
366
  function expandHome(p) {
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/web/static.ts
4
+ import { createReadStream, existsSync, readFileSync } from "fs";
5
+ import { stat } from "fs/promises";
6
+ import { fileURLToPath } from "url";
7
+ import { extname, join, normalize, sep } from "path";
8
+ var MIME = {
9
+ ".html": "text/html; charset=utf-8",
10
+ ".js": "text/javascript; charset=utf-8",
11
+ ".mjs": "text/javascript; charset=utf-8",
12
+ ".css": "text/css; charset=utf-8",
13
+ ".json": "application/json; charset=utf-8",
14
+ ".svg": "image/svg+xml",
15
+ ".png": "image/png",
16
+ ".jpg": "image/jpeg",
17
+ ".jpeg": "image/jpeg",
18
+ ".gif": "image/gif",
19
+ ".ico": "image/x-icon",
20
+ ".woff": "font/woff",
21
+ ".woff2": "font/woff2",
22
+ ".ttf": "font/ttf",
23
+ ".otf": "font/otf",
24
+ ".map": "application/json; charset=utf-8",
25
+ ".webmanifest": "application/manifest+json"
26
+ };
27
+ function findWebRoot() {
28
+ const candidates = ["./web/", "../web/", "../dist/web/", "../../dist/web/"];
29
+ for (const rel of candidates) {
30
+ try {
31
+ const dir = fileURLToPath(new URL(rel, import.meta.url));
32
+ if (existsSync(join(dir, "index.html"))) return dir.replace(/[\\/]+$/, "");
33
+ } catch {
34
+ }
35
+ }
36
+ return null;
37
+ }
38
+ function resolveStaticPath(webRoot, urlPath) {
39
+ let clean;
40
+ try {
41
+ clean = decodeURIComponent(urlPath.split("?")[0]);
42
+ } catch {
43
+ return null;
44
+ }
45
+ const rel = normalize(clean).replace(/^(\.\.[/\\])+/, "").replace(/^[/\\]+/, "");
46
+ const full = join(webRoot, rel);
47
+ if (full !== webRoot && !full.startsWith(webRoot + sep)) return null;
48
+ return full;
49
+ }
50
+ function send(res, status, type, body) {
51
+ res.writeHead(status, {
52
+ "Content-Type": type,
53
+ "Cache-Control": "no-store",
54
+ "Referrer-Policy": "no-referrer",
55
+ "X-Content-Type-Options": "nosniff"
56
+ });
57
+ res.end(body);
58
+ }
59
+ function sendJson(res, status, data) {
60
+ send(res, status, "application/json; charset=utf-8", JSON.stringify(data));
61
+ }
62
+ function serveStatic(webRoot, urlPath, res) {
63
+ const path = urlPath.split("?")[0];
64
+ const filePath = resolveStaticPath(webRoot, path === "/" ? "/index.html" : path);
65
+ if (!filePath) {
66
+ send(res, 403, "text/plain", "forbidden");
67
+ return;
68
+ }
69
+ void stat(filePath).then((st) => {
70
+ if (st.isFile()) {
71
+ const type = MIME[extname(filePath).toLowerCase()] || "application/octet-stream";
72
+ const immutable = filePath.includes(`${sep}assets${sep}`);
73
+ res.writeHead(200, {
74
+ "Content-Type": type,
75
+ "Cache-Control": immutable ? "public, max-age=31536000, immutable" : "no-cache",
76
+ "Referrer-Policy": "no-referrer",
77
+ "X-Content-Type-Options": "nosniff"
78
+ });
79
+ createReadStream(filePath).pipe(res);
80
+ } else {
81
+ throw new Error("not a file");
82
+ }
83
+ }).catch(() => {
84
+ if (extname(path)) {
85
+ send(res, 404, "text/plain", "not found");
86
+ return;
87
+ }
88
+ const indexPath = join(webRoot, "index.html");
89
+ if (!existsSync(indexPath)) {
90
+ send(res, 404, "text/plain", "not found");
91
+ return;
92
+ }
93
+ res.writeHead(200, {
94
+ "Content-Type": MIME[".html"],
95
+ "Cache-Control": "no-cache",
96
+ "Referrer-Policy": "no-referrer",
97
+ "X-Content-Type-Options": "nosniff"
98
+ });
99
+ createReadStream(indexPath).on("error", () => {
100
+ try {
101
+ res.destroy();
102
+ } catch {
103
+ }
104
+ }).pipe(res);
105
+ });
106
+ }
107
+ function appVersion() {
108
+ for (const rel of ["../package.json", "../../package.json"]) {
109
+ try {
110
+ const p = fileURLToPath(new URL(rel, import.meta.url));
111
+ const pkg = JSON.parse(readFileSync(p, "utf-8"));
112
+ if (typeof pkg.version === "string") return pkg.version;
113
+ } catch {
114
+ }
115
+ }
116
+ return "";
117
+ }
118
+
119
+ // src/web/open.ts
120
+ import { spawn } from "child_process";
121
+ import { appendFileSync } from "fs";
122
+ function browserUrl(url, wsToken) {
123
+ return wsToken ? `${url}#tokmonToken=${encodeURIComponent(wsToken)}` : url;
124
+ }
125
+ function openBrowser(url, wsToken) {
126
+ const target = browserUrl(url, wsToken);
127
+ if (process.env.TOKMON_OPENLOG) {
128
+ try {
129
+ appendFileSync(process.env.TOKMON_OPENLOG, target + "\n");
130
+ } catch {
131
+ }
132
+ return;
133
+ }
134
+ try {
135
+ if (process.platform === "darwin") {
136
+ spawn("open", [target], { stdio: "ignore", detached: true }).unref();
137
+ } else if (process.platform === "win32") {
138
+ spawn("cmd", ["/c", "start", "", target], { stdio: "ignore", detached: true }).unref();
139
+ } else {
140
+ spawn("xdg-open", [target], { stdio: "ignore", detached: true }).unref();
141
+ }
142
+ } catch {
143
+ }
144
+ }
145
+
146
+ export {
147
+ findWebRoot,
148
+ send,
149
+ sendJson,
150
+ serveStatic,
151
+ appVersion,
152
+ browserUrl,
153
+ openBrowser
154
+ };