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
+ * Pattern command handlers
3
+ *
4
+ * Single responsibility: Handle pattern-related commands.
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+
9
+ import { DRIFT_COMMANDS } from '../command-definitions.js';
10
+
11
+ import type { ConnectionManager } from '../../client/index.js';
12
+ import type { NotificationService } from '../../ui/notifications/notification-service.js';
13
+ import type { CommandRouter, CommandContext } from '../command-router.js';
14
+
15
+
16
+ /**
17
+ * Pattern quick pick item with id
18
+ */
19
+ interface PatternQuickPickItem extends vscode.QuickPickItem {
20
+ id: string;
21
+ }
22
+
23
+ /**
24
+ * Create pattern command handlers
25
+ */
26
+ export function createPatternHandlers(
27
+ router: CommandRouter,
28
+ connectionManager: ConnectionManager,
29
+ notifications: NotificationService
30
+ ): void {
31
+ // Show patterns command
32
+ router.register({
33
+ id: DRIFT_COMMANDS.showPatterns,
34
+ handler: async (_ctx: CommandContext) => {
35
+ // Focus the patterns tree view
36
+ await vscode.commands.executeCommand('drift.patterns.focus');
37
+ },
38
+ });
39
+
40
+ // Approve pattern command
41
+ router.register({
42
+ id: DRIFT_COMMANDS.approvePattern,
43
+ handler: async (ctx: CommandContext) => {
44
+ const client = connectionManager.getClient();
45
+ if (!client) {
46
+ throw new Error('Not connected to server');
47
+ }
48
+
49
+ const patternId = ctx.args[0] as string | undefined;
50
+
51
+ if (!patternId) {
52
+ // Show pattern picker
53
+ const patterns = await client.sendRequest<Array<{ id: string; name: string }>>(
54
+ 'drift/patterns/list',
55
+ { status: 'discovered' }
56
+ );
57
+
58
+ if (patterns.length === 0) {
59
+ await notifications.info('No patterns to approve.');
60
+ return;
61
+ }
62
+
63
+ const items: PatternQuickPickItem[] = patterns.map((p: { id: string; name: string }) => ({
64
+ label: p.name,
65
+ description: p.id,
66
+ id: p.id,
67
+ }));
68
+
69
+ const selected = await notifications.quickPick(items, { title: 'Select Pattern to Approve' });
70
+
71
+ if (!selected) {return;}
72
+
73
+ await client.sendRequest('drift/patterns/approve', { id: selected.id });
74
+ await notifications.info(`Pattern "${selected.label}" approved.`);
75
+ } else {
76
+ await client.sendRequest('drift/patterns/approve', { id: patternId });
77
+ await notifications.info(`Pattern approved.`);
78
+ }
79
+ },
80
+ });
81
+
82
+ // Ignore pattern command
83
+ router.register({
84
+ id: DRIFT_COMMANDS.ignorePattern,
85
+ handler: async (ctx: CommandContext) => {
86
+ const client = connectionManager.getClient();
87
+ if (!client) {
88
+ throw new Error('Not connected to server');
89
+ }
90
+
91
+ const patternId = ctx.args[0] as string | undefined;
92
+
93
+ if (!patternId) {
94
+ // Show pattern picker
95
+ const patterns = await client.sendRequest<Array<{ id: string; name: string }>>(
96
+ 'drift/patterns/list',
97
+ { status: 'discovered' }
98
+ );
99
+
100
+ if (patterns.length === 0) {
101
+ await notifications.info('No patterns to ignore.');
102
+ return;
103
+ }
104
+
105
+ const items: PatternQuickPickItem[] = patterns.map((p: { id: string; name: string }) => ({
106
+ label: p.name,
107
+ description: p.id,
108
+ id: p.id,
109
+ }));
110
+
111
+ const selected = await notifications.quickPick(items, { title: 'Select Pattern to Ignore' });
112
+
113
+ if (!selected) {return;}
114
+
115
+ await client.sendRequest('drift/patterns/ignore', { id: selected.id });
116
+ await notifications.info(`Pattern "${selected.label}" ignored.`);
117
+ } else {
118
+ await client.sendRequest('drift/patterns/ignore', { id: patternId });
119
+ await notifications.info(`Pattern ignored.`);
120
+ }
121
+ },
122
+ });
123
+
124
+ // Create variant command
125
+ router.register({
126
+ id: DRIFT_COMMANDS.createVariant,
127
+ handler: async (ctx: CommandContext) => {
128
+ const client = connectionManager.getClient();
129
+ if (!client) {
130
+ throw new Error('Not connected to server');
131
+ }
132
+
133
+ const patternId = ctx.args[0] as string | undefined;
134
+ const violationId = ctx.args[1] as string | undefined;
135
+
136
+ if (!patternId) {
137
+ await notifications.warning('No pattern specified for variant creation.');
138
+ return;
139
+ }
140
+
141
+ // Get variant name from user
142
+ const name = await notifications.inputBox({
143
+ title: 'Create Variant',
144
+ prompt: 'Enter a name for this variant',
145
+ placeHolder: 'e.g., legacy-auth-pattern',
146
+ });
147
+
148
+ if (!name) {return;}
149
+
150
+ // Get variant description
151
+ const description = await notifications.inputBox({
152
+ title: 'Create Variant',
153
+ prompt: 'Enter a description (optional)',
154
+ placeHolder: 'e.g., Used in legacy authentication module',
155
+ });
156
+
157
+ await client.sendRequest('drift/patterns/createVariant', {
158
+ patternId,
159
+ violationId,
160
+ name,
161
+ description,
162
+ });
163
+
164
+ await notifications.info(`Variant "${name}" created.`);
165
+ },
166
+ });
167
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Scan command handlers
3
+ *
4
+ * Single responsibility: Handle scan-related commands.
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+
9
+ import { DRIFT_COMMANDS } from '../command-definitions.js';
10
+
11
+ import type { ConnectionManager } from '../../client/index.js';
12
+ import type { EventBus } from '../../infrastructure/event-bus.js';
13
+ import type { StateManager } from '../../state/index.js';
14
+ import type { NotificationService } from '../../ui/notifications/notification-service.js';
15
+ import type { CommandRouter, CommandContext } from '../command-router.js';
16
+
17
+
18
+ /**
19
+ * Create scan command handlers
20
+ */
21
+ export function createScanHandlers(
22
+ router: CommandRouter,
23
+ connectionManager: ConnectionManager,
24
+ stateManager: StateManager,
25
+ notifications: NotificationService,
26
+ eventBus: EventBus
27
+ ): void {
28
+ // Rescan workspace command
29
+ router.register({
30
+ id: DRIFT_COMMANDS.rescan,
31
+ showProgress: true,
32
+ progressTitle: 'Scanning workspace...',
33
+ handler: async (ctx: CommandContext) => {
34
+ const client = connectionManager.getClient();
35
+ if (!client) {
36
+ throw new Error('Not connected to server');
37
+ }
38
+
39
+ // Update state to scanning
40
+ stateManager.update(draft => {
41
+ draft.workspace.scanning = true;
42
+ });
43
+
44
+ eventBus.emit('scan:started', { files: 0 });
45
+
46
+ try {
47
+ ctx.progress?.report({ message: 'Analyzing patterns...' });
48
+
49
+ const result = await client.sendRequest<{
50
+ patterns: number;
51
+ violations: number;
52
+ duration: number;
53
+ }>('drift/rescan');
54
+
55
+ // Update state with results
56
+ stateManager.update(draft => {
57
+ draft.workspace.scanning = false;
58
+ draft.workspace.lastScanTime = Date.now();
59
+ draft.patterns.total = result.patterns;
60
+ draft.violations.total = result.violations;
61
+ });
62
+
63
+ eventBus.emit('scan:completed', {
64
+ duration: result.duration,
65
+ patterns: result.patterns,
66
+ violations: result.violations,
67
+ });
68
+
69
+ await notifications.info(
70
+ `Scan complete: ${result.patterns} patterns, ${result.violations} violations`
71
+ );
72
+ } catch (error) {
73
+ stateManager.update(draft => {
74
+ draft.workspace.scanning = false;
75
+ });
76
+ throw error;
77
+ }
78
+ },
79
+ });
80
+
81
+ // Scan current file command
82
+ router.register({
83
+ id: DRIFT_COMMANDS.scanFile,
84
+ handler: async (_ctx: CommandContext) => {
85
+ const editor = vscode.window.activeTextEditor;
86
+ if (!editor) {
87
+ await notifications.warning('No file is currently open.');
88
+ return;
89
+ }
90
+
91
+ const client = connectionManager.getClient();
92
+ if (!client) {
93
+ throw new Error('Not connected to server');
94
+ }
95
+
96
+ const uri = editor.document.uri.toString();
97
+
98
+ await notifications.withProgress('Scanning file...', async (progress) => {
99
+ progress.report({ message: editor.document.fileName });
100
+
101
+ await client.sendRequest('drift/scanFile', { uri });
102
+
103
+ await notifications.info('File scan complete.');
104
+ });
105
+ },
106
+ });
107
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * UI command handlers
3
+ *
4
+ * Single responsibility: Handle UI-related commands.
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+
9
+ import { DRIFT_COMMANDS } from '../command-definitions.js';
10
+
11
+ import type { NotificationService } from '../../ui/notifications/notification-service.js';
12
+ import type { CommandRouter, CommandContext } from '../command-router.js';
13
+
14
+ /**
15
+ * Create UI command handlers
16
+ */
17
+ export function createUIHandlers(
18
+ router: CommandRouter,
19
+ notifications: NotificationService
20
+ ): void {
21
+ // Open dashboard command
22
+ router.register({
23
+ id: DRIFT_COMMANDS.openDashboard,
24
+ handler: async (_ctx: CommandContext) => {
25
+ // Open the dashboard webview
26
+ await vscode.commands.executeCommand('drift.dashboard.focus');
27
+ },
28
+ });
29
+
30
+ // Open settings command
31
+ router.register({
32
+ id: DRIFT_COMMANDS.openSettings,
33
+ handler: async (_ctx: CommandContext) => {
34
+ // Open VS Code settings filtered to Drift
35
+ await vscode.commands.executeCommand(
36
+ 'workbench.action.openSettings',
37
+ '@ext:drift.drift'
38
+ );
39
+ },
40
+ });
41
+
42
+ // Export patterns command
43
+ router.register({
44
+ id: DRIFT_COMMANDS.exportPatterns,
45
+ showProgress: true,
46
+ progressTitle: 'Exporting patterns...',
47
+ handler: async (_ctx: CommandContext) => {
48
+ // Show save dialog
49
+ const uri = await vscode.window.showSaveDialog({
50
+ defaultUri: vscode.Uri.file('drift-patterns.json'),
51
+ filters: {
52
+ 'JSON': ['json'],
53
+ 'All Files': ['*'],
54
+ },
55
+ title: 'Export Patterns',
56
+ });
57
+
58
+ if (!uri) {return;}
59
+
60
+ // TODO: Implement actual export via LSP
61
+ await notifications.info(`Patterns exported to ${uri.fsPath}`);
62
+ },
63
+ });
64
+
65
+ // Generate report command
66
+ router.register({
67
+ id: DRIFT_COMMANDS.generateReport,
68
+ showProgress: true,
69
+ progressTitle: 'Generating report...',
70
+ handler: async (_ctx: CommandContext) => {
71
+ // Show save dialog
72
+ const uri = await vscode.window.showSaveDialog({
73
+ defaultUri: vscode.Uri.file('drift-report.html'),
74
+ filters: {
75
+ 'HTML': ['html'],
76
+ 'Markdown': ['md'],
77
+ 'JSON': ['json'],
78
+ },
79
+ title: 'Generate Report',
80
+ });
81
+
82
+ if (!uri) {return;}
83
+
84
+ // TODO: Implement actual report generation via LSP
85
+ await notifications.info(`Report generated at ${uri.fsPath}`);
86
+ },
87
+ });
88
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Violation command handlers
3
+ *
4
+ * Single responsibility: Handle violation-related commands.
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+
9
+ import { DRIFT_COMMANDS } from '../command-definitions.js';
10
+
11
+ import type { ConnectionManager } from '../../client/index.js';
12
+ import type { NotificationService } from '../../ui/notifications/notification-service.js';
13
+ import type { CommandRouter, CommandContext } from '../command-router.js';
14
+
15
+
16
+ /**
17
+ * Create violation command handlers
18
+ */
19
+ export function createViolationHandlers(
20
+ router: CommandRouter,
21
+ connectionManager: ConnectionManager,
22
+ notifications: NotificationService
23
+ ): void {
24
+ // Show violations command
25
+ router.register({
26
+ id: DRIFT_COMMANDS.showViolations,
27
+ handler: async (_ctx: CommandContext) => {
28
+ // Focus the violations tree view
29
+ await vscode.commands.executeCommand('drift.violations.focus');
30
+ },
31
+ });
32
+
33
+ // Ignore once command
34
+ router.register({
35
+ id: DRIFT_COMMANDS.ignoreOnce,
36
+ handler: async (ctx: CommandContext) => {
37
+ const client = connectionManager.getClient();
38
+ if (!client) {
39
+ throw new Error('Not connected to server');
40
+ }
41
+
42
+ const violationId = ctx.args[0] as string | undefined;
43
+ const uri = ctx.args[1] as string | undefined;
44
+ const line = ctx.args[2] as number | undefined;
45
+
46
+ if (!violationId || !uri || line === undefined) {
47
+ // Try to get from current editor position
48
+ const editor = vscode.window.activeTextEditor;
49
+ if (!editor) {
50
+ await notifications.warning('No violation selected.');
51
+ return;
52
+ }
53
+
54
+ const position = editor.selection.active;
55
+ const diagnostics = vscode.languages.getDiagnostics(editor.document.uri);
56
+ const driftDiagnostic = diagnostics.find(
57
+ d => d.source === 'drift' && d.range.contains(position)
58
+ );
59
+
60
+ if (!driftDiagnostic) {
61
+ await notifications.warning('No Drift violation at cursor position.');
62
+ return;
63
+ }
64
+
65
+ // Extract violation ID from diagnostic data
66
+ const data = (driftDiagnostic as any).data;
67
+ if (!data?.violationId) {
68
+ await notifications.warning('Cannot identify violation.');
69
+ return;
70
+ }
71
+
72
+ await client.sendRequest('drift/violations/ignoreOnce', {
73
+ violationId: data.violationId,
74
+ uri: editor.document.uri.toString(),
75
+ line: driftDiagnostic.range.start.line,
76
+ });
77
+ } else {
78
+ await client.sendRequest('drift/violations/ignoreOnce', {
79
+ violationId,
80
+ uri,
81
+ line,
82
+ });
83
+ }
84
+
85
+ await notifications.info('Violation ignored for this occurrence.');
86
+ },
87
+ });
88
+
89
+ // Quick fix command
90
+ router.register({
91
+ id: DRIFT_COMMANDS.quickFix,
92
+ handler: async (_ctx: CommandContext) => {
93
+ // Trigger VS Code's built-in quick fix
94
+ await vscode.commands.executeCommand('editor.action.quickFix');
95
+ },
96
+ });
97
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Commands module exports
3
+ */
4
+
5
+ export { CommandRouter, createCommandRouter } from './command-router.js';
6
+ export { CommandDefinitions, DRIFT_COMMANDS } from './command-definitions.js';
7
+ export * from './handlers/index.js';
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Connection check middleware
3
+ *
4
+ * Single responsibility: Verify connection before command execution.
5
+ */
6
+
7
+ import { DRIFT_COMMANDS, type DriftCommand } from '../command-definitions.js';
8
+
9
+ import type { StateManager } from '../../state/index.js';
10
+ import type { CommandMiddleware, CommandContext } from '../command-router.js';
11
+
12
+ /**
13
+ * Commands that don't require connection
14
+ */
15
+ const CONNECTION_EXEMPT_COMMANDS = new Set<DriftCommand>([
16
+ DRIFT_COMMANDS.reconnect,
17
+ DRIFT_COMMANDS.showStatus,
18
+ DRIFT_COMMANDS.showError,
19
+ DRIFT_COMMANDS.openSettings,
20
+ DRIFT_COMMANDS.openDashboard,
21
+ ]);
22
+
23
+ /**
24
+ * Create connection check middleware
25
+ */
26
+ export function createConnectionCheckMiddleware(
27
+ stateManager: StateManager
28
+ ): CommandMiddleware {
29
+ return async (ctx: CommandContext, next: () => Promise<void>): Promise<void> => {
30
+ // Skip check for exempt commands
31
+ if (CONNECTION_EXEMPT_COMMANDS.has(ctx.command)) {
32
+ await next();
33
+ return;
34
+ }
35
+
36
+ const state = stateManager.getState();
37
+
38
+ if (state.connection.status !== 'connected') {
39
+ throw new Error(
40
+ 'Drift server is not connected. Please wait for initialization or run "Drift: Reconnect".'
41
+ );
42
+ }
43
+
44
+ await next();
45
+ };
46
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Command middleware module exports
3
+ */
4
+
5
+ export { createLoggingMiddleware } from './logging-middleware.js';
6
+ export { createConnectionCheckMiddleware } from './connection-check-middleware.js';
7
+ export { createTelemetryMiddleware } from './telemetry-middleware.js';
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Logging middleware
3
+ *
4
+ * Single responsibility: Log command execution.
5
+ */
6
+
7
+ import type { Logger } from '../../infrastructure/index.js';
8
+ import type { CommandMiddleware, CommandContext } from '../command-router.js';
9
+
10
+ /**
11
+ * Create logging middleware
12
+ */
13
+ export function createLoggingMiddleware(logger: Logger): CommandMiddleware {
14
+ return async (ctx: CommandContext, next: () => Promise<void>): Promise<void> => {
15
+ logger.debug(`Executing command: ${ctx.command}`, { args: ctx.args });
16
+
17
+ try {
18
+ await next();
19
+
20
+ const duration = performance.now() - ctx.startTime;
21
+ logger.debug(`Command completed: ${ctx.command} (${duration.toFixed(2)}ms)`);
22
+ } catch (error) {
23
+ const duration = performance.now() - ctx.startTime;
24
+ logger.error(`Command failed: ${ctx.command} (${duration.toFixed(2)}ms)`, error);
25
+ throw error;
26
+ }
27
+ };
28
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Telemetry middleware
3
+ *
4
+ * Single responsibility: Track command usage for analytics.
5
+ */
6
+
7
+ import type { CommandMiddleware, CommandContext } from '../command-router.js';
8
+
9
+ /**
10
+ * Telemetry tracker interface
11
+ */
12
+ export interface TelemetryTracker {
13
+ trackCommand(data: {
14
+ command: string;
15
+ duration: number;
16
+ success: boolean;
17
+ error?: string;
18
+ }): void;
19
+ }
20
+
21
+ /**
22
+ * Create telemetry middleware
23
+ */
24
+ export function createTelemetryMiddleware(
25
+ tracker: TelemetryTracker
26
+ ): CommandMiddleware {
27
+ return async (ctx: CommandContext, next: () => Promise<void>): Promise<void> => {
28
+ try {
29
+ await next();
30
+
31
+ tracker.trackCommand({
32
+ command: ctx.command,
33
+ duration: performance.now() - ctx.startTime,
34
+ success: true,
35
+ });
36
+ } catch (error) {
37
+ tracker.trackCommand({
38
+ command: ctx.command,
39
+ duration: performance.now() - ctx.startTime,
40
+ success: false,
41
+ error: error instanceof Error ? error.name : 'UnknownError',
42
+ });
43
+ throw error;
44
+ }
45
+ };
46
+ }