@shin1ohno/sage 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/cli/mcp-handler.d.ts.map +1 -1
  2. package/dist/cli/mcp-handler.js +154 -6
  3. package/dist/cli/mcp-handler.js.map +1 -1
  4. package/dist/cli/signal-handler.d.ts +23 -0
  5. package/dist/cli/signal-handler.d.ts.map +1 -0
  6. package/dist/cli/signal-handler.js +51 -0
  7. package/dist/cli/signal-handler.js.map +1 -0
  8. package/dist/config/config-differ.d.ts +21 -0
  9. package/dist/config/config-differ.d.ts.map +1 -0
  10. package/dist/config/config-differ.js +194 -0
  11. package/dist/config/config-differ.js.map +1 -0
  12. package/dist/config/config-reload-service.d.ts +84 -0
  13. package/dist/config/config-reload-service.d.ts.map +1 -0
  14. package/dist/config/config-reload-service.js +234 -0
  15. package/dist/config/config-reload-service.js.map +1 -0
  16. package/dist/config/config-watcher.d.ts +78 -0
  17. package/dist/config/config-watcher.d.ts.map +1 -0
  18. package/dist/config/config-watcher.js +244 -0
  19. package/dist/config/config-watcher.js.map +1 -0
  20. package/dist/config/hot-reload-config.d.ts +16 -0
  21. package/dist/config/hot-reload-config.d.ts.map +1 -0
  22. package/dist/config/hot-reload-config.js +61 -0
  23. package/dist/config/hot-reload-config.js.map +1 -0
  24. package/dist/index.js +58 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/services/reloadable/calendar-source-manager-adapter.d.ts +45 -0
  27. package/dist/services/reloadable/calendar-source-manager-adapter.d.ts.map +1 -0
  28. package/dist/services/reloadable/calendar-source-manager-adapter.js +106 -0
  29. package/dist/services/reloadable/calendar-source-manager-adapter.js.map +1 -0
  30. package/dist/services/reloadable/index.d.ts +46 -0
  31. package/dist/services/reloadable/index.d.ts.map +1 -0
  32. package/dist/services/reloadable/index.js +88 -0
  33. package/dist/services/reloadable/index.js.map +1 -0
  34. package/dist/services/reloadable/notion-service-adapter.d.ts +45 -0
  35. package/dist/services/reloadable/notion-service-adapter.d.ts.map +1 -0
  36. package/dist/services/reloadable/notion-service-adapter.js +86 -0
  37. package/dist/services/reloadable/notion-service-adapter.js.map +1 -0
  38. package/dist/services/reloadable/priority-engine-adapter.d.ts +73 -0
  39. package/dist/services/reloadable/priority-engine-adapter.d.ts.map +1 -0
  40. package/dist/services/reloadable/priority-engine-adapter.js +105 -0
  41. package/dist/services/reloadable/priority-engine-adapter.js.map +1 -0
  42. package/dist/services/reloadable/reminder-manager-adapter.d.ts +45 -0
  43. package/dist/services/reloadable/reminder-manager-adapter.d.ts.map +1 -0
  44. package/dist/services/reloadable/reminder-manager-adapter.js +80 -0
  45. package/dist/services/reloadable/reminder-manager-adapter.js.map +1 -0
  46. package/dist/services/reloadable/todo-list-manager-adapter.d.ts +45 -0
  47. package/dist/services/reloadable/todo-list-manager-adapter.d.ts.map +1 -0
  48. package/dist/services/reloadable/todo-list-manager-adapter.js +80 -0
  49. package/dist/services/reloadable/todo-list-manager-adapter.js.map +1 -0
  50. package/dist/services/reloadable/working-cadence-adapter.d.ts +52 -0
  51. package/dist/services/reloadable/working-cadence-adapter.d.ts.map +1 -0
  52. package/dist/services/reloadable/working-cadence-adapter.js +77 -0
  53. package/dist/services/reloadable/working-cadence-adapter.js.map +1 -0
  54. package/dist/services/service-registry.d.ts +85 -0
  55. package/dist/services/service-registry.d.ts.map +1 -0
  56. package/dist/services/service-registry.js +166 -0
  57. package/dist/services/service-registry.js.map +1 -0
  58. package/dist/tools/config/index.d.ts +9 -0
  59. package/dist/tools/config/index.d.ts.map +1 -0
  60. package/dist/tools/config/index.js +8 -0
  61. package/dist/tools/config/index.js.map +1 -0
  62. package/dist/tools/config/reload-handler.d.ts +35 -0
  63. package/dist/tools/config/reload-handler.d.ts.map +1 -0
  64. package/dist/tools/config/reload-handler.js +63 -0
  65. package/dist/tools/config/reload-handler.js.map +1 -0
  66. package/dist/tools/integrations/handlers.d.ts +2 -0
  67. package/dist/tools/integrations/handlers.d.ts.map +1 -1
  68. package/dist/tools/integrations/handlers.js.map +1 -1
  69. package/dist/tools/setup/handlers.d.ts +2 -0
  70. package/dist/tools/setup/handlers.d.ts.map +1 -1
  71. package/dist/tools/setup/handlers.js +14 -0
  72. package/dist/tools/setup/handlers.js.map +1 -1
  73. package/dist/types/hot-reload.d.ts +131 -0
  74. package/dist/types/hot-reload.d.ts.map +1 -0
  75. package/dist/types/hot-reload.js +5 -0
  76. package/dist/types/hot-reload.js.map +1 -0
  77. package/dist/version.js +1 -1
  78. package/dist/version.js.map +1 -1
  79. package/package.json +1 -1
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Configuration Reload Service
3
+ *
4
+ * Orchestrates configuration hot-reload functionality.
5
+ * Subscribes to ConfigWatcher events and coordinates service
6
+ * re-initialization through ServiceRegistry.
7
+ */
8
+ import type { ReloadResult, ConfigReloadServiceOptions, ConfigWatcher } from '../types/hot-reload.js';
9
+ import type { UserConfig } from '../types/config.js';
10
+ import type { ServiceRegistry } from '../services/service-registry.js';
11
+ /**
12
+ * ConfigReloadService manages automatic configuration reloading
13
+ *
14
+ * Subscribes to file change events from ConfigWatcher, validates
15
+ * new configuration, calculates differences, and coordinates
16
+ * service re-initialization through ServiceRegistry.
17
+ */
18
+ export declare class ConfigReloadService {
19
+ private readonly watcher;
20
+ private readonly serviceRegistry;
21
+ private readonly enableAutoReload;
22
+ private readonly onReloadCallback?;
23
+ private currentConfig;
24
+ private lastReloadResult;
25
+ private isReloading;
26
+ private pendingReload;
27
+ private changeHandler;
28
+ /**
29
+ * Create a new ConfigReloadService
30
+ *
31
+ * @param watcher - ConfigWatcher instance to subscribe to
32
+ * @param serviceRegistry - ServiceRegistry for coordinating service re-initialization
33
+ * @param options - Optional configuration options
34
+ */
35
+ constructor(watcher: ConfigWatcher, serviceRegistry: ServiceRegistry, options?: ConfigReloadServiceOptions);
36
+ /**
37
+ * Start the reload service
38
+ *
39
+ * Loads initial configuration and subscribes to watcher events
40
+ * if auto-reload is enabled.
41
+ */
42
+ start(): Promise<void>;
43
+ /**
44
+ * Stop the reload service
45
+ *
46
+ * Unsubscribes from watcher events and stops the watcher.
47
+ */
48
+ stop(): void;
49
+ /**
50
+ * Check if auto-reload is enabled
51
+ */
52
+ isAutoReloadEnabled(): boolean;
53
+ /**
54
+ * Get the result of the last reload operation
55
+ */
56
+ getLastReloadResult(): ReloadResult | null;
57
+ /**
58
+ * Get the current configuration
59
+ */
60
+ getCurrentConfig(): UserConfig | null;
61
+ /**
62
+ * Reload configuration manually or in response to file changes
63
+ *
64
+ * Implements reload lock mechanism to prevent concurrent reloads.
65
+ * If a reload is already in progress, queues the request and returns
66
+ * the same promise.
67
+ *
68
+ * @returns ReloadResult with details about the reload operation
69
+ */
70
+ reload(): Promise<ReloadResult>;
71
+ /**
72
+ * Perform the actual reload operation
73
+ */
74
+ private performReload;
75
+ /**
76
+ * Handle config file change events from watcher
77
+ */
78
+ private handleConfigChange;
79
+ /**
80
+ * Invoke the onReload callback if configured
81
+ */
82
+ private invokeCallback;
83
+ }
84
+ //# sourceMappingURL=config-reload-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-reload-service.d.ts","sourceRoot":"","sources":["../../src/config/config-reload-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,0BAA0B,EAC1B,aAAa,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAKvE;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAiC;IAEnE,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,aAAa,CAAyC;IAE9D;;;;;;OAMG;gBAED,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,eAAe,EAChC,OAAO,GAAE,0BAA+B;IAa1C;;;;;OAKG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB5B;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAeZ;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACH,mBAAmB,IAAI,YAAY,GAAG,IAAI;IAI1C;;OAEG;IACH,gBAAgB,IAAI,UAAU,GAAG,IAAI;IAIrC;;;;;;;;OAQG;IACG,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IA0BrC;;OAEG;YACW,aAAa;IAoG3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,cAAc;CAYvB"}
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Configuration Reload Service
3
+ *
4
+ * Orchestrates configuration hot-reload functionality.
5
+ * Subscribes to ConfigWatcher events and coordinates service
6
+ * re-initialization through ServiceRegistry.
7
+ */
8
+ import { ConfigLoader } from './loader.js';
9
+ import { diffConfig, hasSignificantChanges } from './config-differ.js';
10
+ import { createLogger } from '../utils/logger.js';
11
+ const logger = createLogger('config-reload-service');
12
+ /**
13
+ * ConfigReloadService manages automatic configuration reloading
14
+ *
15
+ * Subscribes to file change events from ConfigWatcher, validates
16
+ * new configuration, calculates differences, and coordinates
17
+ * service re-initialization through ServiceRegistry.
18
+ */
19
+ export class ConfigReloadService {
20
+ watcher;
21
+ serviceRegistry;
22
+ enableAutoReload;
23
+ onReloadCallback;
24
+ currentConfig = null;
25
+ lastReloadResult = null;
26
+ isReloading = false;
27
+ pendingReload = null;
28
+ changeHandler = null;
29
+ /**
30
+ * Create a new ConfigReloadService
31
+ *
32
+ * @param watcher - ConfigWatcher instance to subscribe to
33
+ * @param serviceRegistry - ServiceRegistry for coordinating service re-initialization
34
+ * @param options - Optional configuration options
35
+ */
36
+ constructor(watcher, serviceRegistry, options = {}) {
37
+ this.watcher = watcher;
38
+ this.serviceRegistry = serviceRegistry;
39
+ this.enableAutoReload = options.enableAutoReload ?? true;
40
+ this.onReloadCallback = options.onReload;
41
+ logger.debug({ enableAutoReload: this.enableAutoReload }, 'ConfigReloadService initialized');
42
+ }
43
+ /**
44
+ * Start the reload service
45
+ *
46
+ * Loads initial configuration and subscribes to watcher events
47
+ * if auto-reload is enabled.
48
+ */
49
+ async start() {
50
+ logger.info('Starting ConfigReloadService');
51
+ // Load initial configuration
52
+ try {
53
+ this.currentConfig = await ConfigLoader.load();
54
+ logger.debug('Initial configuration loaded');
55
+ }
56
+ catch (error) {
57
+ logger.error({ err: error }, 'Failed to load initial configuration');
58
+ throw error;
59
+ }
60
+ // Subscribe to watcher events if auto-reload is enabled
61
+ if (this.enableAutoReload) {
62
+ this.changeHandler = this.handleConfigChange.bind(this);
63
+ this.watcher.on('change', this.changeHandler);
64
+ logger.info('Subscribed to config watcher change events');
65
+ }
66
+ }
67
+ /**
68
+ * Stop the reload service
69
+ *
70
+ * Unsubscribes from watcher events and stops the watcher.
71
+ */
72
+ stop() {
73
+ logger.info('Stopping ConfigReloadService');
74
+ // Unsubscribe from watcher events
75
+ if (this.changeHandler) {
76
+ this.watcher.off('change', this.changeHandler);
77
+ this.changeHandler = null;
78
+ logger.debug('Unsubscribed from config watcher change events');
79
+ }
80
+ // Stop the watcher
81
+ this.watcher.stop();
82
+ logger.info('ConfigReloadService stopped');
83
+ }
84
+ /**
85
+ * Check if auto-reload is enabled
86
+ */
87
+ isAutoReloadEnabled() {
88
+ return this.enableAutoReload;
89
+ }
90
+ /**
91
+ * Get the result of the last reload operation
92
+ */
93
+ getLastReloadResult() {
94
+ return this.lastReloadResult;
95
+ }
96
+ /**
97
+ * Get the current configuration
98
+ */
99
+ getCurrentConfig() {
100
+ return this.currentConfig;
101
+ }
102
+ /**
103
+ * Reload configuration manually or in response to file changes
104
+ *
105
+ * Implements reload lock mechanism to prevent concurrent reloads.
106
+ * If a reload is already in progress, queues the request and returns
107
+ * the same promise.
108
+ *
109
+ * @returns ReloadResult with details about the reload operation
110
+ */
111
+ async reload() {
112
+ // If already reloading, queue and return pending promise
113
+ if (this.isReloading && this.pendingReload) {
114
+ logger.debug('Reload already in progress, queueing request');
115
+ return this.pendingReload;
116
+ }
117
+ // Set reload lock
118
+ this.isReloading = true;
119
+ logger.info('Starting configuration reload');
120
+ const startTime = Date.now();
121
+ // Create and store the pending reload promise
122
+ this.pendingReload = this.performReload(startTime);
123
+ try {
124
+ const result = await this.pendingReload;
125
+ return result;
126
+ }
127
+ finally {
128
+ // Release reload lock
129
+ this.isReloading = false;
130
+ this.pendingReload = null;
131
+ }
132
+ }
133
+ /**
134
+ * Perform the actual reload operation
135
+ */
136
+ async performReload(startTime) {
137
+ try {
138
+ // Load new configuration
139
+ logger.debug('Loading new configuration from disk');
140
+ const newConfig = await ConfigLoader.load();
141
+ // Calculate diff if we have a previous config
142
+ let changedSections = [];
143
+ if (this.currentConfig) {
144
+ const diff = diffConfig(this.currentConfig, newConfig);
145
+ logger.debug({
146
+ changedSections: diff.changedSections,
147
+ addedKeys: Object.keys(diff.addedKeys).length,
148
+ removedKeys: diff.removedKeys.length,
149
+ modifiedKeys: Object.keys(diff.modifiedKeys).length,
150
+ }, 'Configuration diff calculated');
151
+ // Check if there are significant changes
152
+ if (!hasSignificantChanges(diff)) {
153
+ logger.info('No significant configuration changes detected');
154
+ const result = {
155
+ success: true,
156
+ changedSections: [],
157
+ reinitializedServices: [],
158
+ timestamp: new Date().toISOString(),
159
+ durationMs: Date.now() - startTime,
160
+ };
161
+ this.lastReloadResult = result;
162
+ this.invokeCallback(result);
163
+ return result;
164
+ }
165
+ changedSections = diff.changedSections;
166
+ }
167
+ // Re-initialize affected services
168
+ logger.info({ changedSections }, 'Re-initializing services for changed sections');
169
+ const affectedServices = this.serviceRegistry.getServicesForSections(changedSections);
170
+ const reinitializedServices = affectedServices.map((s) => s.name);
171
+ await this.serviceRegistry.reinitializeForSections(changedSections, newConfig);
172
+ // Update current config
173
+ this.currentConfig = newConfig;
174
+ const durationMs = Date.now() - startTime;
175
+ logger.info({
176
+ changedSections,
177
+ reinitializedServices,
178
+ durationMs,
179
+ }, 'Configuration reload completed successfully');
180
+ const result = {
181
+ success: true,
182
+ changedSections,
183
+ reinitializedServices,
184
+ timestamp: new Date().toISOString(),
185
+ durationMs,
186
+ };
187
+ this.lastReloadResult = result;
188
+ this.invokeCallback(result);
189
+ return result;
190
+ }
191
+ catch (error) {
192
+ const durationMs = Date.now() - startTime;
193
+ const errorMessage = error instanceof Error ? error.message : String(error);
194
+ logger.error({
195
+ err: error,
196
+ durationMs,
197
+ }, 'Configuration reload failed');
198
+ const result = {
199
+ success: false,
200
+ changedSections: [],
201
+ reinitializedServices: [],
202
+ error: errorMessage,
203
+ timestamp: new Date().toISOString(),
204
+ durationMs,
205
+ };
206
+ this.lastReloadResult = result;
207
+ this.invokeCallback(result);
208
+ return result;
209
+ }
210
+ }
211
+ /**
212
+ * Handle config file change events from watcher
213
+ */
214
+ handleConfigChange(path) {
215
+ logger.info({ path }, 'Config file change detected, triggering reload');
216
+ this.reload().catch((error) => {
217
+ logger.error({ err: error, path }, 'Failed to reload configuration after file change');
218
+ });
219
+ }
220
+ /**
221
+ * Invoke the onReload callback if configured
222
+ */
223
+ invokeCallback(result) {
224
+ if (this.onReloadCallback) {
225
+ try {
226
+ this.onReloadCallback(result);
227
+ }
228
+ catch (error) {
229
+ logger.error({ err: error }, 'Error in onReload callback');
230
+ }
231
+ }
232
+ }
233
+ }
234
+ //# sourceMappingURL=config-reload-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-reload-service.js","sourceRoot":"","sources":["../../src/config/config-reload-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Configuration File Watcher
3
+ * Watches user config and remote config files for changes
4
+ * and emits events with debouncing support.
5
+ */
6
+ import { EventEmitter } from 'events';
7
+ import type { ConfigWatcherOptions, ConfigWatcherEvents } from '../types/hot-reload.js';
8
+ /**
9
+ * ConfigWatcher watches configuration files for changes
10
+ * and emits debounced 'change' events.
11
+ */
12
+ export declare class ConfigWatcher extends EventEmitter {
13
+ private readonly debounceMs;
14
+ private readonly configPaths;
15
+ private watchers;
16
+ private debounceTimers;
17
+ private watching;
18
+ constructor(options?: ConfigWatcherOptions);
19
+ /**
20
+ * Start watching all configuration files
21
+ */
22
+ start(): Promise<void>;
23
+ /**
24
+ * Stop watching all configuration files
25
+ */
26
+ stop(): void;
27
+ /**
28
+ * Check if the watcher is currently active
29
+ */
30
+ isWatching(): boolean;
31
+ /**
32
+ * Get the list of watched paths
33
+ */
34
+ getWatchedPaths(): string[];
35
+ /**
36
+ * Watch a single file for changes
37
+ */
38
+ private watchFile;
39
+ /**
40
+ * Watch for file creation when the file doesn't exist
41
+ */
42
+ private watchForFileCreation;
43
+ /**
44
+ * Handle file change events
45
+ */
46
+ private handleFileChange;
47
+ /**
48
+ * Handle potential file deletion
49
+ */
50
+ private handlePotentialDeletion;
51
+ /**
52
+ * Emit debounced change event
53
+ */
54
+ private emitDebouncedChange;
55
+ /**
56
+ * Handle watch errors
57
+ */
58
+ private handleWatchError;
59
+ /**
60
+ * Check if a file exists
61
+ */
62
+ private fileExists;
63
+ /**
64
+ * Get parent directory of a file path
65
+ */
66
+ private getParentDirectory;
67
+ /**
68
+ * Get file name from a file path
69
+ */
70
+ private getFileName;
71
+ /**
72
+ * Type-safe event emitter methods
73
+ */
74
+ on<K extends keyof ConfigWatcherEvents>(event: K, listener: ConfigWatcherEvents[K]): this;
75
+ off<K extends keyof ConfigWatcherEvents>(event: K, listener: ConfigWatcherEvents[K]): this;
76
+ emit<K extends keyof ConfigWatcherEvents>(event: K, ...args: Parameters<ConfigWatcherEvents[K]>): boolean;
77
+ }
78
+ //# sourceMappingURL=config-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-watcher.d.ts","sourceRoot":"","sources":["../../src/config/config-watcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAYxF;;;GAGG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,OAAO,GAAE,oBAAyB;IAW9C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAe5B;;OAEG;IACH,IAAI,IAAI,IAAI;IAwBZ;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;IAI3B;;OAEG;YACW,SAAS;IA0BvB;;OAEG;YACW,oBAAoB;IAsClC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;OAEG;YACW,uBAAuB;IAoBrC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;YACW,UAAU;IASxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACM,EAAE,CAAC,CAAC,SAAS,MAAM,mBAAmB,EAC7C,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC/B,IAAI;IAIE,GAAG,CAAC,CAAC,SAAS,MAAM,mBAAmB,EAC9C,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC/B,IAAI;IAIE,IAAI,CAAC,CAAC,SAAS,MAAM,mBAAmB,EAC/C,KAAK,EAAE,CAAC,EACR,GAAG,IAAI,EAAE,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAC1C,OAAO;CAGX"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Configuration File Watcher
3
+ * Watches user config and remote config files for changes
4
+ * and emits events with debouncing support.
5
+ */
6
+ import { EventEmitter } from 'events';
7
+ import { watch, constants, promises as fsPromises } from 'fs';
8
+ import { ConfigLoader } from './loader.js';
9
+ import { DEFAULT_REMOTE_CONFIG_PATH } from '../cli/remote-config-loader.js';
10
+ import { createLogger } from '../utils/logger.js';
11
+ const logger = createLogger('config-watcher');
12
+ /**
13
+ * Default debounce delay in milliseconds
14
+ */
15
+ const DEFAULT_DEBOUNCE_MS = 500;
16
+ /**
17
+ * ConfigWatcher watches configuration files for changes
18
+ * and emits debounced 'change' events.
19
+ */
20
+ export class ConfigWatcher extends EventEmitter {
21
+ debounceMs;
22
+ configPaths;
23
+ watchers = new Map();
24
+ debounceTimers = new Map();
25
+ watching = false;
26
+ constructor(options = {}) {
27
+ super();
28
+ this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
29
+ this.configPaths = options.configPaths ?? [
30
+ ConfigLoader.getConfigPath(),
31
+ DEFAULT_REMOTE_CONFIG_PATH,
32
+ ];
33
+ logger.debug({ debounceMs: this.debounceMs, configPaths: this.configPaths }, 'ConfigWatcher initialized');
34
+ }
35
+ /**
36
+ * Start watching all configuration files
37
+ */
38
+ async start() {
39
+ if (this.watching) {
40
+ logger.warn('ConfigWatcher is already watching');
41
+ return;
42
+ }
43
+ logger.info({ paths: this.configPaths }, 'Starting config file watcher');
44
+ for (const configPath of this.configPaths) {
45
+ await this.watchFile(configPath);
46
+ }
47
+ this.watching = true;
48
+ }
49
+ /**
50
+ * Stop watching all configuration files
51
+ */
52
+ stop() {
53
+ if (!this.watching) {
54
+ logger.warn('ConfigWatcher is not watching');
55
+ return;
56
+ }
57
+ logger.info('Stopping config file watcher');
58
+ // Clear all debounce timers
59
+ Array.from(this.debounceTimers.values()).forEach((timer) => {
60
+ clearTimeout(timer);
61
+ });
62
+ this.debounceTimers.clear();
63
+ // Close all file watchers
64
+ Array.from(this.watchers.entries()).forEach(([watchPath, watcher]) => {
65
+ logger.debug({ path: watchPath }, 'Closing watcher');
66
+ watcher.close();
67
+ });
68
+ this.watchers.clear();
69
+ this.watching = false;
70
+ }
71
+ /**
72
+ * Check if the watcher is currently active
73
+ */
74
+ isWatching() {
75
+ return this.watching;
76
+ }
77
+ /**
78
+ * Get the list of watched paths
79
+ */
80
+ getWatchedPaths() {
81
+ return [...this.configPaths];
82
+ }
83
+ /**
84
+ * Watch a single file for changes
85
+ */
86
+ async watchFile(filePath) {
87
+ try {
88
+ // Check if file exists before watching
89
+ const fileExists = await this.fileExists(filePath);
90
+ if (!fileExists) {
91
+ logger.warn({ path: filePath }, 'Config file does not exist, will watch for creation');
92
+ // Watch the parent directory for file creation
93
+ await this.watchForFileCreation(filePath);
94
+ return;
95
+ }
96
+ const watcher = watch(filePath, (_eventType, _filename) => {
97
+ this.handleFileChange(filePath, _eventType);
98
+ });
99
+ watcher.on('error', (error) => {
100
+ this.handleWatchError(filePath, error);
101
+ });
102
+ this.watchers.set(filePath, watcher);
103
+ logger.debug({ path: filePath }, 'Started watching config file');
104
+ }
105
+ catch (error) {
106
+ this.handleWatchError(filePath, error);
107
+ }
108
+ }
109
+ /**
110
+ * Watch for file creation when the file doesn't exist
111
+ */
112
+ async watchForFileCreation(filePath) {
113
+ const parentDir = this.getParentDirectory(filePath);
114
+ const fileName = this.getFileName(filePath);
115
+ try {
116
+ // Check if parent directory exists
117
+ const parentExists = await this.fileExists(parentDir);
118
+ if (!parentExists) {
119
+ logger.warn({ path: parentDir }, 'Parent directory does not exist, cannot watch for file creation');
120
+ return;
121
+ }
122
+ const watcher = watch(parentDir, async (eventType, detectedFileName) => {
123
+ if (detectedFileName === fileName && eventType === 'rename') {
124
+ const fileNowExists = await this.fileExists(filePath);
125
+ if (fileNowExists) {
126
+ logger.info({ path: filePath }, 'Config file created, starting to watch');
127
+ // Close directory watcher and start file watcher
128
+ watcher.close();
129
+ this.watchers.delete(parentDir + ':' + fileName);
130
+ await this.watchFile(filePath);
131
+ // Emit change event for the newly created file
132
+ this.emitDebouncedChange(filePath);
133
+ }
134
+ }
135
+ });
136
+ watcher.on('error', (error) => {
137
+ logger.error({ path: parentDir, error: error.message }, 'Error watching parent directory');
138
+ });
139
+ this.watchers.set(parentDir + ':' + fileName, watcher);
140
+ logger.debug({ path: parentDir, fileName }, 'Watching parent directory for file creation');
141
+ }
142
+ catch (error) {
143
+ logger.error({ path: parentDir, error: error.message }, 'Failed to watch parent directory');
144
+ }
145
+ }
146
+ /**
147
+ * Handle file change events
148
+ */
149
+ handleFileChange(filePath, eventType) {
150
+ logger.debug({ path: filePath, eventType }, 'File change detected');
151
+ if (eventType === 'rename') {
152
+ // File may have been deleted
153
+ this.handlePotentialDeletion(filePath);
154
+ return;
155
+ }
156
+ // Debounce the change event
157
+ this.emitDebouncedChange(filePath);
158
+ }
159
+ /**
160
+ * Handle potential file deletion
161
+ */
162
+ async handlePotentialDeletion(filePath) {
163
+ const fileExists = await this.fileExists(filePath);
164
+ if (!fileExists) {
165
+ logger.warn({ path: filePath }, 'Config file was deleted, continuing with current config');
166
+ // Close the current watcher
167
+ const watcher = this.watchers.get(filePath);
168
+ if (watcher) {
169
+ watcher.close();
170
+ this.watchers.delete(filePath);
171
+ }
172
+ // Start watching for file recreation
173
+ await this.watchForFileCreation(filePath);
174
+ }
175
+ else {
176
+ // File was recreated or renamed back
177
+ logger.info({ path: filePath }, 'Config file recreated');
178
+ this.emitDebouncedChange(filePath);
179
+ }
180
+ }
181
+ /**
182
+ * Emit debounced change event
183
+ */
184
+ emitDebouncedChange(filePath) {
185
+ // Clear existing timer for this path
186
+ const existingTimer = this.debounceTimers.get(filePath);
187
+ if (existingTimer) {
188
+ clearTimeout(existingTimer);
189
+ }
190
+ // Set new debounce timer
191
+ const timer = setTimeout(() => {
192
+ this.debounceTimers.delete(filePath);
193
+ logger.info({ path: filePath }, 'Emitting config change event');
194
+ this.emit('change', filePath);
195
+ }, this.debounceMs);
196
+ this.debounceTimers.set(filePath, timer);
197
+ }
198
+ /**
199
+ * Handle watch errors
200
+ */
201
+ handleWatchError(filePath, error) {
202
+ logger.error({ path: filePath, error: error.message }, 'Error watching config file');
203
+ this.emit('error', error);
204
+ }
205
+ /**
206
+ * Check if a file exists
207
+ */
208
+ async fileExists(filePath) {
209
+ try {
210
+ await fsPromises.access(filePath, constants.F_OK);
211
+ return true;
212
+ }
213
+ catch {
214
+ return false;
215
+ }
216
+ }
217
+ /**
218
+ * Get parent directory of a file path
219
+ */
220
+ getParentDirectory(filePath) {
221
+ const lastSlash = filePath.lastIndexOf('/');
222
+ return lastSlash > 0 ? filePath.substring(0, lastSlash) : '/';
223
+ }
224
+ /**
225
+ * Get file name from a file path
226
+ */
227
+ getFileName(filePath) {
228
+ const lastSlash = filePath.lastIndexOf('/');
229
+ return lastSlash >= 0 ? filePath.substring(lastSlash + 1) : filePath;
230
+ }
231
+ /**
232
+ * Type-safe event emitter methods
233
+ */
234
+ on(event, listener) {
235
+ return super.on(event, listener);
236
+ }
237
+ off(event, listener) {
238
+ return super.off(event, listener);
239
+ }
240
+ emit(event, ...args) {
241
+ return super.emit(event, ...args);
242
+ }
243
+ }
244
+ //# sourceMappingURL=config-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-watcher.js","sourceRoot":"","sources":["../../src/config/config-watcher.ts"],"names":[],"mappings":"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"}