statusbar-quick-actions 0.0.10

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/src/types.ts ADDED
@@ -0,0 +1,368 @@
1
+ /**
2
+ * TypeScript type definitions for StatusBar Quick Actions Extension
3
+ */
4
+
5
+ import * as vscode from "vscode";
6
+
7
+ /**
8
+ * Button command configuration
9
+ */
10
+ export interface ButtonCommand {
11
+ type:
12
+ | "npm"
13
+ | "yarn"
14
+ | "pnpm"
15
+ | "bun"
16
+ | "shell"
17
+ | "github"
18
+ | "vscode"
19
+ | "task"
20
+ | "bunx"
21
+ | "npx"
22
+ | "pnpx"
23
+ | "detect";
24
+ script?: string;
25
+ command?: string;
26
+ args?: string[];
27
+ }
28
+
29
+ /**
30
+ * Icon configuration
31
+ */
32
+ export interface IconConfig {
33
+ id: string;
34
+ animation?: "spin" | "pulse" | null;
35
+ library?: "vscode" | "material";
36
+ variant?: "outlined" | "filled" | "rounded" | "sharp" | "two-tone";
37
+ size?: "small" | "medium" | "large";
38
+ }
39
+
40
+ /**
41
+ * Button colors
42
+ */
43
+ export interface ButtonColors {
44
+ foreground?: string;
45
+ background?: string;
46
+ }
47
+
48
+ /**
49
+ * Execution behavior configuration
50
+ */
51
+ export interface ExecutionConfig {
52
+ foreground?: boolean;
53
+ showProgress?: boolean;
54
+ timeout?: number;
55
+ notifications?: {
56
+ showSuccess?: boolean;
57
+ showError?: boolean;
58
+ showOutput?: boolean;
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Visibility condition
64
+ */
65
+ export interface VisibilityCondition {
66
+ type: "fileType" | "fileExists" | "gitStatus" | "workspaceFolder";
67
+ patterns?: string[];
68
+ path?: string;
69
+ status?: "repository" | "clean" | "dirty" | "ahead" | "behind";
70
+ folders?: string[];
71
+ invert?: boolean;
72
+ }
73
+
74
+ /**
75
+ * Visibility configuration
76
+ */
77
+ export interface VisibilityConfig {
78
+ conditions: VisibilityCondition[];
79
+ debounceMs?: number;
80
+ }
81
+
82
+ /**
83
+ * History tracking configuration
84
+ */
85
+ export interface HistoryConfig {
86
+ enabled?: boolean;
87
+ maxEntries?: number;
88
+ }
89
+
90
+ /**
91
+ * Output panel configuration
92
+ */
93
+ export interface OutputPanelConfig {
94
+ enabled: boolean;
95
+ mode: "per-button" | "shared";
96
+ format: "raw" | "formatted" | "ansi";
97
+ clearOnRun: boolean;
98
+ showTimestamps: boolean;
99
+ preserveHistory: boolean;
100
+ maxLines: number;
101
+ }
102
+
103
+ /**
104
+ * Performance configuration
105
+ */
106
+ export interface PerformanceConfig {
107
+ visibilityDebounceMs: number;
108
+ enableVirtualization: boolean;
109
+ cacheResults: boolean;
110
+ }
111
+
112
+ /**
113
+ * Theme color configuration
114
+ */
115
+ export interface ThemeColorConfig {
116
+ foreground: string;
117
+ background: string;
118
+ }
119
+
120
+ /**
121
+ * Theme configuration
122
+ */
123
+ export interface ThemeConfig {
124
+ mode: "auto" | "dark" | "light" | "highContrast";
125
+ dark: {
126
+ button: ThemeColorConfig;
127
+ executing: ThemeColorConfig;
128
+ error: ThemeColorConfig;
129
+ };
130
+ light: {
131
+ button: ThemeColorConfig;
132
+ executing: ThemeColorConfig;
133
+ error: ThemeColorConfig;
134
+ };
135
+ highContrast: {
136
+ button: ThemeColorConfig;
137
+ executing: ThemeColorConfig;
138
+ error: ThemeColorConfig;
139
+ };
140
+ }
141
+
142
+ /**
143
+ * Notification configuration
144
+ */
145
+ export interface NotificationConfig {
146
+ showSuccess: boolean;
147
+ showError: boolean;
148
+ showProgress: boolean;
149
+ position: "top-left" | "top-right" | "bottom-left" | "bottom-right";
150
+ duration: number;
151
+ includeOutput: boolean;
152
+ }
153
+
154
+ /**
155
+ * Button state interface
156
+ */
157
+ export interface ButtonState {
158
+ item: vscode.StatusBarItem;
159
+ config: StatusBarButtonConfig;
160
+ isExecuting: boolean;
161
+ lastResult?: ExecutionResult;
162
+ history: ExecutionResult[];
163
+ accessibility: {
164
+ role: string;
165
+ ariaLabel: string;
166
+ focusOrder: number;
167
+ };
168
+ }
169
+
170
+ /**
171
+ * StatusBar button configuration
172
+ */
173
+ export interface StatusBarButtonConfig {
174
+ id: string;
175
+ text: string;
176
+ tooltip?: string;
177
+ icon?: IconConfig;
178
+ command: ButtonCommand;
179
+ enabled?: boolean;
180
+ alignment?: "left" | "right";
181
+ priority?: number;
182
+ colors?: ButtonColors;
183
+ execution?: ExecutionConfig;
184
+ visibility?: VisibilityConfig;
185
+ workingDirectory?: string;
186
+ environment?: Record<string, string>;
187
+ history?: HistoryConfig;
188
+ dynamicLabel?: DynamicLabelField; // Dynamic label configuration
189
+ }
190
+
191
+ /**
192
+ * Extension configuration
193
+ */
194
+ export interface ExtensionConfig {
195
+ buttons: StatusBarButtonConfig[];
196
+ theme?: ThemeConfig;
197
+ notifications?: NotificationConfig;
198
+ history: boolean;
199
+ autoDetect: boolean;
200
+ settings?: {
201
+ debug?: boolean;
202
+ accessibility?: {
203
+ keyboardNavigation?: boolean;
204
+ highContrast?: boolean;
205
+ };
206
+ output?: OutputPanelConfig;
207
+ performance?: PerformanceConfig;
208
+ icons?: {
209
+ library: "vscode" | "material";
210
+ defaultVariant: string;
211
+ defaultSize: string;
212
+ };
213
+ };
214
+ }
215
+
216
+ /**
217
+ * Command execution result
218
+ */
219
+ export interface ExecutionResult {
220
+ code: number;
221
+ stdout: string;
222
+ stderr: string;
223
+ duration: number;
224
+ timestamp: Date;
225
+ command: string;
226
+ }
227
+
228
+ /**
229
+ * Command history entry
230
+ */
231
+ export interface CommandHistoryEntry {
232
+ id: string;
233
+ buttonId: string;
234
+ result: ExecutionResult;
235
+ command: string;
236
+ }
237
+
238
+ /**
239
+ * Execution options
240
+ */
241
+ export interface ExecutionOptions {
242
+ workingDirectory?: string;
243
+ environment?: Record<string, string>;
244
+ timeout?: number;
245
+ streaming?: {
246
+ enabled: boolean;
247
+ onStdout?: (data: string) => void;
248
+ onStderr?: (data: string) => void;
249
+ onProgress?: (percent: number) => void;
250
+ };
251
+ }
252
+
253
+ /**
254
+ * Visibility context
255
+ */
256
+ export interface VisibilityContext {
257
+ activeFile?: vscode.Uri;
258
+ activeFileName?: string;
259
+ activeFileExtension?: string;
260
+ workspaceFolders?: vscode.WorkspaceFolder[];
261
+ gitStatus?: {
262
+ repository: boolean;
263
+ clean: boolean;
264
+ ahead: boolean;
265
+ behind: boolean;
266
+ };
267
+ }
268
+
269
+ /**
270
+ * Notification types
271
+ */
272
+ export type NotificationType =
273
+ | "success"
274
+ | "error"
275
+ | "warning"
276
+ | "info"
277
+ | "progress";
278
+
279
+ /**
280
+ * Progress notification data
281
+ */
282
+ export interface ProgressNotification {
283
+ increment?: number;
284
+ message?: string;
285
+ }
286
+
287
+ /**
288
+ * Configuration validation result
289
+ */
290
+ export interface ValidationResult {
291
+ isValid: boolean;
292
+ errors: string[];
293
+ warnings: string[];
294
+ }
295
+
296
+ /**
297
+ * Menu category for nested settings
298
+ */
299
+ export interface MenuCategory {
300
+ id: string;
301
+ label: string;
302
+ icon: string;
303
+ description: string;
304
+ items: MenuCategoryItem[];
305
+ }
306
+
307
+ /**
308
+ * Menu category item
309
+ */
310
+ export interface MenuCategoryItem {
311
+ id: string;
312
+ label: string;
313
+ description?: string;
314
+ action: () => Promise<void>;
315
+ }
316
+
317
+ /**
318
+ * Button event types
319
+ */
320
+ export type ButtonEvent = "click" | "hover" | "focus" | "blur";
321
+
322
+ /**
323
+ * Dynamic label field configuration
324
+ */
325
+ export interface DynamicLabelField {
326
+ type: "time" | "url" | "env" | "git" | "custom";
327
+ format?: string; // For time: date-time format string
328
+ url?: string; // For url: URL to fetch from
329
+ envVar?: string; // For env: environment variable name
330
+ gitInfo?: "branch" | "status" | "remote"; // For git: git information type
331
+ customFunction?: string; // For custom: function name to evaluate
332
+ refreshInterval?: number; // Refresh interval in milliseconds (0 = no auto-refresh)
333
+ fallback?: string; // Fallback value if evaluation fails
334
+ template?: string; // Template string with ${placeholder} syntax
335
+ }
336
+
337
+ /**
338
+ * Preset configuration for button sets
339
+ */
340
+ export interface PresetConfig {
341
+ id: string;
342
+ name: string;
343
+ description?: string;
344
+ buttons: StatusBarButtonConfig[];
345
+ theme?: ThemeConfig;
346
+ metadata?: {
347
+ created: Date;
348
+ modified: Date;
349
+ author?: string;
350
+ tags?: string[];
351
+ };
352
+ }
353
+
354
+ /**
355
+ * Preset application mode
356
+ */
357
+ export type PresetApplicationMode = "replace" | "merge" | "append";
358
+
359
+ /**
360
+ * Dynamic label state
361
+ */
362
+ export interface DynamicLabelState {
363
+ fieldConfig: DynamicLabelField;
364
+ lastValue: string;
365
+ lastUpdated: Date;
366
+ refreshTimer?: NodeJS.Timeout;
367
+ error?: string;
368
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Debounce utility for StatusBar Quick Actions
3
+ */
4
+
5
+ /**
6
+ * Creates a debounced function that delays invoking func until after wait milliseconds
7
+ * have elapsed since the last time the debounced function was invoked
8
+ */
9
+ export function debounce<T extends (...args: unknown[]) => unknown>(
10
+ func: T,
11
+ wait: number,
12
+ ): (...args: Parameters<T>) => void {
13
+ let timeout: NodeJS.Timeout | null = null;
14
+
15
+ return function executedFunction(...args: Parameters<T>) {
16
+ const later = () => {
17
+ timeout = null;
18
+ func(...args);
19
+ };
20
+
21
+ if (timeout) {
22
+ clearTimeout(timeout);
23
+ }
24
+
25
+ timeout = setTimeout(later, wait);
26
+ };
27
+ }
28
+
29
+ /**
30
+ * Manages debounced visibility checks for buttons
31
+ */
32
+ export class DebouncedVisibilityChecker {
33
+ private debouncedChecks: Map<string, (...args: unknown[]) => void>;
34
+ private defaultDelay: number;
35
+
36
+ constructor(defaultDelay: number) {
37
+ this.debouncedChecks = new Map();
38
+ this.defaultDelay = defaultDelay;
39
+ }
40
+
41
+ /**
42
+ * Get or create a debounced check function for a button
43
+ */
44
+ public getDebouncedCheck(
45
+ buttonId: string,
46
+ checkFn: () => void,
47
+ customDelay?: number,
48
+ ): () => void {
49
+ const key = buttonId;
50
+ if (!this.debouncedChecks.has(key)) {
51
+ const delay = customDelay ?? this.defaultDelay;
52
+ this.debouncedChecks.set(key, debounce(checkFn, delay));
53
+ }
54
+ return this.debouncedChecks.get(key)!;
55
+ }
56
+
57
+ /**
58
+ * Remove a debounced check function for a button
59
+ */
60
+ public removeDebouncedCheck(buttonId: string): void {
61
+ this.debouncedChecks.delete(buttonId);
62
+ }
63
+
64
+ /**
65
+ * Clear all debounced check functions
66
+ */
67
+ public clear(): void {
68
+ this.debouncedChecks.clear();
69
+ }
70
+
71
+ /**
72
+ * Dispose of all resources
73
+ */
74
+ public dispose(): void {
75
+ this.clear();
76
+ }
77
+
78
+ /**
79
+ * Get the number of registered debounced checks
80
+ */
81
+ public size(): number {
82
+ return this.debouncedChecks.size;
83
+ }
84
+
85
+ /**
86
+ * Check if a debounced check exists for a button
87
+ */
88
+ public has(buttonId: string): boolean {
89
+ return this.debouncedChecks.has(buttonId);
90
+ }
91
+ }