driftdetect-vscode 0.8.2

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 (309) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test.log +138 -0
  3. package/.vscode/launch.json +17 -0
  4. package/.vscode/tasks.json +15 -0
  5. package/LICENSE +121 -0
  6. package/dist/activation/activation-controller.d.ts +61 -0
  7. package/dist/activation/activation-controller.d.ts.map +1 -0
  8. package/dist/activation/activation-controller.js +235 -0
  9. package/dist/activation/activation-controller.js.map +1 -0
  10. package/dist/activation/activation-phases.d.ts +28 -0
  11. package/dist/activation/activation-phases.d.ts.map +1 -0
  12. package/dist/activation/activation-phases.js +80 -0
  13. package/dist/activation/activation-phases.js.map +1 -0
  14. package/dist/activation/index.d.ts +6 -0
  15. package/dist/activation/index.d.ts.map +1 -0
  16. package/dist/activation/index.js +6 -0
  17. package/dist/activation/index.js.map +1 -0
  18. package/dist/client/connection-config.d.ts +50 -0
  19. package/dist/client/connection-config.d.ts.map +1 -0
  20. package/dist/client/connection-config.js +56 -0
  21. package/dist/client/connection-config.js.map +1 -0
  22. package/dist/client/connection-manager.d.ts +70 -0
  23. package/dist/client/connection-manager.d.ts.map +1 -0
  24. package/dist/client/connection-manager.js +214 -0
  25. package/dist/client/connection-manager.js.map +1 -0
  26. package/dist/client/index.d.ts +8 -0
  27. package/dist/client/index.d.ts.map +1 -0
  28. package/dist/client/index.js +8 -0
  29. package/dist/client/index.js.map +1 -0
  30. package/dist/client/language-client-factory.d.ts +29 -0
  31. package/dist/client/language-client-factory.d.ts.map +1 -0
  32. package/dist/client/language-client-factory.js +76 -0
  33. package/dist/client/language-client-factory.js.map +1 -0
  34. package/dist/client/request-middleware.d.ts +38 -0
  35. package/dist/client/request-middleware.d.ts.map +1 -0
  36. package/dist/client/request-middleware.js +85 -0
  37. package/dist/client/request-middleware.js.map +1 -0
  38. package/dist/commands/command-definitions.d.ts +53 -0
  39. package/dist/commands/command-definitions.d.ts.map +1 -0
  40. package/dist/commands/command-definitions.js +212 -0
  41. package/dist/commands/command-definitions.js.map +1 -0
  42. package/dist/commands/command-router.d.ts +80 -0
  43. package/dist/commands/command-router.d.ts.map +1 -0
  44. package/dist/commands/command-router.js +127 -0
  45. package/dist/commands/command-router.js.map +1 -0
  46. package/dist/commands/handlers/connection-handlers.d.ts +14 -0
  47. package/dist/commands/handlers/connection-handlers.d.ts.map +1 -0
  48. package/dist/commands/handlers/connection-handlers.js +57 -0
  49. package/dist/commands/handlers/connection-handlers.js.map +1 -0
  50. package/dist/commands/handlers/constants-handlers.d.ts +11 -0
  51. package/dist/commands/handlers/constants-handlers.d.ts.map +1 -0
  52. package/dist/commands/handlers/constants-handlers.js +84 -0
  53. package/dist/commands/handlers/constants-handlers.js.map +1 -0
  54. package/dist/commands/handlers/index.d.ts +10 -0
  55. package/dist/commands/handlers/index.d.ts.map +1 -0
  56. package/dist/commands/handlers/index.js +10 -0
  57. package/dist/commands/handlers/index.js.map +1 -0
  58. package/dist/commands/handlers/pattern-handlers.d.ts +13 -0
  59. package/dist/commands/handlers/pattern-handlers.d.ts.map +1 -0
  60. package/dist/commands/handlers/pattern-handlers.js +127 -0
  61. package/dist/commands/handlers/pattern-handlers.js.map +1 -0
  62. package/dist/commands/handlers/scan-handlers.d.ts +15 -0
  63. package/dist/commands/handlers/scan-handlers.d.ts.map +1 -0
  64. package/dist/commands/handlers/scan-handlers.js +74 -0
  65. package/dist/commands/handlers/scan-handlers.js.map +1 -0
  66. package/dist/commands/handlers/ui-handlers.d.ts +12 -0
  67. package/dist/commands/handlers/ui-handlers.d.ts.map +1 -0
  68. package/dist/commands/handlers/ui-handlers.js +74 -0
  69. package/dist/commands/handlers/ui-handlers.js.map +1 -0
  70. package/dist/commands/handlers/violation-handlers.d.ts +13 -0
  71. package/dist/commands/handlers/violation-handlers.d.ts.map +1 -0
  72. package/dist/commands/handlers/violation-handlers.js +76 -0
  73. package/dist/commands/handlers/violation-handlers.js.map +1 -0
  74. package/dist/commands/index.d.ts +7 -0
  75. package/dist/commands/index.d.ts.map +1 -0
  76. package/dist/commands/index.js +7 -0
  77. package/dist/commands/index.js.map +1 -0
  78. package/dist/commands/middleware/connection-check-middleware.d.ts +12 -0
  79. package/dist/commands/middleware/connection-check-middleware.d.ts.map +1 -0
  80. package/dist/commands/middleware/connection-check-middleware.js +34 -0
  81. package/dist/commands/middleware/connection-check-middleware.js.map +1 -0
  82. package/dist/commands/middleware/index.d.ts +7 -0
  83. package/dist/commands/middleware/index.d.ts.map +1 -0
  84. package/dist/commands/middleware/index.js +7 -0
  85. package/dist/commands/middleware/index.js.map +1 -0
  86. package/dist/commands/middleware/logging-middleware.d.ts +12 -0
  87. package/dist/commands/middleware/logging-middleware.d.ts.map +1 -0
  88. package/dist/commands/middleware/logging-middleware.js +24 -0
  89. package/dist/commands/middleware/logging-middleware.js.map +1 -0
  90. package/dist/commands/middleware/telemetry-middleware.d.ts +22 -0
  91. package/dist/commands/middleware/telemetry-middleware.d.ts.map +1 -0
  92. package/dist/commands/middleware/telemetry-middleware.js +30 -0
  93. package/dist/commands/middleware/telemetry-middleware.js.map +1 -0
  94. package/dist/config/config-manager.d.ts +53 -0
  95. package/dist/config/config-manager.d.ts.map +1 -0
  96. package/dist/config/config-manager.js +178 -0
  97. package/dist/config/config-manager.js.map +1 -0
  98. package/dist/config/defaults.d.ts +11 -0
  99. package/dist/config/defaults.d.ts.map +1 -0
  100. package/dist/config/defaults.js +43 -0
  101. package/dist/config/defaults.js.map +1 -0
  102. package/dist/config/index.d.ts +7 -0
  103. package/dist/config/index.d.ts.map +1 -0
  104. package/dist/config/index.js +7 -0
  105. package/dist/config/index.js.map +1 -0
  106. package/dist/config/validator.d.ts +22 -0
  107. package/dist/config/validator.d.ts.map +1 -0
  108. package/dist/config/validator.js +93 -0
  109. package/dist/config/validator.js.map +1 -0
  110. package/dist/extension.d.ts +32 -0
  111. package/dist/extension.d.ts.map +1 -0
  112. package/dist/extension.js +50 -0
  113. package/dist/extension.js.map +1 -0
  114. package/dist/infrastructure/disposable-manager.d.ts +43 -0
  115. package/dist/infrastructure/disposable-manager.d.ts.map +1 -0
  116. package/dist/infrastructure/disposable-manager.js +75 -0
  117. package/dist/infrastructure/disposable-manager.js.map +1 -0
  118. package/dist/infrastructure/event-bus.d.ts +85 -0
  119. package/dist/infrastructure/event-bus.d.ts.map +1 -0
  120. package/dist/infrastructure/event-bus.js +74 -0
  121. package/dist/infrastructure/event-bus.js.map +1 -0
  122. package/dist/infrastructure/index.d.ts +10 -0
  123. package/dist/infrastructure/index.d.ts.map +1 -0
  124. package/dist/infrastructure/index.js +10 -0
  125. package/dist/infrastructure/index.js.map +1 -0
  126. package/dist/infrastructure/logger.d.ts +37 -0
  127. package/dist/infrastructure/logger.d.ts.map +1 -0
  128. package/dist/infrastructure/logger.js +86 -0
  129. package/dist/infrastructure/logger.js.map +1 -0
  130. package/dist/infrastructure/service-container.d.ts +68 -0
  131. package/dist/infrastructure/service-container.d.ts.map +1 -0
  132. package/dist/infrastructure/service-container.js +94 -0
  133. package/dist/infrastructure/service-container.js.map +1 -0
  134. package/dist/state/index.d.ts +7 -0
  135. package/dist/state/index.d.ts.map +1 -0
  136. package/dist/state/index.js +7 -0
  137. package/dist/state/index.js.map +1 -0
  138. package/dist/state/initial-state.d.ts +11 -0
  139. package/dist/state/initial-state.d.ts.map +1 -0
  140. package/dist/state/initial-state.js +58 -0
  141. package/dist/state/initial-state.js.map +1 -0
  142. package/dist/state/selectors.d.ts +41 -0
  143. package/dist/state/selectors.d.ts.map +1 -0
  144. package/dist/state/selectors.js +61 -0
  145. package/dist/state/selectors.js.map +1 -0
  146. package/dist/state/state-manager.d.ts +54 -0
  147. package/dist/state/state-manager.d.ts.map +1 -0
  148. package/dist/state/state-manager.js +166 -0
  149. package/dist/state/state-manager.js.map +1 -0
  150. package/dist/types/config-types.d.ts +69 -0
  151. package/dist/types/config-types.d.ts.map +1 -0
  152. package/dist/types/config-types.js +5 -0
  153. package/dist/types/config-types.js.map +1 -0
  154. package/dist/types/extension-types.d.ts +45 -0
  155. package/dist/types/extension-types.d.ts.map +1 -0
  156. package/dist/types/extension-types.js +5 -0
  157. package/dist/types/extension-types.js.map +1 -0
  158. package/dist/types/index.d.ts +12 -0
  159. package/dist/types/index.d.ts.map +1 -0
  160. package/dist/types/index.js +12 -0
  161. package/dist/types/index.js.map +1 -0
  162. package/dist/types/lsp-types.d.ts +70 -0
  163. package/dist/types/lsp-types.d.ts.map +1 -0
  164. package/dist/types/lsp-types.js +5 -0
  165. package/dist/types/lsp-types.js.map +1 -0
  166. package/dist/types/state-types.d.ts +82 -0
  167. package/dist/types/state-types.d.ts.map +1 -0
  168. package/dist/types/state-types.js +5 -0
  169. package/dist/types/state-types.js.map +1 -0
  170. package/dist/types/vscode-types.d.ts +36 -0
  171. package/dist/types/vscode-types.d.ts.map +1 -0
  172. package/dist/types/vscode-types.js +7 -0
  173. package/dist/types/vscode-types.js.map +1 -0
  174. package/dist/ui/decorations/decoration-controller.d.ts +45 -0
  175. package/dist/ui/decorations/decoration-controller.d.ts.map +1 -0
  176. package/dist/ui/decorations/decoration-controller.js +198 -0
  177. package/dist/ui/decorations/decoration-controller.js.map +1 -0
  178. package/dist/ui/decorations/decoration-types.d.ts +28 -0
  179. package/dist/ui/decorations/decoration-types.d.ts.map +1 -0
  180. package/dist/ui/decorations/decoration-types.js +98 -0
  181. package/dist/ui/decorations/decoration-types.js.map +1 -0
  182. package/dist/ui/decorations/index.d.ts +7 -0
  183. package/dist/ui/decorations/index.d.ts.map +1 -0
  184. package/dist/ui/decorations/index.js +6 -0
  185. package/dist/ui/decorations/index.js.map +1 -0
  186. package/dist/ui/index.d.ts +7 -0
  187. package/dist/ui/index.d.ts.map +1 -0
  188. package/dist/ui/index.js +7 -0
  189. package/dist/ui/index.js.map +1 -0
  190. package/dist/ui/notifications/index.d.ts +5 -0
  191. package/dist/ui/notifications/index.d.ts.map +1 -0
  192. package/dist/ui/notifications/index.js +5 -0
  193. package/dist/ui/notifications/index.js.map +1 -0
  194. package/dist/ui/notifications/notification-service.d.ts +66 -0
  195. package/dist/ui/notifications/notification-service.d.ts.map +1 -0
  196. package/dist/ui/notifications/notification-service.js +103 -0
  197. package/dist/ui/notifications/notification-service.js.map +1 -0
  198. package/dist/ui/status-bar/index.d.ts +6 -0
  199. package/dist/ui/status-bar/index.d.ts.map +1 -0
  200. package/dist/ui/status-bar/index.js +6 -0
  201. package/dist/ui/status-bar/index.js.map +1 -0
  202. package/dist/ui/status-bar/status-bar-controller.d.ts +37 -0
  203. package/dist/ui/status-bar/status-bar-controller.d.ts.map +1 -0
  204. package/dist/ui/status-bar/status-bar-controller.js +111 -0
  205. package/dist/ui/status-bar/status-bar-controller.js.map +1 -0
  206. package/dist/ui/status-bar/status-bar-modes.d.ts +26 -0
  207. package/dist/ui/status-bar/status-bar-modes.d.ts.map +1 -0
  208. package/dist/ui/status-bar/status-bar-modes.js +97 -0
  209. package/dist/ui/status-bar/status-bar-modes.js.map +1 -0
  210. package/dist/views/base-tree-provider.d.ts +74 -0
  211. package/dist/views/base-tree-provider.d.ts.map +1 -0
  212. package/dist/views/base-tree-provider.js +95 -0
  213. package/dist/views/base-tree-provider.js.map +1 -0
  214. package/dist/views/constants-tree-provider.d.ts +112 -0
  215. package/dist/views/constants-tree-provider.d.ts.map +1 -0
  216. package/dist/views/constants-tree-provider.js +344 -0
  217. package/dist/views/constants-tree-provider.js.map +1 -0
  218. package/dist/views/files-tree-provider.d.ts +37 -0
  219. package/dist/views/files-tree-provider.d.ts.map +1 -0
  220. package/dist/views/files-tree-provider.js +98 -0
  221. package/dist/views/files-tree-provider.js.map +1 -0
  222. package/dist/views/index.d.ts +10 -0
  223. package/dist/views/index.d.ts.map +1 -0
  224. package/dist/views/index.js +10 -0
  225. package/dist/views/index.js.map +1 -0
  226. package/dist/views/patterns-tree-provider.d.ts +39 -0
  227. package/dist/views/patterns-tree-provider.d.ts.map +1 -0
  228. package/dist/views/patterns-tree-provider.js +139 -0
  229. package/dist/views/patterns-tree-provider.js.map +1 -0
  230. package/dist/views/violations-tree-provider.d.ts +46 -0
  231. package/dist/views/violations-tree-provider.d.ts.map +1 -0
  232. package/dist/views/violations-tree-provider.js +158 -0
  233. package/dist/views/violations-tree-provider.js.map +1 -0
  234. package/dist/webview/index.d.ts +7 -0
  235. package/dist/webview/index.d.ts.map +1 -0
  236. package/dist/webview/index.js +7 -0
  237. package/dist/webview/index.js.map +1 -0
  238. package/dist/webview/webview-manager.d.ts +57 -0
  239. package/dist/webview/webview-manager.d.ts.map +1 -0
  240. package/dist/webview/webview-manager.js +167 -0
  241. package/dist/webview/webview-manager.js.map +1 -0
  242. package/package.json +405 -0
  243. package/resources/drift-icon.png +0 -0
  244. package/resources/drift-icon.svg +5 -0
  245. package/resources/icons/error.svg +4 -0
  246. package/resources/icons/info.svg +4 -0
  247. package/resources/icons/lightbulb.svg +4 -0
  248. package/resources/icons/warning.svg +4 -0
  249. package/src/activation/activation-controller.ts +320 -0
  250. package/src/activation/activation-phases.ts +96 -0
  251. package/src/activation/index.ts +6 -0
  252. package/src/client/connection-config.ts +64 -0
  253. package/src/client/connection-manager.ts +263 -0
  254. package/src/client/index.ts +8 -0
  255. package/src/client/language-client-factory.ts +111 -0
  256. package/src/client/request-middleware.ts +117 -0
  257. package/src/commands/command-definitions.ts +243 -0
  258. package/src/commands/command-router.ts +194 -0
  259. package/src/commands/handlers/connection-handlers.ts +74 -0
  260. package/src/commands/handlers/constants-handlers.ts +99 -0
  261. package/src/commands/handlers/index.ts +10 -0
  262. package/src/commands/handlers/pattern-handlers.ts +167 -0
  263. package/src/commands/handlers/scan-handlers.ts +107 -0
  264. package/src/commands/handlers/ui-handlers.ts +88 -0
  265. package/src/commands/handlers/violation-handlers.ts +97 -0
  266. package/src/commands/index.ts +7 -0
  267. package/src/commands/middleware/connection-check-middleware.ts +46 -0
  268. package/src/commands/middleware/index.ts +7 -0
  269. package/src/commands/middleware/logging-middleware.ts +28 -0
  270. package/src/commands/middleware/telemetry-middleware.ts +46 -0
  271. package/src/config/config-manager.ts +213 -0
  272. package/src/config/defaults.ts +45 -0
  273. package/src/config/index.ts +7 -0
  274. package/src/config/validator.ts +118 -0
  275. package/src/extension.ts +57 -0
  276. package/src/infrastructure/disposable-manager.ts +87 -0
  277. package/src/infrastructure/event-bus.ts +121 -0
  278. package/src/infrastructure/index.ts +10 -0
  279. package/src/infrastructure/logger.ts +108 -0
  280. package/src/infrastructure/service-container.ts +123 -0
  281. package/src/state/index.ts +7 -0
  282. package/src/state/initial-state.ts +60 -0
  283. package/src/state/selectors.ts +126 -0
  284. package/src/state/state-manager.ts +198 -0
  285. package/src/types/config-types.ts +77 -0
  286. package/src/types/extension-types.ts +58 -0
  287. package/src/types/index.ts +12 -0
  288. package/src/types/lsp-types.ts +77 -0
  289. package/src/types/state-types.ts +92 -0
  290. package/src/types/vscode-types.ts +40 -0
  291. package/src/ui/decorations/decoration-controller.ts +252 -0
  292. package/src/ui/decorations/decoration-types.ts +129 -0
  293. package/src/ui/decorations/index.ts +7 -0
  294. package/src/ui/index.ts +7 -0
  295. package/src/ui/notifications/index.ts +5 -0
  296. package/src/ui/notifications/notification-service.ts +167 -0
  297. package/src/ui/status-bar/index.ts +6 -0
  298. package/src/ui/status-bar/status-bar-controller.ts +135 -0
  299. package/src/ui/status-bar/status-bar-modes.ts +119 -0
  300. package/src/views/base-tree-provider.ts +127 -0
  301. package/src/views/constants-tree-provider.ts +525 -0
  302. package/src/views/files-tree-provider.ts +140 -0
  303. package/src/views/index.ts +10 -0
  304. package/src/views/patterns-tree-provider.ts +179 -0
  305. package/src/views/violations-tree-provider.ts +210 -0
  306. package/src/webview/index.ts +7 -0
  307. package/src/webview/webview-manager.ts +238 -0
  308. package/tsconfig.json +22 -0
  309. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,167 @@
1
+ /**
2
+ * NotificationService - User notification management
3
+ *
4
+ * Single responsibility: Display notifications to users.
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+
9
+ import type { Logger } from '../../infrastructure/index.js';
10
+
11
+ /**
12
+ * Notification action
13
+ */
14
+ export interface NotificationAction {
15
+ title: string;
16
+ command?: string;
17
+ args?: unknown[];
18
+ callback?: () => void | Promise<void>;
19
+ }
20
+
21
+ /**
22
+ * Notification options
23
+ */
24
+ export interface NotificationOptions {
25
+ modal?: boolean;
26
+ detail?: string;
27
+ }
28
+
29
+ /**
30
+ * Notification service for user messages
31
+ */
32
+ export class NotificationService {
33
+ constructor(private readonly logger: Logger) {}
34
+
35
+ /**
36
+ * Show an information message
37
+ */
38
+ async info(
39
+ message: string,
40
+ actions: NotificationAction[] = [],
41
+ options: NotificationOptions = {}
42
+ ): Promise<string | undefined> {
43
+ return this.show('info', message, actions, options);
44
+ }
45
+
46
+ /**
47
+ * Show a warning message
48
+ */
49
+ async warning(
50
+ message: string,
51
+ actions: NotificationAction[] = [],
52
+ options: NotificationOptions = {}
53
+ ): Promise<string | undefined> {
54
+ return this.show('warning', message, actions, options);
55
+ }
56
+
57
+ /**
58
+ * Show an error message
59
+ */
60
+ async error(
61
+ message: string,
62
+ actions: NotificationAction[] = [],
63
+ options: NotificationOptions = {}
64
+ ): Promise<string | undefined> {
65
+ this.logger.error(message);
66
+ return this.show('error', message, actions, options);
67
+ }
68
+
69
+ /**
70
+ * Show a progress notification
71
+ */
72
+ async withProgress<T>(
73
+ title: string,
74
+ task: (
75
+ progress: vscode.Progress<{ message?: string; increment?: number }>,
76
+ token: vscode.CancellationToken
77
+ ) => Promise<T>,
78
+ options: { cancellable?: boolean; location?: vscode.ProgressLocation } = {}
79
+ ): Promise<T> {
80
+ return vscode.window.withProgress(
81
+ {
82
+ location: options.location ?? vscode.ProgressLocation.Notification,
83
+ title: `Drift: ${title}`,
84
+ cancellable: options.cancellable ?? false,
85
+ },
86
+ task
87
+ );
88
+ }
89
+
90
+ /**
91
+ * Show a quick pick
92
+ */
93
+ async quickPick<T extends vscode.QuickPickItem>(
94
+ items: T[],
95
+ options: vscode.QuickPickOptions = {}
96
+ ): Promise<T | undefined> {
97
+ const pickOptions: vscode.QuickPickOptions = {
98
+ ...options,
99
+ };
100
+ if (options.title) {
101
+ pickOptions.title = `Drift: ${options.title}`;
102
+ }
103
+ return vscode.window.showQuickPick(items, pickOptions);
104
+ }
105
+
106
+ /**
107
+ * Show an input box
108
+ */
109
+ async inputBox(options: vscode.InputBoxOptions = {}): Promise<string | undefined> {
110
+ const inputOptions: vscode.InputBoxOptions = {
111
+ ...options,
112
+ };
113
+ if (options.title) {
114
+ inputOptions.title = `Drift: ${options.title}`;
115
+ }
116
+ return vscode.window.showInputBox(inputOptions);
117
+ }
118
+
119
+ private async show(
120
+ type: 'info' | 'warning' | 'error',
121
+ message: string,
122
+ actions: NotificationAction[],
123
+ options: NotificationOptions
124
+ ): Promise<string | undefined> {
125
+ const actionTitles = actions.map(a => a.title);
126
+
127
+ const showFn = {
128
+ info: vscode.window.showInformationMessage,
129
+ warning: vscode.window.showWarningMessage,
130
+ error: vscode.window.showErrorMessage,
131
+ }[type];
132
+
133
+ const messageOptions: vscode.MessageOptions = {};
134
+ if (options.modal !== undefined) {
135
+ messageOptions.modal = options.modal;
136
+ }
137
+ if (options.detail !== undefined) {
138
+ messageOptions.detail = options.detail;
139
+ }
140
+
141
+ const selected = await showFn(
142
+ `Drift: ${message}`,
143
+ messageOptions,
144
+ ...actionTitles
145
+ );
146
+
147
+ if (selected) {
148
+ const action = actions.find(a => a.title === selected);
149
+ if (action) {
150
+ if (action.callback) {
151
+ await action.callback();
152
+ } else if (action.command) {
153
+ await vscode.commands.executeCommand(action.command, ...(action.args || []));
154
+ }
155
+ }
156
+ }
157
+
158
+ return selected;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Factory function for creating notification service
164
+ */
165
+ export function createNotificationService(logger: Logger): NotificationService {
166
+ return new NotificationService(logger);
167
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Status bar module exports
3
+ */
4
+
5
+ export { StatusBarController, createStatusBar } from './status-bar-controller.js';
6
+ export { StatusBarModes, getStatusBarMode } from './status-bar-modes.js';
@@ -0,0 +1,135 @@
1
+ /**
2
+ * StatusBarController - Status bar management
3
+ *
4
+ * Single responsibility: Display extension status in VS Code status bar.
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+
9
+ import { getStatusBarMode } from './status-bar-modes.js';
10
+ import { selectStatusBarData } from '../../state/selectors.js';
11
+
12
+ import type { StateManager } from '../../state/index.js';
13
+
14
+ /**
15
+ * Status bar controller
16
+ */
17
+ export class StatusBarController implements vscode.Disposable {
18
+ private readonly item: vscode.StatusBarItem;
19
+ private readonly disposables: vscode.Disposable[] = [];
20
+
21
+ constructor(private readonly stateManager: StateManager) {
22
+ this.item = vscode.window.createStatusBarItem(
23
+ vscode.StatusBarAlignment.Right,
24
+ 100
25
+ );
26
+
27
+ this.setupSubscriptions();
28
+ this.updateDisplay();
29
+ this.item.show();
30
+ }
31
+
32
+ /**
33
+ * Show the status bar item
34
+ */
35
+ show(): void {
36
+ this.item.show();
37
+ }
38
+
39
+ /**
40
+ * Hide the status bar item
41
+ */
42
+ hide(): void {
43
+ this.item.hide();
44
+ }
45
+
46
+ /**
47
+ * Dispose resources
48
+ */
49
+ dispose(): void {
50
+ this.item.dispose();
51
+ for (const d of this.disposables) {
52
+ d.dispose();
53
+ }
54
+ }
55
+
56
+ private setupSubscriptions(): void {
57
+ // Subscribe to relevant state changes
58
+ this.disposables.push(
59
+ this.stateManager.subscribe(selectStatusBarData, () => {
60
+ this.updateDisplay();
61
+ })
62
+ );
63
+ }
64
+
65
+ private updateDisplay(): void {
66
+ const state = this.stateManager.getState();
67
+ const { status, violations, scanning } = {
68
+ status: state.connection.status,
69
+ violations: state.violations.total,
70
+ scanning: state.workspace.scanning,
71
+ };
72
+
73
+ const mode = getStatusBarMode(status, violations, scanning);
74
+
75
+ this.item.text = `${mode.icon} ${mode.text}`;
76
+ this.item.tooltip = this.buildTooltip(mode.tooltip, state);
77
+ this.item.backgroundColor = mode.backgroundColor;
78
+ this.item.command = mode.command;
79
+ }
80
+
81
+ private buildTooltip(baseTooltip: string, state: ReturnType<StateManager['getState']>): vscode.MarkdownString {
82
+ const md = new vscode.MarkdownString();
83
+ md.isTrusted = true;
84
+ md.supportThemeIcons = true;
85
+
86
+ md.appendMarkdown(`### $(drift-logo) Drift\n\n`);
87
+ md.appendMarkdown(`${baseTooltip}\n\n`);
88
+
89
+ // Add stats if connected
90
+ if (state.connection.status === 'connected') {
91
+ md.appendMarkdown(`---\n\n`);
92
+ md.appendMarkdown(`**Patterns:** ${state.patterns.total}\n\n`);
93
+ md.appendMarkdown(`**Violations:** ${state.violations.total}\n\n`);
94
+
95
+ if (state.violations.total > 0) {
96
+ md.appendMarkdown(`\n`);
97
+ for (const [severity, count] of Object.entries(state.violations.bySeverity)) {
98
+ if (count > 0) {
99
+ const icon = this.getSeverityIcon(severity);
100
+ md.appendMarkdown(`- ${icon} ${severity}: ${count}\n`);
101
+ }
102
+ }
103
+ }
104
+
105
+ md.appendMarkdown(`\n---\n\n`);
106
+ md.appendMarkdown(`[View Violations](command:drift.showViolations) | `);
107
+ md.appendMarkdown(`[View Patterns](command:drift.showPatterns) | `);
108
+ md.appendMarkdown(`[Rescan](command:drift.rescan)\n`);
109
+ }
110
+
111
+ return md;
112
+ }
113
+
114
+ private getSeverityIcon(severity: string): string {
115
+ switch (severity) {
116
+ case 'error':
117
+ return '$(error)';
118
+ case 'warning':
119
+ return '$(warning)';
120
+ case 'info':
121
+ return '$(info)';
122
+ case 'hint':
123
+ return '$(lightbulb)';
124
+ default:
125
+ return '$(circle)';
126
+ }
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Factory function for creating status bar controller
132
+ */
133
+ export function createStatusBar(stateManager: StateManager): StatusBarController {
134
+ return new StatusBarController(stateManager);
135
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Status bar display modes
3
+ *
4
+ * Single responsibility: Define status bar visual states.
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+
9
+ import type { ConnectionState } from '../../types/index.js';
10
+
11
+ /**
12
+ * Status bar mode configuration
13
+ */
14
+ export interface StatusBarMode {
15
+ icon: string;
16
+ text: string;
17
+ tooltip: string;
18
+ backgroundColor?: vscode.ThemeColor;
19
+ command?: string;
20
+ }
21
+
22
+ /**
23
+ * Status bar modes for different states
24
+ */
25
+ export const StatusBarModes: Record<string, StatusBarMode> = {
26
+ disconnected: {
27
+ icon: '$(circle-slash)',
28
+ text: 'Drift: Disconnected',
29
+ tooltip: 'Drift is not connected. Click to reconnect.',
30
+ backgroundColor: new vscode.ThemeColor('statusBarItem.errorBackground'),
31
+ command: 'drift.reconnect',
32
+ },
33
+ connecting: {
34
+ icon: '$(sync~spin)',
35
+ text: 'Drift: Connecting...',
36
+ tooltip: 'Connecting to Drift server...',
37
+ },
38
+ connected: {
39
+ icon: '$(check)',
40
+ text: 'Drift: Ready',
41
+ tooltip: 'Drift is connected and ready.',
42
+ command: 'drift.showStatus',
43
+ },
44
+ reconnecting: {
45
+ icon: '$(sync~spin)',
46
+ text: 'Drift: Reconnecting...',
47
+ tooltip: 'Reconnecting to Drift server...',
48
+ },
49
+ error: {
50
+ icon: '$(error)',
51
+ text: 'Drift: Error',
52
+ tooltip: 'Drift encountered an error. Click for details.',
53
+ backgroundColor: new vscode.ThemeColor('statusBarItem.errorBackground'),
54
+ command: 'drift.showError',
55
+ },
56
+ failed: {
57
+ icon: '$(error)',
58
+ text: 'Drift: Failed',
59
+ tooltip: 'Drift failed to connect. Click to retry.',
60
+ backgroundColor: new vscode.ThemeColor('statusBarItem.errorBackground'),
61
+ command: 'drift.reconnect',
62
+ },
63
+ scanning: {
64
+ icon: '$(sync~spin)',
65
+ text: 'Drift: Scanning...',
66
+ tooltip: 'Scanning workspace for patterns...',
67
+ },
68
+ healthy: {
69
+ icon: '$(pass)',
70
+ text: 'Drift',
71
+ tooltip: 'No violations found.',
72
+ command: 'drift.showStatus',
73
+ },
74
+ warning: {
75
+ icon: '$(warning)',
76
+ text: 'Drift',
77
+ tooltip: 'Violations found. Click to view.',
78
+ backgroundColor: new vscode.ThemeColor('statusBarItem.warningBackground'),
79
+ command: 'drift.showViolations',
80
+ },
81
+ };
82
+
83
+ /**
84
+ * Get status bar mode based on state
85
+ */
86
+ export function getStatusBarMode(
87
+ connectionState: ConnectionState,
88
+ violations: number,
89
+ scanning: boolean
90
+ ): StatusBarMode {
91
+ // Connection states take priority
92
+ if (connectionState !== 'connected') {
93
+ return StatusBarModes[connectionState] ?? StatusBarModes['disconnected']!;
94
+ }
95
+
96
+ // Scanning state
97
+ if (scanning) {
98
+ return StatusBarModes['scanning']!;
99
+ }
100
+
101
+ // Violation-based states
102
+ if (violations > 0) {
103
+ const warningMode = StatusBarModes['warning']!;
104
+ const result: StatusBarMode = {
105
+ icon: warningMode.icon,
106
+ text: `Drift: ${violations}`,
107
+ tooltip: `${violations} violation${violations === 1 ? '' : 's'} found. Click to view.`,
108
+ };
109
+ if (warningMode.backgroundColor) {
110
+ result.backgroundColor = warningMode.backgroundColor;
111
+ }
112
+ if (warningMode.command) {
113
+ result.command = warningMode.command;
114
+ }
115
+ return result;
116
+ }
117
+
118
+ return StatusBarModes['healthy']!;
119
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * BaseTreeProvider - Abstract base for tree view providers
3
+ *
4
+ * Single responsibility: Provide common tree view functionality.
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+
9
+ import type { LanguageClient } from 'vscode-languageclient/node';
10
+
11
+ /**
12
+ * Base tree item with common properties
13
+ */
14
+ export interface BaseTreeItem extends vscode.TreeItem {
15
+ contextValue: string;
16
+ }
17
+
18
+ /**
19
+ * Cache entry with expiry
20
+ */
21
+ interface CacheEntry<T> {
22
+ data: T;
23
+ expiry: number;
24
+ }
25
+
26
+ /**
27
+ * Abstract base class for tree providers
28
+ */
29
+ export abstract class BaseTreeProvider<T extends BaseTreeItem>
30
+ implements vscode.TreeDataProvider<T>, vscode.Disposable
31
+ {
32
+ protected readonly cache = new Map<string, CacheEntry<T[]>>();
33
+ protected readonly disposables: vscode.Disposable[] = [];
34
+ protected readonly cacheTTL = 30000; // 30 seconds
35
+
36
+ protected readonly _onDidChangeTreeData = new vscode.EventEmitter<T | undefined>();
37
+ readonly onDidChangeTreeData = this._onDidChangeTreeData.event;
38
+
39
+ constructor(protected readonly client: LanguageClient | null) {}
40
+
41
+ /**
42
+ * Refresh the tree view
43
+ */
44
+ refresh(item?: T): void {
45
+ if (item) {
46
+ this.invalidateCache(this.getCacheKey(item));
47
+ } else {
48
+ this.invalidateAllCache();
49
+ }
50
+ this._onDidChangeTreeData.fire(item);
51
+ }
52
+
53
+ /**
54
+ * Get tree item representation
55
+ */
56
+ getTreeItem(element: T): vscode.TreeItem {
57
+ return element;
58
+ }
59
+
60
+ /**
61
+ * Get children of an element
62
+ */
63
+ abstract getChildren(element?: T): Promise<T[]>;
64
+
65
+ /**
66
+ * Dispose resources
67
+ */
68
+ dispose(): void {
69
+ this._onDidChangeTreeData.dispose();
70
+ this.cache.clear();
71
+ for (const d of this.disposables) {
72
+ d.dispose();
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Get cache key for an item
78
+ */
79
+ protected getCacheKey(item?: T): string {
80
+ return item?.id?.toString() ?? 'root';
81
+ }
82
+
83
+ /**
84
+ * Get cached data if valid
85
+ */
86
+ protected getCached(key: string): T[] | undefined {
87
+ const entry = this.cache.get(key);
88
+ if (entry && entry.expiry > Date.now()) {
89
+ return entry.data;
90
+ }
91
+ return undefined;
92
+ }
93
+
94
+ /**
95
+ * Set cache data
96
+ */
97
+ protected setCache(key: string, data: T[]): void {
98
+ this.cache.set(key, {
99
+ data,
100
+ expiry: Date.now() + this.cacheTTL,
101
+ });
102
+ }
103
+
104
+ /**
105
+ * Invalidate specific cache entry
106
+ */
107
+ protected invalidateCache(key: string): void {
108
+ this.cache.delete(key);
109
+ }
110
+
111
+ /**
112
+ * Invalidate all cache entries
113
+ */
114
+ protected invalidateAllCache(): void {
115
+ this.cache.clear();
116
+ }
117
+
118
+ /**
119
+ * Send request to LSP server
120
+ */
121
+ protected async sendRequest<R>(method: string, params?: unknown): Promise<R> {
122
+ if (!this.client) {
123
+ throw new Error('Not connected to server');
124
+ }
125
+ return this.client.sendRequest<R>(method, params);
126
+ }
127
+ }