wave-agent-sdk 0.0.7 → 0.0.8

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 (172) hide show
  1. package/dist/agent.d.ts +32 -20
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +202 -20
  4. package/dist/constants/events.d.ts +28 -0
  5. package/dist/constants/events.d.ts.map +1 -0
  6. package/dist/constants/events.js +27 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -0
  10. package/dist/managers/aiManager.d.ts +34 -1
  11. package/dist/managers/aiManager.d.ts.map +1 -1
  12. package/dist/managers/aiManager.js +243 -128
  13. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  14. package/dist/managers/backgroundBashManager.js +7 -6
  15. package/dist/managers/hookManager.d.ts +9 -4
  16. package/dist/managers/hookManager.d.ts.map +1 -1
  17. package/dist/managers/hookManager.js +62 -30
  18. package/dist/managers/liveConfigManager.d.ts +58 -0
  19. package/dist/managers/liveConfigManager.d.ts.map +1 -0
  20. package/dist/managers/liveConfigManager.js +160 -0
  21. package/dist/managers/messageManager.d.ts +38 -13
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +163 -30
  24. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  25. package/dist/managers/slashCommandManager.js +4 -1
  26. package/dist/managers/subagentManager.d.ts +51 -0
  27. package/dist/managers/subagentManager.d.ts.map +1 -1
  28. package/dist/managers/subagentManager.js +189 -18
  29. package/dist/services/aiService.d.ts +13 -5
  30. package/dist/services/aiService.d.ts.map +1 -1
  31. package/dist/services/aiService.js +350 -74
  32. package/dist/services/configurationWatcher.d.ts +120 -0
  33. package/dist/services/configurationWatcher.d.ts.map +1 -0
  34. package/dist/services/configurationWatcher.js +439 -0
  35. package/dist/services/fileWatcher.d.ts +69 -0
  36. package/dist/services/fileWatcher.d.ts.map +1 -0
  37. package/dist/services/fileWatcher.js +213 -0
  38. package/dist/services/hook.d.ts +91 -9
  39. package/dist/services/hook.d.ts.map +1 -1
  40. package/dist/services/hook.js +393 -43
  41. package/dist/services/jsonlHandler.d.ts +62 -0
  42. package/dist/services/jsonlHandler.d.ts.map +1 -0
  43. package/dist/services/jsonlHandler.js +257 -0
  44. package/dist/services/memory.d.ts +9 -0
  45. package/dist/services/memory.d.ts.map +1 -1
  46. package/dist/services/memory.js +81 -12
  47. package/dist/services/memoryStore.d.ts +81 -0
  48. package/dist/services/memoryStore.d.ts.map +1 -0
  49. package/dist/services/memoryStore.js +200 -0
  50. package/dist/services/session.d.ts +64 -49
  51. package/dist/services/session.d.ts.map +1 -1
  52. package/dist/services/session.js +310 -132
  53. package/dist/tools/bashTool.d.ts.map +1 -1
  54. package/dist/tools/bashTool.js +5 -4
  55. package/dist/tools/deleteFileTool.d.ts.map +1 -1
  56. package/dist/tools/deleteFileTool.js +2 -1
  57. package/dist/tools/editTool.d.ts.map +1 -1
  58. package/dist/tools/editTool.js +3 -2
  59. package/dist/tools/multiEditTool.d.ts.map +1 -1
  60. package/dist/tools/multiEditTool.js +4 -3
  61. package/dist/tools/readTool.d.ts.map +1 -1
  62. package/dist/tools/readTool.js +2 -1
  63. package/dist/tools/writeTool.d.ts.map +1 -1
  64. package/dist/tools/writeTool.js +5 -6
  65. package/dist/types/commands.d.ts +4 -0
  66. package/dist/types/commands.d.ts.map +1 -1
  67. package/dist/types/core.d.ts +35 -0
  68. package/dist/types/core.d.ts.map +1 -1
  69. package/dist/types/environment.d.ts +42 -0
  70. package/dist/types/environment.d.ts.map +1 -0
  71. package/dist/types/environment.js +21 -0
  72. package/dist/types/hooks.d.ts +8 -2
  73. package/dist/types/hooks.d.ts.map +1 -1
  74. package/dist/types/hooks.js +8 -2
  75. package/dist/types/index.d.ts +2 -0
  76. package/dist/types/index.d.ts.map +1 -1
  77. package/dist/types/index.js +2 -0
  78. package/dist/types/memoryStore.d.ts +82 -0
  79. package/dist/types/memoryStore.d.ts.map +1 -0
  80. package/dist/types/memoryStore.js +7 -0
  81. package/dist/types/messaging.d.ts +14 -2
  82. package/dist/types/messaging.d.ts.map +1 -1
  83. package/dist/types/session.d.ts +20 -0
  84. package/dist/types/session.d.ts.map +1 -0
  85. package/dist/types/session.js +7 -0
  86. package/dist/utils/bashHistory.d.ts.map +1 -1
  87. package/dist/utils/bashHistory.js +27 -26
  88. package/dist/utils/cacheControlUtils.d.ts +121 -0
  89. package/dist/utils/cacheControlUtils.d.ts.map +1 -0
  90. package/dist/utils/cacheControlUtils.js +367 -0
  91. package/dist/utils/commandPathResolver.d.ts +52 -0
  92. package/dist/utils/commandPathResolver.d.ts.map +1 -0
  93. package/dist/utils/commandPathResolver.js +145 -0
  94. package/dist/utils/configPaths.d.ts +85 -0
  95. package/dist/utils/configPaths.d.ts.map +1 -0
  96. package/dist/utils/configPaths.js +121 -0
  97. package/dist/utils/configResolver.d.ts +37 -10
  98. package/dist/utils/configResolver.d.ts.map +1 -1
  99. package/dist/utils/configResolver.js +127 -23
  100. package/dist/utils/constants.d.ts +1 -1
  101. package/dist/utils/constants.js +1 -1
  102. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  103. package/dist/utils/convertMessagesForAPI.js +7 -5
  104. package/dist/utils/customCommands.d.ts.map +1 -1
  105. package/dist/utils/customCommands.js +66 -21
  106. package/dist/utils/fileUtils.d.ts +15 -0
  107. package/dist/utils/fileUtils.d.ts.map +1 -0
  108. package/dist/utils/fileUtils.js +61 -0
  109. package/dist/utils/globalLogger.d.ts +102 -0
  110. package/dist/utils/globalLogger.d.ts.map +1 -0
  111. package/dist/utils/globalLogger.js +136 -0
  112. package/dist/utils/mcpUtils.d.ts.map +1 -1
  113. package/dist/utils/mcpUtils.js +25 -3
  114. package/dist/utils/messageOperations.d.ts +20 -8
  115. package/dist/utils/messageOperations.d.ts.map +1 -1
  116. package/dist/utils/messageOperations.js +25 -16
  117. package/dist/utils/pathEncoder.d.ts +104 -0
  118. package/dist/utils/pathEncoder.d.ts.map +1 -0
  119. package/dist/utils/pathEncoder.js +272 -0
  120. package/dist/utils/subagentParser.d.ts.map +1 -1
  121. package/dist/utils/subagentParser.js +2 -1
  122. package/dist/utils/tokenCalculation.d.ts +26 -0
  123. package/dist/utils/tokenCalculation.d.ts.map +1 -0
  124. package/dist/utils/tokenCalculation.js +36 -0
  125. package/package.json +6 -3
  126. package/src/agent.ts +298 -34
  127. package/src/constants/events.ts +38 -0
  128. package/src/index.ts +2 -0
  129. package/src/managers/aiManager.ts +323 -170
  130. package/src/managers/backgroundBashManager.ts +7 -6
  131. package/src/managers/hookManager.ts +83 -40
  132. package/src/managers/liveConfigManager.ts +248 -0
  133. package/src/managers/messageManager.ts +230 -63
  134. package/src/managers/slashCommandManager.ts +4 -1
  135. package/src/managers/subagentManager.ts +283 -21
  136. package/src/services/aiService.ts +474 -83
  137. package/src/services/configurationWatcher.ts +622 -0
  138. package/src/services/fileWatcher.ts +301 -0
  139. package/src/services/hook.ts +538 -47
  140. package/src/services/jsonlHandler.ts +319 -0
  141. package/src/services/memory.ts +92 -12
  142. package/src/services/memoryStore.ts +279 -0
  143. package/src/services/session.ts +381 -157
  144. package/src/tools/bashTool.ts +5 -4
  145. package/src/tools/deleteFileTool.ts +2 -1
  146. package/src/tools/editTool.ts +3 -2
  147. package/src/tools/multiEditTool.ts +4 -3
  148. package/src/tools/readTool.ts +2 -1
  149. package/src/tools/writeTool.ts +7 -6
  150. package/src/types/commands.ts +6 -0
  151. package/src/types/core.ts +44 -0
  152. package/src/types/environment.ts +60 -0
  153. package/src/types/hooks.ts +21 -8
  154. package/src/types/index.ts +2 -0
  155. package/src/types/memoryStore.ts +94 -0
  156. package/src/types/messaging.ts +14 -2
  157. package/src/types/session.ts +25 -0
  158. package/src/utils/bashHistory.ts +27 -27
  159. package/src/utils/cacheControlUtils.ts +540 -0
  160. package/src/utils/commandPathResolver.ts +189 -0
  161. package/src/utils/configPaths.ts +163 -0
  162. package/src/utils/configResolver.ts +182 -22
  163. package/src/utils/constants.ts +1 -1
  164. package/src/utils/convertMessagesForAPI.ts +7 -5
  165. package/src/utils/customCommands.ts +90 -22
  166. package/src/utils/fileUtils.ts +65 -0
  167. package/src/utils/globalLogger.ts +145 -0
  168. package/src/utils/mcpUtils.ts +34 -3
  169. package/src/utils/messageOperations.ts +42 -20
  170. package/src/utils/pathEncoder.ts +379 -0
  171. package/src/utils/subagentParser.ts +2 -1
  172. package/src/utils/tokenCalculation.ts +43 -0
@@ -0,0 +1,301 @@
1
+ /**
2
+ * File Watcher Service
3
+ *
4
+ * Provides robust cross-platform file watching using Chokidar library.
5
+ * Handles file watching with debouncing, error recovery, and graceful fallbacks.
6
+ */
7
+
8
+ import * as chokidar from "chokidar";
9
+ import { EventEmitter } from "events";
10
+ import type { Logger } from "../types/index.js";
11
+ import { FILE_WATCHER_EVENTS } from "../constants/events.js";
12
+
13
+ export interface FileWatchEvent {
14
+ type: "change" | "create" | "delete" | "rename";
15
+ path: string;
16
+ timestamp: number;
17
+ size?: number;
18
+ }
19
+
20
+ export interface FileWatcherConfig {
21
+ stabilityThreshold: number; // Chokidar awaitWriteFinish delay (ms)
22
+ pollInterval: number; // Chokidar polling interval (ms)
23
+ maxRetries: number; // Default: 3
24
+ fallbackPolling: boolean; // Default: false
25
+ ignoreTempFiles: boolean; // Default: true
26
+ }
27
+
28
+ export interface FileWatcherStatus {
29
+ isActive: boolean;
30
+ path: string;
31
+ method: "native" | "polling" | "failed";
32
+ errorCount: number;
33
+ lastError?: string;
34
+ lastEvent?: FileWatchEvent;
35
+ }
36
+
37
+ interface FileWatcherEntry {
38
+ path: string;
39
+ watcher: chokidar.FSWatcher | null;
40
+ isActive: boolean;
41
+ lastEvent: number;
42
+ errorCount: number;
43
+ lastError?: string;
44
+ callbacks: Set<(event: FileWatchEvent) => void>;
45
+ config: FileWatcherConfig;
46
+ }
47
+
48
+ export class FileWatcherService extends EventEmitter {
49
+ private watchers: Map<string, FileWatcherEntry> = new Map();
50
+ private globalWatcher: chokidar.FSWatcher | null = null;
51
+ private defaultConfig: FileWatcherConfig;
52
+ private logger?: Logger;
53
+
54
+ constructor(logger?: Logger, config?: Partial<FileWatcherConfig>) {
55
+ super();
56
+ this.logger = logger;
57
+ this.defaultConfig = {
58
+ stabilityThreshold: 300,
59
+ pollInterval: 100,
60
+ maxRetries: 3,
61
+ fallbackPolling: false,
62
+ ignoreTempFiles: true,
63
+ ...config,
64
+ };
65
+ }
66
+
67
+ /**
68
+ * Start watching a file
69
+ * Maps to FR-010: Handle file deletion, creation, and modification
70
+ */
71
+ async watchFile(
72
+ path: string,
73
+ callback: (event: FileWatchEvent) => void,
74
+ ): Promise<void> {
75
+ try {
76
+ if (this.watchers.has(path)) {
77
+ // Add callback to existing watcher
78
+ const entry = this.watchers.get(path)!;
79
+ entry.callbacks.add(callback);
80
+ return;
81
+ }
82
+
83
+ // Create new watcher entry
84
+ const entry: FileWatcherEntry = {
85
+ path,
86
+ watcher: null,
87
+ isActive: false,
88
+ lastEvent: Date.now(),
89
+ errorCount: 0,
90
+ lastError: undefined,
91
+ callbacks: new Set([callback]),
92
+ config: { ...this.defaultConfig },
93
+ };
94
+
95
+ this.watchers.set(path, entry);
96
+ await this.initializeWatcher(entry);
97
+ } catch (error) {
98
+ this.logger?.error(
99
+ `Live Config: Failed to watch file ${path}: ${(error as Error).message}`,
100
+ );
101
+ throw error;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Stop watching a file
107
+ * Resource cleanup
108
+ */
109
+ async unwatchFile(path: string): Promise<void> {
110
+ const entry = this.watchers.get(path);
111
+ if (!entry) return;
112
+
113
+ try {
114
+ if (entry.watcher) {
115
+ entry.watcher.unwatch(path);
116
+ }
117
+
118
+ this.watchers.delete(path);
119
+ this.logger?.info(`Live Config: Stopped watching file: ${path}`);
120
+ } catch (error) {
121
+ this.logger?.warn(
122
+ `Live Config: Error unwatching file ${path}: ${(error as Error).message}`,
123
+ );
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Get watcher status
129
+ * Maps to FR-012: Handle watcher initialization failures
130
+ */
131
+ getWatcherStatus(path: string): FileWatcherStatus | null {
132
+ const entry = this.watchers.get(path);
133
+ if (!entry) return null;
134
+
135
+ return {
136
+ isActive: entry.isActive,
137
+ path: entry.path,
138
+ method:
139
+ entry.errorCount > 0
140
+ ? "failed"
141
+ : entry.config.fallbackPolling
142
+ ? "polling"
143
+ : "native",
144
+ errorCount: entry.errorCount,
145
+ lastError: entry.lastError,
146
+ lastEvent:
147
+ entry.lastEvent > 0
148
+ ? {
149
+ type: FILE_WATCHER_EVENTS.CHANGE,
150
+ path: entry.path,
151
+ timestamp: entry.lastEvent,
152
+ }
153
+ : undefined,
154
+ };
155
+ }
156
+
157
+ /**
158
+ * Get all watcher statuses
159
+ * For monitoring and debugging
160
+ */
161
+ getAllWatcherStatuses(): FileWatcherStatus[] {
162
+ return Array.from(this.watchers.keys())
163
+ .map((path) => this.getWatcherStatus(path))
164
+ .filter((status): status is FileWatcherStatus => status !== null);
165
+ }
166
+
167
+ /**
168
+ * Configure watcher behavior
169
+ * Runtime configuration updates
170
+ */
171
+ updateConfig(config: Partial<FileWatcherConfig>): void {
172
+ this.defaultConfig = { ...this.defaultConfig, ...config };
173
+
174
+ // Update existing watchers with new config
175
+ for (const entry of this.watchers.values()) {
176
+ entry.config = { ...entry.config, ...config };
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Cleanup all watchers
182
+ */
183
+ async cleanup(): Promise<void> {
184
+ const paths = Array.from(this.watchers.keys());
185
+ await Promise.all(paths.map((path) => this.unwatchFile(path)));
186
+
187
+ if (this.globalWatcher) {
188
+ await this.globalWatcher.close();
189
+ this.globalWatcher = null;
190
+ }
191
+ }
192
+
193
+ private async initializeWatcher(entry: FileWatcherEntry): Promise<void> {
194
+ try {
195
+ // Initialize global watcher if needed
196
+ if (!this.globalWatcher) {
197
+ this.globalWatcher = chokidar.watch([], {
198
+ persistent: true,
199
+ ignoreInitial: true,
200
+ awaitWriteFinish: {
201
+ stabilityThreshold: entry.config.stabilityThreshold,
202
+ pollInterval: entry.config.pollInterval,
203
+ },
204
+ usePolling: entry.config.fallbackPolling,
205
+ interval: entry.config.pollInterval,
206
+ });
207
+
208
+ this.setupGlobalWatcherEvents();
209
+ }
210
+
211
+ // Add path to global watcher
212
+ this.globalWatcher.add(entry.path);
213
+ entry.watcher = this.globalWatcher;
214
+ entry.isActive = true;
215
+ entry.errorCount = 0;
216
+
217
+ this.logger?.info(`Live Config: Started watching file: ${entry.path}`);
218
+ } catch (error) {
219
+ entry.errorCount++;
220
+ entry.isActive = false;
221
+ entry.lastError = (error as Error).message;
222
+
223
+ this.logger?.error(
224
+ `Live Config: Failed to initialize watcher for ${entry.path}: ${(error as Error).message}`,
225
+ );
226
+
227
+ // Try fallback polling if not already using it
228
+ if (
229
+ !entry.config.fallbackPolling &&
230
+ entry.errorCount < entry.config.maxRetries
231
+ ) {
232
+ this.logger?.info(
233
+ `Live Config: Attempting polling fallback for ${entry.path}`,
234
+ );
235
+ entry.config.fallbackPolling = true;
236
+ await this.initializeWatcher(entry);
237
+ } else {
238
+ throw error;
239
+ }
240
+ }
241
+ }
242
+
243
+ private setupGlobalWatcherEvents(): void {
244
+ if (!this.globalWatcher) return;
245
+
246
+ this.globalWatcher.on(
247
+ FILE_WATCHER_EVENTS.CHANGE,
248
+ (filePath: string, stats?: { size?: number }) => {
249
+ this.handleFileEvent(FILE_WATCHER_EVENTS.CHANGE, filePath, stats);
250
+ },
251
+ );
252
+
253
+ this.globalWatcher.on(
254
+ "add",
255
+ (filePath: string, stats?: { size?: number }) => {
256
+ this.handleFileEvent(FILE_WATCHER_EVENTS.CREATE, filePath, stats);
257
+ },
258
+ );
259
+
260
+ this.globalWatcher.on("unlink", (filePath: string) => {
261
+ this.handleFileEvent(FILE_WATCHER_EVENTS.DELETE, filePath);
262
+ });
263
+
264
+ this.globalWatcher.on("error", (err: unknown) => {
265
+ const error = err instanceof Error ? err : new Error(String(err));
266
+ this.logger?.error(`Live Config: File watcher error: ${error.message}`);
267
+ this.emit("watcherError", error);
268
+ });
269
+ }
270
+
271
+ private handleFileEvent(
272
+ type: FileWatchEvent["type"],
273
+ filePath: string,
274
+ stats?: { size?: number },
275
+ ): void {
276
+ const entry = this.watchers.get(filePath);
277
+ if (!entry) return;
278
+
279
+ const event: FileWatchEvent = {
280
+ type,
281
+ path: filePath,
282
+ timestamp: Date.now(),
283
+ size: stats?.size,
284
+ };
285
+
286
+ entry.lastEvent = event.timestamp;
287
+
288
+ // Notify all callbacks for this file
289
+ for (const callback of entry.callbacks) {
290
+ try {
291
+ callback(event);
292
+ } catch (error) {
293
+ this.logger?.error(
294
+ `Live Config: Error in file watch callback for ${filePath}: ${(error as Error).message}`,
295
+ );
296
+ }
297
+ }
298
+
299
+ this.logger?.debug(`Live Config: File ${type} event for ${filePath}`);
300
+ }
301
+ }