@tokentop/ttop 0.4.0 → 0.5.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 (75) hide show
  1. package/package.json +9 -4
  2. package/src/agents/aggregator.ts +8 -1
  3. package/src/agents/types.ts +3 -0
  4. package/src/cli.ts +2 -2
  5. package/src/demo/simulator.ts +1 -1
  6. package/src/plugins/agents/index.ts +2 -0
  7. package/src/plugins/auth-sources.ts +2 -3
  8. package/src/plugins/lifecycle.ts +1 -1
  9. package/src/plugins/loader.test.ts +1 -1
  10. package/src/plugins/loader.ts +15 -7
  11. package/src/plugins/notification-bus.ts +5 -2
  12. package/src/plugins/notifications/terminal-bell.ts +1 -1
  13. package/src/plugins/notifications/visual-flash.ts +1 -1
  14. package/src/plugins/plugin-context-factory.ts +4 -19
  15. package/src/plugins/providers/anthropic.ts +2 -2
  16. package/src/plugins/providers/antigravity.ts +1 -1
  17. package/src/plugins/providers/chutes.ts +189 -0
  18. package/src/plugins/providers/codex.ts +1 -1
  19. package/src/plugins/providers/gemini.ts +1 -1
  20. package/src/plugins/providers/github-copilot.ts +1 -1
  21. package/src/plugins/providers/index.ts +1 -0
  22. package/src/plugins/providers/minimax.ts +1 -1
  23. package/src/plugins/providers/openai-api.ts +1 -1
  24. package/src/plugins/providers/opencode-zen.ts +1 -1
  25. package/src/plugins/providers/perplexity.ts +1 -1
  26. package/src/plugins/providers/zai.ts +1 -1
  27. package/src/plugins/registry.ts +9 -9
  28. package/src/plugins/sandbox-guard.test.ts +1 -1
  29. package/src/plugins/sandbox-guard.ts +1 -1
  30. package/src/plugins/sandbox.ts +1 -1
  31. package/src/plugins/themes/catppuccin-latte.ts +1 -1
  32. package/src/plugins/themes/catppuccin-mocha.ts +1 -1
  33. package/src/plugins/themes/claude-code.ts +1 -1
  34. package/src/plugins/themes/dracula.ts +1 -1
  35. package/src/plugins/themes/github-light.ts +1 -1
  36. package/src/plugins/themes/gruvbox-dark.ts +1 -1
  37. package/src/plugins/themes/gruvbox-light.ts +1 -1
  38. package/src/plugins/themes/kanagawa.ts +1 -1
  39. package/src/plugins/themes/nord.ts +1 -1
  40. package/src/plugins/themes/one-dark.ts +1 -1
  41. package/src/plugins/themes/opencode.ts +1 -1
  42. package/src/plugins/themes/rose-pine-dawn.ts +1 -1
  43. package/src/plugins/themes/rose-pine.ts +1 -1
  44. package/src/plugins/themes/solarized-light.ts +1 -1
  45. package/src/plugins/themes/tokyo-night.ts +1 -1
  46. package/src/plugins/update-checker.ts +2 -2
  47. package/src/pricing/estimator.test.ts +1 -1
  48. package/src/pricing/estimator.ts +1 -1
  49. package/src/pricing/fallback.ts +1 -1
  50. package/src/pricing/index.ts +1 -1
  51. package/src/pricing/models-dev.ts +1 -1
  52. package/src/storage/index.ts +6 -0
  53. package/src/storage/migrations/index.ts +17 -0
  54. package/src/storage/repos/pluginStorage.ts +35 -0
  55. package/src/tui/App.tsx +1 -1
  56. package/src/tui/components/ProviderCard.tsx +1 -1
  57. package/src/tui/components/ProviderDetailPanel.tsx +1 -1
  58. package/src/tui/components/SessionDetailsDrawer.tsx +10 -0
  59. package/src/tui/components/SessionsTable.tsx +9 -2
  60. package/src/tui/components/SettingsModal.tsx +1 -1
  61. package/src/tui/components/ThemePicker.tsx +1 -1
  62. package/src/tui/contexts/AgentSessionContext.tsx +1 -1
  63. package/src/tui/contexts/PluginContext.tsx +8 -4
  64. package/src/tui/contexts/RealTimeActivityContext.tsx +33 -20
  65. package/src/tui/contexts/ThemeContext.tsx +3 -3
  66. package/src/tui/hooks/useSessionEnrichedProviders.ts +1 -1
  67. package/src/tui/views/SettingsView.tsx +1 -1
  68. package/src/version.ts +1 -1
  69. package/src/plugins/types/agent.ts +0 -108
  70. package/src/plugins/types/base.ts +0 -278
  71. package/src/plugins/types/index.ts +0 -19
  72. package/src/plugins/types/notification.ts +0 -51
  73. package/src/plugins/types/provider.ts +0 -237
  74. package/src/plugins/types/theme.ts +0 -78
  75. package/src/storage/database.ts +0 -623
@@ -1,278 +0,0 @@
1
- /**
2
- * Base plugin types and interfaces for the tokentop plugin system.
3
- *
4
- * These types mirror the Plugin SDK (@tokentop/plugin-sdk) — the SDK is the
5
- * authoritative contract for community developers; core adapts to match.
6
- */
7
-
8
- import { z } from "zod";
9
-
10
- // ---------------------------------------------------------------------------
11
- // Identity
12
- // ---------------------------------------------------------------------------
13
-
14
- /**
15
- * Plugin type discriminator
16
- */
17
- export type PluginType = "provider" | "agent" | "theme" | "notification";
18
-
19
- /**
20
- * Current API contract version.
21
- * Core checks this at load time to ensure compatibility.
22
- */
23
- export const CURRENT_API_VERSION = 2;
24
-
25
- // ---------------------------------------------------------------------------
26
- // Permissions
27
- // ---------------------------------------------------------------------------
28
-
29
- /**
30
- * Plugin permissions schema - defines what a plugin can access
31
- */
32
- export const PluginPermissionsSchema = z.object({
33
- network: z
34
- .object({
35
- enabled: z.boolean(),
36
- allowedDomains: z.array(z.string()).optional(),
37
- })
38
- .optional(),
39
- filesystem: z
40
- .object({
41
- read: z.boolean().optional(),
42
- write: z.boolean().optional(),
43
- paths: z.array(z.string()).optional(),
44
- })
45
- .optional(),
46
- env: z
47
- .object({
48
- read: z.boolean().optional(),
49
- vars: z.array(z.string()).optional(),
50
- })
51
- .optional(),
52
- system: z
53
- .object({
54
- notifications: z.boolean().optional(),
55
- clipboard: z.boolean().optional(),
56
- })
57
- .optional(),
58
- });
59
-
60
- export type PluginPermissions = z.infer<typeof PluginPermissionsSchema>;
61
-
62
- // ---------------------------------------------------------------------------
63
- // Metadata
64
- // ---------------------------------------------------------------------------
65
-
66
- /**
67
- * Plugin metadata
68
- */
69
- export const PluginMetaSchema = z.object({
70
- author: z.string().optional(),
71
- description: z.string().optional(),
72
- homepage: z.string().url().optional(),
73
- repository: z.string().url().optional(),
74
- license: z.string().optional(),
75
- /**
76
- * Brand color as a hex string (e.g. `"#d97757"`).
77
- * Used by the TUI for provider cards, charts, and status indicators.
78
- */
79
- brandColor: z.string().optional(),
80
- /**
81
- * Single-character icon or short glyph for compact displays.
82
- * Example: `"◆"`, `"▲"`, `"⚡"`
83
- */
84
- icon: z.string().optional(),
85
- /**
86
- * Additional provider IDs that should resolve to this plugin.
87
- * Coding agents may tag sessions with provider IDs that differ from
88
- * the plugin's `id` (e.g. OpenCode uses `"openai"` but the plugin
89
- * registers as `"openai-api"`). List those alternate IDs here so the
90
- * TUI can resolve brand colors and other metadata correctly.
91
- */
92
- providerAliases: z.array(z.string()).optional(),
93
- });
94
-
95
- export type PluginMeta = z.infer<typeof PluginMetaSchema>;
96
-
97
- // ---------------------------------------------------------------------------
98
- // Configuration
99
- // ---------------------------------------------------------------------------
100
-
101
- /**
102
- * Plugin configuration field definition (for plugin settings UI)
103
- */
104
- export interface ConfigField {
105
- /** Data type of the setting value. */
106
- type: "string" | "number" | "boolean" | "select";
107
- /** Label shown in the settings UI. */
108
- label?: string;
109
- /** Help text shown below the field. */
110
- description?: string;
111
- /** Whether the field must have a value. */
112
- required?: boolean;
113
- /** Default value when no user config exists. */
114
- default?: unknown;
115
- /** Available options (for `select` type only). */
116
- options?: Array<{ value: string; label: string }>;
117
- /** Minimum value (for `number` type only). */
118
- min?: number;
119
- /** Maximum value (for `number` type only). */
120
- max?: number;
121
- }
122
-
123
- // ---------------------------------------------------------------------------
124
- // Lifecycle Context
125
- // ---------------------------------------------------------------------------
126
-
127
- /**
128
- * Minimal context provided to lifecycle hooks.
129
- */
130
- export interface PluginLifecycleContext {
131
- /** Plugin's validated configuration values. */
132
- readonly config: Record<string, unknown>;
133
- /** Scoped logger that prefixes all output with the plugin ID. */
134
- readonly logger: PluginLogger;
135
- }
136
-
137
- // ---------------------------------------------------------------------------
138
- // Base Plugin
139
- // ---------------------------------------------------------------------------
140
-
141
- /**
142
- * Base plugin interface - all plugins must implement this.
143
- *
144
- * Provides identity, metadata, permissions, optional configuration schema,
145
- * and lifecycle hooks.
146
- */
147
- export interface BasePlugin {
148
- /** API version this plugin targets. Must equal {@link CURRENT_API_VERSION}. */
149
- readonly apiVersion: 2;
150
-
151
- /** Unique plugin identifier (kebab-case) */
152
- readonly id: string;
153
-
154
- /** Plugin type discriminator */
155
- readonly type: PluginType;
156
-
157
- /** Human-readable display name */
158
- readonly name: string;
159
-
160
- /** Semantic version string */
161
- readonly version: string;
162
-
163
- /** Plugin metadata */
164
- readonly meta?: PluginMeta;
165
-
166
- /** Required permissions */
167
- readonly permissions: PluginPermissions;
168
-
169
- /** Plugin-declared configuration fields, rendered in Settings UI */
170
- readonly configSchema?: Record<string, ConfigField>;
171
-
172
- /**
173
- * Default config values. Used when no user configuration exists.
174
- * Keys must match those in {@link configSchema}.
175
- */
176
- readonly defaultConfig?: Record<string, unknown>;
177
-
178
- // -- Lifecycle Hooks (all optional) -------------------------------------
179
-
180
- /**
181
- * Called once after the plugin is loaded and validated.
182
- * Use for one-time setup (open connections, allocate resources).
183
- */
184
- initialize?(ctx: PluginLifecycleContext): Promise<void>;
185
-
186
- /**
187
- * Called when the plugin should begin active work (e.g. polling).
188
- * Called after `initialize()` during app startup, and after re-enable.
189
- */
190
- start?(ctx: PluginLifecycleContext): Promise<void>;
191
-
192
- /**
193
- * Called when the plugin should pause active work.
194
- * Called before `destroy()` during app shutdown, and on disable.
195
- */
196
- stop?(ctx: PluginLifecycleContext): Promise<void>;
197
-
198
- /**
199
- * Called once before the plugin is unloaded.
200
- * Use for cleanup (close connections, flush buffers).
201
- */
202
- destroy?(ctx: PluginLifecycleContext): Promise<void>;
203
-
204
- /**
205
- * Called when the user changes this plugin's configuration.
206
- * Receive the new validated config values.
207
- */
208
- onConfigChange?(
209
- config: Record<string, unknown>,
210
- ctx: PluginLifecycleContext,
211
- ): Promise<void> | void;
212
- }
213
-
214
- // ---------------------------------------------------------------------------
215
- // Logger
216
- // ---------------------------------------------------------------------------
217
-
218
- /**
219
- * Logger interface provided to plugins
220
- */
221
- export interface PluginLogger {
222
- debug(message: string, data?: Record<string, unknown>): void;
223
- info(message: string, data?: Record<string, unknown>): void;
224
- warn(message: string, data?: Record<string, unknown>): void;
225
- error(message: string, data?: Record<string, unknown>): void;
226
- }
227
-
228
- // ---------------------------------------------------------------------------
229
- // HTTP Client
230
- // ---------------------------------------------------------------------------
231
-
232
- /**
233
- * HTTP client interface provided to plugins (sandboxed)
234
- */
235
- export interface PluginHttpClient {
236
- fetch(url: string, init?: RequestInit): Promise<Response>;
237
- }
238
-
239
- // ---------------------------------------------------------------------------
240
- // Validation
241
- // ---------------------------------------------------------------------------
242
-
243
- /**
244
- * Plugin validation result
245
- */
246
- export interface PluginValidationResult {
247
- valid: boolean;
248
- errors: string[];
249
- warnings: string[];
250
- }
251
-
252
- /**
253
- * Plugin load result
254
- */
255
- export interface PluginLoadResult<T extends BasePlugin = BasePlugin> {
256
- success: boolean;
257
- plugin?: T;
258
- error?: string;
259
- source: "builtin" | "local" | "npm";
260
- }
261
-
262
- // ---------------------------------------------------------------------------
263
- // Errors
264
- // ---------------------------------------------------------------------------
265
-
266
- /**
267
- * Plugin permission error
268
- */
269
- export class PluginPermissionError extends Error {
270
- constructor(
271
- public readonly pluginId: string,
272
- public readonly permission: keyof PluginPermissions,
273
- message: string,
274
- ) {
275
- super(`Plugin "${pluginId}" permission denied: ${message}`);
276
- this.name = "PluginPermissionError";
277
- }
278
- }
@@ -1,19 +0,0 @@
1
- export * from "./agent.ts";
2
- export * from "./base.ts";
3
- export * from "./notification.ts";
4
- export * from "./provider.ts";
5
- export * from "./theme.ts";
6
-
7
- import type { AgentPlugin } from "./agent.ts";
8
- import type { NotificationPlugin } from "./notification.ts";
9
- import type { ProviderPlugin } from "./provider.ts";
10
- import type { ThemePlugin } from "./theme.ts";
11
-
12
- export type AnyPlugin = ProviderPlugin | AgentPlugin | ThemePlugin | NotificationPlugin;
13
-
14
- export type PluginByType = {
15
- provider: ProviderPlugin;
16
- agent: AgentPlugin;
17
- theme: ThemePlugin;
18
- notification: NotificationPlugin;
19
- };
@@ -1,51 +0,0 @@
1
- import type { BasePlugin, PluginLogger } from "./base.ts";
2
-
3
- // ---------------------------------------------------------------------------
4
- // Notification Events
5
- // ---------------------------------------------------------------------------
6
-
7
- export type NotificationSeverity = "info" | "warning" | "critical";
8
-
9
- export type NotificationEventType =
10
- | "budget.thresholdCrossed"
11
- | "budget.limitReached"
12
- | "provider.fetchFailed"
13
- | "provider.limitReached"
14
- | "provider.recovered"
15
- | "plugin.crashed"
16
- | "plugin.disabled"
17
- | "app.started"
18
- | "app.updated";
19
-
20
- export interface NotificationEvent {
21
- type: NotificationEventType;
22
- severity: NotificationSeverity;
23
- title: string;
24
- message: string;
25
- timestamp: number;
26
- data?: Record<string, unknown>;
27
- }
28
-
29
- // ---------------------------------------------------------------------------
30
- // Notification Context
31
- // ---------------------------------------------------------------------------
32
-
33
- export interface NotificationContext {
34
- readonly logger: PluginLogger;
35
- readonly config: Record<string, unknown>;
36
- readonly signal: AbortSignal;
37
- }
38
-
39
- // ---------------------------------------------------------------------------
40
- // Notification Plugin
41
- // ---------------------------------------------------------------------------
42
-
43
- export interface NotificationPlugin extends BasePlugin {
44
- readonly type: "notification";
45
-
46
- initialize(ctx: NotificationContext): Promise<void>;
47
- notify(ctx: NotificationContext, event: NotificationEvent): Promise<void>;
48
- test?(ctx: NotificationContext): Promise<boolean>;
49
- supports?(event: NotificationEvent): boolean;
50
- destroy?(): Promise<void>;
51
- }
@@ -1,237 +0,0 @@
1
- import type { BasePlugin, PluginHttpClient, PluginLogger } from "./base.ts";
2
-
3
- export interface ProviderCapabilities {
4
- usageLimits: boolean;
5
- apiRateLimits: boolean;
6
- tokenUsage: boolean;
7
- actualCosts: boolean;
8
- }
9
-
10
- // ---------------------------------------------------------------------------
11
- // Credential types
12
- // ---------------------------------------------------------------------------
13
-
14
- export interface Credentials {
15
- apiKey?: string;
16
- oauth?: OAuthCredentials;
17
- groupId?: string;
18
- source: "env" | "opencode" | "external" | "config";
19
- }
20
-
21
- export interface OAuthCredentials {
22
- accessToken: string;
23
- refreshToken?: string;
24
- expiresAt?: number;
25
- accountId?: string;
26
- managedProjectId?: string;
27
- }
28
-
29
- export interface RefreshedCredentials {
30
- accessToken: string;
31
- refreshToken: string;
32
- expiresAt: number;
33
- }
34
-
35
- // ---------------------------------------------------------------------------
36
- // Auth (plugin-owned discovery)
37
- // ---------------------------------------------------------------------------
38
-
39
- /** Result of a credential discovery attempt. */
40
- export interface CredentialResult {
41
- ok: boolean;
42
- credentials?: Credentials;
43
- reason?: "missing" | "expired" | "invalid" | "error";
44
- message?: string;
45
- }
46
-
47
- /**
48
- * Shape of an entry in OpenCode's auth.json file.
49
- * Used by AuthSources.opencode.getProviderEntry().
50
- */
51
- export interface OpenCodeAuthEntry {
52
- type: "api" | "oauth" | "codex" | "github" | "wellknown";
53
- key?: string;
54
- access?: string;
55
- refresh?: string;
56
- expires?: number;
57
- token?: string;
58
- accessToken?: string;
59
- refreshToken?: string;
60
- expiresAt?: number;
61
- accountId?: string;
62
- groupId?: string;
63
- }
64
-
65
- /**
66
- * Sandboxed auth source helpers injected into plugins.
67
- * All methods respect the plugin's declared permissions.
68
- */
69
- export interface AuthSources {
70
- /** Read an environment variable (sandboxed to `permissions.env.vars`). */
71
- env: {
72
- get(name: string): string | undefined;
73
- };
74
-
75
- /** Read files from the filesystem (sandboxed to `permissions.filesystem.paths`). */
76
- files: {
77
- readText(path: string): Promise<string | null>;
78
- readJson<T = unknown>(path: string): Promise<T | null>;
79
- exists(path: string): Promise<boolean>;
80
- };
81
-
82
- /**
83
- * Read from OpenCode's auth storage.
84
- * Core handles locating the auth file; plugin provides the provider key.
85
- */
86
- opencode: {
87
- getProviderEntry(key: string): Promise<OpenCodeAuthEntry | null>;
88
- };
89
-
90
- /** Platform information for cross-platform credential path resolution. */
91
- platform: {
92
- os: "darwin" | "linux" | "win32";
93
- homedir: string;
94
- arch: string;
95
- };
96
- }
97
-
98
- /** Per-plugin key-value storage (namespaced by plugin ID). */
99
- export interface PluginStorage {
100
- get(key: string): Promise<string | null>;
101
- set(key: string, value: string): Promise<void>;
102
- delete(key: string): Promise<void>;
103
- has(key: string): Promise<boolean>;
104
- }
105
-
106
- /** Full runtime context provided to plugin methods like `auth.discover()`. */
107
- export interface PluginContext {
108
- /** Plugin's validated configuration values. */
109
- readonly config: Record<string, unknown>;
110
- /** Scoped logger. */
111
- readonly logger: PluginLogger;
112
- /** Sandboxed HTTP client. */
113
- readonly http: PluginHttpClient;
114
- /** Credential discovery helpers. */
115
- readonly authSources: AuthSources;
116
- /** Per-plugin persistent key-value storage. */
117
- readonly storage: PluginStorage;
118
- /** Abort signal — fired when the plugin is being stopped or the app is shutting down. */
119
- readonly signal: AbortSignal;
120
- }
121
-
122
- export interface ProviderAuth {
123
- /** Discover credentials using the provided context helpers. */
124
- discover(ctx: PluginContext): Promise<CredentialResult>;
125
- /** Check whether discovered credentials are sufficient to operate. */
126
- isConfigured(credentials: Credentials): boolean;
127
- }
128
-
129
- // ---------------------------------------------------------------------------
130
- // Pricing
131
- // ---------------------------------------------------------------------------
132
-
133
- export interface ModelPricing {
134
- input: number;
135
- output: number;
136
- cacheRead?: number;
137
- cacheWrite?: number;
138
- source?: string;
139
- }
140
-
141
- /** Pricing configuration for a provider's models. */
142
- export interface ProviderPricing {
143
- /**
144
- * Map a model ID to the identifier used by the pricing service.
145
- * Return `undefined` to use the model ID as-is.
146
- */
147
- mapModelId?(modelId: string): string | undefined;
148
- /**
149
- * The provider ID to use when querying models.dev.
150
- * Defaults to `plugin.id` if not specified.
151
- */
152
- modelsDevProviderId?: string;
153
- /** Static fallback prices keyed by model ID. */
154
- staticPrices?: Record<string, ModelPricing>;
155
- }
156
-
157
- // ---------------------------------------------------------------------------
158
- // Usage data
159
- // ---------------------------------------------------------------------------
160
-
161
- export interface UsageLimit {
162
- usedPercent: number | null;
163
- resetsAt?: number;
164
- label?: string;
165
- windowMinutes?: number;
166
- }
167
-
168
- export interface CostBreakdown {
169
- total: number;
170
- input?: number;
171
- output?: number;
172
- cacheRead?: number;
173
- cacheWrite?: number;
174
- currency: string;
175
- }
176
-
177
- export interface ProviderUsageData {
178
- planType?: string;
179
- allowed?: boolean;
180
- limitReached?: boolean;
181
- limits?: {
182
- primary?: UsageLimit;
183
- secondary?: UsageLimit;
184
- items?: UsageLimit[];
185
- };
186
- tokens?: {
187
- input: number;
188
- output: number;
189
- cacheRead?: number;
190
- cacheWrite?: number;
191
- };
192
- credits?: {
193
- hasCredits: boolean;
194
- unlimited: boolean;
195
- balance?: string;
196
- };
197
- cost?: {
198
- actual?: CostBreakdown;
199
- estimated?: CostBreakdown;
200
- /** Session-derived daily cost (today only). Set by enrichment hook. */
201
- estimatedDaily?: CostBreakdown;
202
- /** Session-derived monthly cost (MTD). Set by enrichment hook. */
203
- estimatedMonthly?: CostBreakdown;
204
- source: "api" | "estimated";
205
- };
206
- fetchedAt: number;
207
- error?: string;
208
- }
209
-
210
- // ---------------------------------------------------------------------------
211
- // Fetch context
212
- // ---------------------------------------------------------------------------
213
-
214
- export interface ProviderFetchContext {
215
- readonly credentials: Credentials;
216
- readonly http: PluginHttpClient;
217
- readonly logger: PluginLogger;
218
- readonly config: Record<string, unknown>;
219
- readonly signal: AbortSignal;
220
- readonly options?: {
221
- timePeriod?: "session" | "daily" | "weekly" | "monthly";
222
- sessionId?: string;
223
- };
224
- }
225
-
226
- // ---------------------------------------------------------------------------
227
- // Provider Plugin
228
- // ---------------------------------------------------------------------------
229
-
230
- export interface ProviderPlugin extends BasePlugin {
231
- readonly type: "provider";
232
- readonly capabilities: ProviderCapabilities;
233
- readonly auth: ProviderAuth;
234
- readonly pricing?: ProviderPricing;
235
- fetchUsage(ctx: ProviderFetchContext): Promise<ProviderUsageData>;
236
- refreshToken?(auth: OAuthCredentials): Promise<RefreshedCredentials>;
237
- }
@@ -1,78 +0,0 @@
1
- import { z } from "zod";
2
- import type { BasePlugin } from "./base.ts";
3
-
4
- export const ThemeColorsSchema = z.object({
5
- background: z.string(),
6
- foreground: z.string(),
7
- text: z.string(),
8
- textMuted: z.string(),
9
- textSubtle: z.string(),
10
- primary: z.string(),
11
- secondary: z.string(),
12
- accent: z.string(),
13
- success: z.string(),
14
- warning: z.string(),
15
- error: z.string(),
16
- info: z.string(),
17
- border: z.string(),
18
- borderMuted: z.string(),
19
- selection: z.string(),
20
- highlight: z.string(),
21
- gaugeBackground: z.string(),
22
- gaugeFill: z.string(),
23
- gaugeWarning: z.string(),
24
- gaugeDanger: z.string(),
25
- });
26
-
27
- export type ThemeColors = z.infer<typeof ThemeColorsSchema>;
28
-
29
- export const ThemeComponentsSchema = z.object({
30
- header: z
31
- .object({
32
- background: z.string().optional(),
33
- foreground: z.string().optional(),
34
- titleColor: z.string().optional(),
35
- titleAccentColor: z.string().optional(),
36
- })
37
- .optional(),
38
- statusBar: z
39
- .object({
40
- background: z.string().optional(),
41
- foreground: z.string().optional(),
42
- })
43
- .optional(),
44
- commandPalette: z
45
- .object({
46
- background: z.string().optional(),
47
- border: z.string().optional(),
48
- })
49
- .optional(),
50
- gauge: z
51
- .object({
52
- height: z.number().optional(),
53
- borderRadius: z.number().optional(),
54
- })
55
- .optional(),
56
- });
57
-
58
- export type ThemeComponents = z.infer<typeof ThemeComponentsSchema>;
59
-
60
- export type ColorScheme = "light" | "dark";
61
-
62
- export type ColorSchemePreference = "auto" | "light" | "dark";
63
-
64
- export interface ThemePlugin extends BasePlugin {
65
- readonly type: "theme";
66
- readonly family: string;
67
- readonly colorScheme: ColorScheme;
68
- readonly colors: ThemeColors;
69
- readonly components?: ThemeComponents;
70
- }
71
-
72
- export interface ResolvedTheme {
73
- id: string;
74
- name: string;
75
- colorScheme: ColorScheme;
76
- colors: ThemeColors;
77
- components: ThemeComponents;
78
- }