@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.
- package/package.json +9 -4
- package/src/agents/aggregator.ts +8 -1
- package/src/agents/types.ts +3 -0
- package/src/cli.ts +2 -2
- package/src/demo/simulator.ts +1 -1
- package/src/plugins/agents/index.ts +2 -0
- package/src/plugins/auth-sources.ts +2 -3
- package/src/plugins/lifecycle.ts +1 -1
- package/src/plugins/loader.test.ts +1 -1
- package/src/plugins/loader.ts +15 -7
- package/src/plugins/notification-bus.ts +5 -2
- package/src/plugins/notifications/terminal-bell.ts +1 -1
- package/src/plugins/notifications/visual-flash.ts +1 -1
- package/src/plugins/plugin-context-factory.ts +4 -19
- package/src/plugins/providers/anthropic.ts +2 -2
- package/src/plugins/providers/antigravity.ts +1 -1
- package/src/plugins/providers/chutes.ts +189 -0
- package/src/plugins/providers/codex.ts +1 -1
- package/src/plugins/providers/gemini.ts +1 -1
- package/src/plugins/providers/github-copilot.ts +1 -1
- package/src/plugins/providers/index.ts +1 -0
- package/src/plugins/providers/minimax.ts +1 -1
- package/src/plugins/providers/openai-api.ts +1 -1
- package/src/plugins/providers/opencode-zen.ts +1 -1
- package/src/plugins/providers/perplexity.ts +1 -1
- package/src/plugins/providers/zai.ts +1 -1
- package/src/plugins/registry.ts +9 -9
- package/src/plugins/sandbox-guard.test.ts +1 -1
- package/src/plugins/sandbox-guard.ts +1 -1
- package/src/plugins/sandbox.ts +1 -1
- package/src/plugins/themes/catppuccin-latte.ts +1 -1
- package/src/plugins/themes/catppuccin-mocha.ts +1 -1
- package/src/plugins/themes/claude-code.ts +1 -1
- package/src/plugins/themes/dracula.ts +1 -1
- package/src/plugins/themes/github-light.ts +1 -1
- package/src/plugins/themes/gruvbox-dark.ts +1 -1
- package/src/plugins/themes/gruvbox-light.ts +1 -1
- package/src/plugins/themes/kanagawa.ts +1 -1
- package/src/plugins/themes/nord.ts +1 -1
- package/src/plugins/themes/one-dark.ts +1 -1
- package/src/plugins/themes/opencode.ts +1 -1
- package/src/plugins/themes/rose-pine-dawn.ts +1 -1
- package/src/plugins/themes/rose-pine.ts +1 -1
- package/src/plugins/themes/solarized-light.ts +1 -1
- package/src/plugins/themes/tokyo-night.ts +1 -1
- package/src/plugins/update-checker.ts +2 -2
- package/src/pricing/estimator.test.ts +1 -1
- package/src/pricing/estimator.ts +1 -1
- package/src/pricing/fallback.ts +1 -1
- package/src/pricing/index.ts +1 -1
- package/src/pricing/models-dev.ts +1 -1
- package/src/storage/index.ts +6 -0
- package/src/storage/migrations/index.ts +17 -0
- package/src/storage/repos/pluginStorage.ts +35 -0
- package/src/tui/App.tsx +1 -1
- package/src/tui/components/ProviderCard.tsx +1 -1
- package/src/tui/components/ProviderDetailPanel.tsx +1 -1
- package/src/tui/components/SessionDetailsDrawer.tsx +10 -0
- package/src/tui/components/SessionsTable.tsx +9 -2
- package/src/tui/components/SettingsModal.tsx +1 -1
- package/src/tui/components/ThemePicker.tsx +1 -1
- package/src/tui/contexts/AgentSessionContext.tsx +1 -1
- package/src/tui/contexts/PluginContext.tsx +8 -4
- package/src/tui/contexts/RealTimeActivityContext.tsx +33 -20
- package/src/tui/contexts/ThemeContext.tsx +3 -3
- package/src/tui/hooks/useSessionEnrichedProviders.ts +1 -1
- package/src/tui/views/SettingsView.tsx +1 -1
- package/src/version.ts +1 -1
- package/src/plugins/types/agent.ts +0 -108
- package/src/plugins/types/base.ts +0 -278
- package/src/plugins/types/index.ts +0 -19
- package/src/plugins/types/notification.ts +0 -51
- package/src/plugins/types/provider.ts +0 -237
- package/src/plugins/types/theme.ts +0 -78
- 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
|
-
}
|