@tokentop/ttop 0.2.2 → 0.4.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.
Files changed (160) hide show
  1. package/README.md +2 -5
  2. package/package.json +8 -5
  3. package/src/agents/aggregator.ts +39 -19
  4. package/src/agents/costing.ts +11 -9
  5. package/src/agents/index.ts +7 -9
  6. package/src/agents/types.ts +2 -2
  7. package/src/cli.ts +28 -23
  8. package/src/config/schema.test.ts +42 -40
  9. package/src/config/schema.ts +26 -26
  10. package/src/demo/simulator.ts +161 -122
  11. package/src/plugins/agents/index.ts +2 -2
  12. package/src/plugins/auth-sources.ts +42 -38
  13. package/src/plugins/lifecycle.ts +42 -38
  14. package/src/plugins/loader.test.ts +49 -49
  15. package/src/plugins/loader.ts +67 -63
  16. package/src/plugins/notification-bus.ts +21 -16
  17. package/src/plugins/notifications/index.ts +2 -2
  18. package/src/plugins/notifications/terminal-bell.ts +36 -23
  19. package/src/plugins/notifications/visual-flash.ts +31 -19
  20. package/src/plugins/npm-installer.ts +23 -25
  21. package/src/plugins/plugin-context-factory.ts +10 -10
  22. package/src/plugins/plugin-host.ts +12 -5
  23. package/src/plugins/providers/anthropic.ts +64 -57
  24. package/src/plugins/providers/antigravity.ts +81 -69
  25. package/src/plugins/providers/codex.ts +42 -42
  26. package/src/plugins/providers/gemini.ts +106 -87
  27. package/src/plugins/providers/github-copilot.ts +49 -45
  28. package/src/plugins/providers/index.ts +10 -12
  29. package/src/plugins/providers/minimax.ts +50 -44
  30. package/src/plugins/providers/openai-api.ts +82 -62
  31. package/src/plugins/providers/opencode-zen.ts +46 -39
  32. package/src/plugins/providers/perplexity.ts +55 -46
  33. package/src/plugins/providers/zai.ts +68 -57
  34. package/src/plugins/registry.ts +80 -71
  35. package/src/plugins/sandbox-guard.test.ts +45 -48
  36. package/src/plugins/sandbox-guard.ts +20 -25
  37. package/src/plugins/sandbox.ts +26 -48
  38. package/src/plugins/themes/catppuccin-latte.ts +29 -29
  39. package/src/plugins/themes/catppuccin-mocha.ts +29 -29
  40. package/src/plugins/themes/claude-code.ts +29 -29
  41. package/src/plugins/themes/dracula.ts +29 -29
  42. package/src/plugins/themes/github-light.ts +29 -29
  43. package/src/plugins/themes/gruvbox-dark.ts +29 -29
  44. package/src/plugins/themes/gruvbox-light.ts +29 -29
  45. package/src/plugins/themes/index.ts +15 -15
  46. package/src/plugins/themes/kanagawa.ts +29 -29
  47. package/src/plugins/themes/nord.ts +29 -29
  48. package/src/plugins/themes/one-dark.ts +29 -29
  49. package/src/plugins/themes/opencode.ts +31 -31
  50. package/src/plugins/themes/rose-pine-dawn.ts +29 -29
  51. package/src/plugins/themes/rose-pine.ts +29 -29
  52. package/src/plugins/themes/solarized-light.ts +29 -29
  53. package/src/plugins/themes/tokyo-night.ts +29 -29
  54. package/src/plugins/types/agent.ts +5 -5
  55. package/src/plugins/types/base.ts +35 -24
  56. package/src/plugins/types/index.ts +9 -9
  57. package/src/plugins/types/notification.ts +12 -12
  58. package/src/plugins/types/provider.ts +12 -8
  59. package/src/plugins/types/theme.ts +31 -23
  60. package/src/plugins/update-checker.ts +6 -6
  61. package/src/pricing/estimator.test.ts +39 -44
  62. package/src/pricing/estimator.ts +7 -13
  63. package/src/pricing/fallback.test.ts +30 -34
  64. package/src/pricing/fallback.ts +54 -27
  65. package/src/pricing/index.ts +18 -12
  66. package/src/pricing/models-dev.ts +6 -6
  67. package/src/storage/database.ts +56 -46
  68. package/src/storage/db.ts +12 -12
  69. package/src/storage/index.ts +44 -45
  70. package/src/storage/migrations/index.ts +2 -2
  71. package/src/storage/paths.ts +13 -13
  72. package/src/storage/persistence-service.ts +206 -0
  73. package/src/storage/repos/agentSessions.ts +33 -23
  74. package/src/storage/repos/providerSnapshots.ts +5 -5
  75. package/src/storage/repos/usageEvents.ts +40 -28
  76. package/src/storage/retention.ts +146 -0
  77. package/src/storage/types.ts +5 -5
  78. package/src/tui/App.tsx +180 -137
  79. package/src/tui/components/CommandPalette.tsx +46 -34
  80. package/src/tui/components/DebugConsole.tsx +39 -33
  81. package/src/tui/components/DebugPanel.tsx +314 -183
  82. package/src/tui/components/FooterHints.tsx +2 -2
  83. package/src/tui/components/GhostProviderCard.tsx +37 -35
  84. package/src/tui/components/Header.tsx +68 -35
  85. package/src/tui/components/HelpOverlay.tsx +99 -29
  86. package/src/tui/components/InlineGauge.tsx +10 -7
  87. package/src/tui/components/InlineSparkline.tsx +17 -11
  88. package/src/tui/components/KpiStrip.tsx +128 -98
  89. package/src/tui/components/LimitGauge.tsx +96 -59
  90. package/src/tui/components/ModalBackdrop.tsx +4 -4
  91. package/src/tui/components/ProviderAggregateStrip.tsx +69 -38
  92. package/src/tui/components/ProviderCard.tsx +232 -226
  93. package/src/tui/components/ProviderDetailPanel.tsx +133 -58
  94. package/src/tui/components/ProviderLimitsPanel.tsx +126 -89
  95. package/src/tui/components/ProvidersList.tsx +215 -126
  96. package/src/tui/components/SessionDetailsDrawer.tsx +191 -94
  97. package/src/tui/components/SessionsTable.tsx +320 -169
  98. package/src/tui/components/SettingsModal.tsx +593 -269
  99. package/src/tui/components/SidebarBreakdown.tsx +30 -16
  100. package/src/tui/components/Skeleton.tsx +24 -17
  101. package/src/tui/components/SmartSidebar.tsx +360 -258
  102. package/src/tui/components/Sparkline.tsx +64 -52
  103. package/src/tui/components/Spinner.tsx +3 -3
  104. package/src/tui/components/StatusBar.tsx +27 -27
  105. package/src/tui/components/ThemePicker.tsx +67 -66
  106. package/src/tui/components/Toast.tsx +9 -6
  107. package/src/tui/components/UsageGauge.tsx +10 -13
  108. package/src/tui/components/index.ts +5 -5
  109. package/src/tui/contexts/AgentSessionContext.tsx +164 -151
  110. package/src/tui/contexts/ConfigContext.tsx +15 -13
  111. package/src/tui/contexts/DashboardRuntimeContext.tsx +26 -26
  112. package/src/tui/contexts/DemoModeContext.tsx +22 -15
  113. package/src/tui/contexts/DrawerContext.tsx +11 -9
  114. package/src/tui/contexts/InputContext.tsx +2 -2
  115. package/src/tui/contexts/LogContext.tsx +62 -47
  116. package/src/tui/contexts/PluginContext.tsx +238 -183
  117. package/src/tui/contexts/RealTimeActivityContext.tsx +70 -36
  118. package/src/tui/contexts/StorageContext.tsx +95 -149
  119. package/src/tui/contexts/ThemeContext.tsx +21 -16
  120. package/src/tui/contexts/TimeWindowContext.tsx +72 -61
  121. package/src/tui/contexts/ToastContext.tsx +10 -7
  122. package/src/tui/contexts/index.ts +9 -5
  123. package/src/tui/createApp.tsx +8 -12
  124. package/src/tui/debug/captureFrame.ts +25 -28
  125. package/src/tui/debug/snapshot.tsx +179 -162
  126. package/src/tui/driver/assertions.ts +30 -22
  127. package/src/tui/driver/cli.ts +231 -221
  128. package/src/tui/driver/coverage.ts +27 -44
  129. package/src/tui/driver/demo-snapshot.ts +33 -33
  130. package/src/tui/driver/diff.ts +26 -32
  131. package/src/tui/driver/driver.ts +43 -48
  132. package/src/tui/driver/index.ts +36 -40
  133. package/src/tui/driver/recorder.ts +37 -48
  134. package/src/tui/driver/test-workflow.ts +51 -51
  135. package/src/tui/driver/test.ts +25 -25
  136. package/src/tui/hooks/index.ts +24 -20
  137. package/src/tui/hooks/useAnimatedValue.ts +13 -18
  138. package/src/tui/hooks/useDashboardKeyboard.ts +118 -98
  139. package/src/tui/hooks/useDashboardState.ts +26 -24
  140. package/src/tui/hooks/useEmaActivity.ts +82 -74
  141. package/src/tui/hooks/useEntranceAnimation.ts +11 -11
  142. package/src/tui/hooks/useExitAnimation.ts +7 -3
  143. package/src/tui/hooks/usePulse.ts +4 -4
  144. package/src/tui/hooks/useSafeRenderer.ts +5 -5
  145. package/src/tui/hooks/useSessionEnrichedProviders.ts +150 -0
  146. package/src/tui/hooks/useValueFlash.ts +10 -14
  147. package/src/tui/index.tsx +29 -6
  148. package/src/tui/shutdown.ts +19 -0
  149. package/src/tui/utils/providerColor.ts +1 -1
  150. package/src/tui/views/Dashboard.tsx +164 -102
  151. package/src/tui/views/HistoricalTrendsView.tsx +579 -250
  152. package/src/tui/views/ProjectsView.tsx +495 -243
  153. package/src/tui/views/RealTimeDashboard.tsx +176 -116
  154. package/src/tui/views/SettingsView.tsx +225 -189
  155. package/src/tui/views/index.ts +2 -2
  156. package/src/types/opentui-test-utils.d.ts +7 -7
  157. package/src/utils/clipboard.ts +29 -29
  158. package/src/utils/currency.test.ts +53 -53
  159. package/src/utils/currency.ts +35 -32
  160. package/src/version.ts +1 -1
@@ -1,8 +1,8 @@
1
- import * as fs from 'fs/promises';
2
- import * as path from 'path';
3
- import { diffFrames, highlightDiff, type DiffResult } from './diff.ts';
1
+ import * as fs from "fs/promises";
2
+ import * as path from "path";
3
+ import { type DiffResult, diffFrames, highlightDiff } from "./diff.ts";
4
4
 
5
- const DEFAULT_GOLDEN_DIR = './golden';
5
+ const DEFAULT_GOLDEN_DIR = "./golden";
6
6
 
7
7
  export interface GoldenFile {
8
8
  version: 1;
@@ -37,7 +37,7 @@ export interface AssertOptions {
37
37
  function parseGoldenFile(content: string): GoldenFile | null {
38
38
  try {
39
39
  const parsed = JSON.parse(content);
40
- if (parsed.version === 1 && typeof parsed.frame === 'string') {
40
+ if (parsed.version === 1 && typeof parsed.frame === "string") {
41
41
  return parsed as GoldenFile;
42
42
  }
43
43
  return null;
@@ -46,7 +46,12 @@ function parseGoldenFile(content: string): GoldenFile | null {
46
46
  }
47
47
  }
48
48
 
49
- function createGoldenContent(frame: string, width: number, height: number, existingCreatedAt?: string): string {
49
+ function createGoldenContent(
50
+ frame: string,
51
+ width: number,
52
+ height: number,
53
+ existingCreatedAt?: string,
54
+ ): string {
50
55
  const now = new Date().toISOString();
51
56
  const golden: GoldenFile = {
52
57
  version: 1,
@@ -61,7 +66,7 @@ function createGoldenContent(frame: string, width: number, height: number, exist
61
66
 
62
67
  async function tryReadFile(filePath: string): Promise<string | null> {
63
68
  try {
64
- return await fs.readFile(filePath, 'utf-8');
69
+ return await fs.readFile(filePath, "utf-8");
65
70
  } catch {
66
71
  return null;
67
72
  }
@@ -70,14 +75,13 @@ async function tryReadFile(filePath: string): Promise<string | null> {
70
75
  async function tryUnlink(filePath: string): Promise<void> {
71
76
  try {
72
77
  await fs.unlink(filePath);
73
- } catch {
74
- }
78
+ } catch {}
75
79
  }
76
80
 
77
81
  export async function assertSnapshot(
78
82
  name: string,
79
83
  actual: string,
80
- options: AssertOptions = {}
84
+ options: AssertOptions = {},
81
85
  ): Promise<AssertResult> {
82
86
  const {
83
87
  goldenDir = DEFAULT_GOLDEN_DIR,
@@ -115,18 +119,18 @@ export async function assertSnapshot(
115
119
  passed: false,
116
120
  goldenExists,
117
121
  goldenPath: path.resolve(goldenPath),
118
- message: 'Cannot create golden file: width and height are required',
122
+ message: "Cannot create golden file: width and height are required",
119
123
  };
120
124
  }
121
125
 
122
126
  const content = createGoldenContent(actual, width, height, golden?.createdAt);
123
- await fs.writeFile(goldenPath, content, 'utf-8');
127
+ await fs.writeFile(goldenPath, content, "utf-8");
124
128
 
125
129
  if (actualGoldenPath === legacyPath) {
126
130
  await tryUnlink(legacyPath);
127
131
  }
128
132
 
129
- const action = goldenExists ? 'Updated' : 'Created new';
133
+ const action = goldenExists ? "Updated" : "Created new";
130
134
  return {
131
135
  passed: true,
132
136
  goldenExists: !goldenExists ? false : true,
@@ -163,7 +167,7 @@ export async function assertSnapshot(
163
167
  passed: false,
164
168
  goldenExists: false,
165
169
  goldenPath: path.resolve(goldenPath),
166
- message: 'Golden file is corrupted or in unknown format',
170
+ message: "Golden file is corrupted or in unknown format",
167
171
  };
168
172
  }
169
173
 
@@ -208,14 +212,17 @@ export async function listGoldenFiles(goldenDir: string = DEFAULT_GOLDEN_DIR): P
208
212
  try {
209
213
  const files = await fs.readdir(goldenDir);
210
214
  return files
211
- .filter((f) => f.endsWith('.golden.json') || f.endsWith('.golden.txt'))
212
- .map((f) => f.replace('.golden.json', '').replace('.golden.txt', ''));
215
+ .filter((f) => f.endsWith(".golden.json") || f.endsWith(".golden.txt"))
216
+ .map((f) => f.replace(".golden.json", "").replace(".golden.txt", ""));
213
217
  } catch {
214
218
  return [];
215
219
  }
216
220
  }
217
221
 
218
- export async function deleteGoldenFile(name: string, goldenDir: string = DEFAULT_GOLDEN_DIR): Promise<boolean> {
222
+ export async function deleteGoldenFile(
223
+ name: string,
224
+ goldenDir: string = DEFAULT_GOLDEN_DIR,
225
+ ): Promise<boolean> {
219
226
  const jsonPath = path.join(goldenDir, `${name}.golden.json`);
220
227
  const txtPath = path.join(goldenDir, `${name}.golden.txt`);
221
228
 
@@ -224,14 +231,12 @@ export async function deleteGoldenFile(name: string, goldenDir: string = DEFAULT
224
231
  try {
225
232
  await fs.unlink(jsonPath);
226
233
  deleted = true;
227
- } catch {
228
- }
234
+ } catch {}
229
235
 
230
236
  try {
231
237
  await fs.unlink(txtPath);
232
238
  deleted = true;
233
- } catch {
234
- }
239
+ } catch {}
235
240
 
236
241
  return deleted;
237
242
  }
@@ -246,7 +251,10 @@ export interface GoldenFileInfo {
246
251
  isLegacy: boolean;
247
252
  }
248
253
 
249
- export async function getGoldenFile(name: string, goldenDir: string = DEFAULT_GOLDEN_DIR): Promise<GoldenFileInfo | null> {
254
+ export async function getGoldenFile(
255
+ name: string,
256
+ goldenDir: string = DEFAULT_GOLDEN_DIR,
257
+ ): Promise<GoldenFileInfo | null> {
250
258
  const jsonPath = path.join(goldenDir, `${name}.golden.json`);
251
259
  const txtPath = path.join(goldenDir, `${name}.golden.txt`);
252
260