wave-agent-sdk 0.0.6 → 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 (180) hide show
  1. package/dist/agent.d.ts +32 -20
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +209 -24
  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 +248 -132
  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 +13 -16
  16. package/dist/managers/hookManager.d.ts.map +1 -1
  17. package/dist/managers/hookManager.js +81 -44
  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 +41 -24
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +168 -49
  24. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  25. package/dist/managers/slashCommandManager.js +9 -3
  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 +190 -19
  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/todoWriteTool.d.ts.map +1 -1
  64. package/dist/tools/todoWriteTool.js +3 -10
  65. package/dist/tools/writeTool.d.ts.map +1 -1
  66. package/dist/tools/writeTool.js +5 -6
  67. package/dist/types/commands.d.ts +4 -0
  68. package/dist/types/commands.d.ts.map +1 -1
  69. package/dist/types/core.d.ts +35 -0
  70. package/dist/types/core.d.ts.map +1 -1
  71. package/dist/types/environment.d.ts +42 -0
  72. package/dist/types/environment.d.ts.map +1 -0
  73. package/dist/types/environment.js +21 -0
  74. package/dist/types/hooks.d.ts +8 -2
  75. package/dist/types/hooks.d.ts.map +1 -1
  76. package/dist/types/hooks.js +8 -2
  77. package/dist/types/index.d.ts +2 -0
  78. package/dist/types/index.d.ts.map +1 -1
  79. package/dist/types/index.js +2 -0
  80. package/dist/types/memoryStore.d.ts +82 -0
  81. package/dist/types/memoryStore.d.ts.map +1 -0
  82. package/dist/types/memoryStore.js +7 -0
  83. package/dist/types/messaging.d.ts +21 -9
  84. package/dist/types/messaging.d.ts.map +1 -1
  85. package/dist/types/messaging.js +5 -1
  86. package/dist/types/session.d.ts +20 -0
  87. package/dist/types/session.d.ts.map +1 -0
  88. package/dist/types/session.js +7 -0
  89. package/dist/utils/bashHistory.d.ts.map +1 -1
  90. package/dist/utils/bashHistory.js +27 -26
  91. package/dist/utils/cacheControlUtils.d.ts +121 -0
  92. package/dist/utils/cacheControlUtils.d.ts.map +1 -0
  93. package/dist/utils/cacheControlUtils.js +367 -0
  94. package/dist/utils/commandPathResolver.d.ts +52 -0
  95. package/dist/utils/commandPathResolver.d.ts.map +1 -0
  96. package/dist/utils/commandPathResolver.js +145 -0
  97. package/dist/utils/configPaths.d.ts +85 -0
  98. package/dist/utils/configPaths.d.ts.map +1 -0
  99. package/dist/utils/configPaths.js +121 -0
  100. package/dist/utils/configResolver.d.ts +37 -10
  101. package/dist/utils/configResolver.d.ts.map +1 -1
  102. package/dist/utils/configResolver.js +127 -23
  103. package/dist/utils/constants.d.ts +1 -1
  104. package/dist/utils/constants.js +1 -1
  105. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  106. package/dist/utils/convertMessagesForAPI.js +8 -13
  107. package/dist/utils/customCommands.d.ts.map +1 -1
  108. package/dist/utils/customCommands.js +66 -21
  109. package/dist/utils/fileUtils.d.ts +15 -0
  110. package/dist/utils/fileUtils.d.ts.map +1 -0
  111. package/dist/utils/fileUtils.js +61 -0
  112. package/dist/utils/globalLogger.d.ts +102 -0
  113. package/dist/utils/globalLogger.d.ts.map +1 -0
  114. package/dist/utils/globalLogger.js +136 -0
  115. package/dist/utils/hookMatcher.d.ts +1 -6
  116. package/dist/utils/hookMatcher.d.ts.map +1 -1
  117. package/dist/utils/mcpUtils.d.ts.map +1 -1
  118. package/dist/utils/mcpUtils.js +25 -3
  119. package/dist/utils/messageOperations.d.ts +27 -27
  120. package/dist/utils/messageOperations.d.ts.map +1 -1
  121. package/dist/utils/messageOperations.js +46 -36
  122. package/dist/utils/pathEncoder.d.ts +104 -0
  123. package/dist/utils/pathEncoder.d.ts.map +1 -0
  124. package/dist/utils/pathEncoder.js +272 -0
  125. package/dist/utils/subagentParser.d.ts.map +1 -1
  126. package/dist/utils/subagentParser.js +2 -1
  127. package/dist/utils/tokenCalculation.d.ts +26 -0
  128. package/dist/utils/tokenCalculation.d.ts.map +1 -0
  129. package/dist/utils/tokenCalculation.js +36 -0
  130. package/package.json +6 -3
  131. package/src/agent.ts +301 -37
  132. package/src/constants/events.ts +38 -0
  133. package/src/index.ts +2 -0
  134. package/src/managers/aiManager.ts +325 -173
  135. package/src/managers/backgroundBashManager.ts +7 -6
  136. package/src/managers/hookManager.ts +106 -84
  137. package/src/managers/liveConfigManager.ts +248 -0
  138. package/src/managers/messageManager.ts +237 -100
  139. package/src/managers/slashCommandManager.ts +9 -7
  140. package/src/managers/subagentManager.ts +284 -22
  141. package/src/services/aiService.ts +474 -83
  142. package/src/services/configurationWatcher.ts +622 -0
  143. package/src/services/fileWatcher.ts +301 -0
  144. package/src/services/hook.ts +538 -47
  145. package/src/services/jsonlHandler.ts +319 -0
  146. package/src/services/memory.ts +92 -12
  147. package/src/services/memoryStore.ts +279 -0
  148. package/src/services/session.ts +381 -157
  149. package/src/tools/bashTool.ts +5 -4
  150. package/src/tools/deleteFileTool.ts +2 -1
  151. package/src/tools/editTool.ts +3 -2
  152. package/src/tools/multiEditTool.ts +4 -3
  153. package/src/tools/readTool.ts +2 -1
  154. package/src/tools/todoWriteTool.ts +3 -11
  155. package/src/tools/writeTool.ts +7 -6
  156. package/src/types/commands.ts +6 -0
  157. package/src/types/core.ts +44 -0
  158. package/src/types/environment.ts +60 -0
  159. package/src/types/hooks.ts +21 -8
  160. package/src/types/index.ts +2 -0
  161. package/src/types/memoryStore.ts +94 -0
  162. package/src/types/messaging.ts +21 -10
  163. package/src/types/session.ts +25 -0
  164. package/src/utils/bashHistory.ts +27 -27
  165. package/src/utils/cacheControlUtils.ts +540 -0
  166. package/src/utils/commandPathResolver.ts +189 -0
  167. package/src/utils/configPaths.ts +163 -0
  168. package/src/utils/configResolver.ts +182 -22
  169. package/src/utils/constants.ts +1 -1
  170. package/src/utils/convertMessagesForAPI.ts +8 -14
  171. package/src/utils/customCommands.ts +90 -22
  172. package/src/utils/fileUtils.ts +65 -0
  173. package/src/utils/globalLogger.ts +145 -0
  174. package/src/utils/hookMatcher.ts +1 -12
  175. package/src/utils/mcpUtils.ts +34 -3
  176. package/src/utils/messageOperations.ts +77 -60
  177. package/src/utils/pathEncoder.ts +379 -0
  178. package/src/utils/subagentParser.ts +2 -1
  179. package/src/utils/tokenCalculation.ts +43 -0
  180. package/src/types/index.ts.backup +0 -357
@@ -4,24 +4,17 @@
4
4
  * Central orchestrator for the hooks system. Handles configuration loading,
5
5
  * validation, and hook execution across all supported events.
6
6
  */
7
- import { type HookEvent, type HookConfiguration, type PartialHookConfiguration, type HookExecutionContext, type ExtendedHookExecutionContext, type HookExecutionResult, type ValidationResult } from "../types/hooks.js";
8
- import { type IHookMatcher } from "../utils/hookMatcher.js";
7
+ import { type HookEvent, type WaveConfiguration, type PartialHookConfiguration, type HookExecutionContext, type ExtendedHookExecutionContext, type HookExecutionResult, type ValidationResult } from "../types/hooks.js";
8
+ import { HookMatcher } from "../utils/hookMatcher.js";
9
9
  import type { Logger } from "../types/index.js";
10
10
  import type { MessageManager } from "./messageManager.js";
11
- export interface IHookManager {
12
- loadConfiguration(userHooks?: PartialHookConfiguration, projectHooks?: PartialHookConfiguration): void;
13
- loadConfigurationFromSettings(): void;
14
- executeHooks(event: HookEvent, context: HookExecutionContext | ExtendedHookExecutionContext): Promise<HookExecutionResult[]>;
15
- hasHooks(event: HookEvent, toolName?: string): boolean;
16
- validateConfiguration(config: HookConfiguration): ValidationResult;
17
- getConfiguration(): PartialHookConfiguration | undefined;
18
- }
19
- export declare class HookManager implements IHookManager {
11
+ export declare class HookManager {
20
12
  private configuration;
13
+ private environmentVars;
21
14
  private readonly matcher;
22
15
  private readonly logger?;
23
16
  private readonly workdir;
24
- constructor(workdir: string, matcher?: IHookMatcher, logger?: Logger);
17
+ constructor(workdir: string, matcher?: HookMatcher, logger?: Logger);
25
18
  /**
26
19
  * Load and merge hook configurations from user and project settings
27
20
  * Project settings take precedence over user settings
@@ -29,7 +22,7 @@ export declare class HookManager implements IHookManager {
29
22
  loadConfiguration(userHooks?: PartialHookConfiguration, projectHooks?: PartialHookConfiguration): void;
30
23
  /**
31
24
  * Load configuration from filesystem settings
32
- * Automatically loads and merges user and project hooks configuration
25
+ * Automatically loads and merges user and project Wave configuration (hooks + environment)
33
26
  */
34
27
  loadConfigurationFromSettings(): void;
35
28
  /**
@@ -40,7 +33,7 @@ export declare class HookManager implements IHookManager {
40
33
  * Process hook execution results and determine appropriate actions
41
34
  * based on exit codes and hook event type
42
35
  */
43
- processHookResults(event: HookEvent, results: HookExecutionResult[], messageManager?: MessageManager, toolId?: string, originalToolResult?: string): {
36
+ processHookResults(event: HookEvent, results: HookExecutionResult[], messageManager?: MessageManager, toolId?: string, toolParameters?: string): {
44
37
  shouldBlock: boolean;
45
38
  errorMessage?: string;
46
39
  };
@@ -61,9 +54,9 @@ export declare class HookManager implements IHookManager {
61
54
  */
62
55
  hasHooks(event: HookEvent, toolName?: string): boolean;
63
56
  /**
64
- * Validate hook configuration structure and content
57
+ * Validate Wave configuration structure and content
65
58
  */
66
- validateConfiguration(config: HookConfiguration): ValidationResult;
59
+ validateConfiguration(config: WaveConfiguration): ValidationResult;
67
60
  /**
68
61
  * Validate partial hook configuration structure and content
69
62
  */
@@ -72,6 +65,10 @@ export declare class HookManager implements IHookManager {
72
65
  * Get current configuration
73
66
  */
74
67
  getConfiguration(): PartialHookConfiguration | undefined;
68
+ /**
69
+ * Get current environment variables
70
+ */
71
+ getEnvironmentVars(): Record<string, string> | undefined;
75
72
  /**
76
73
  * Clear current configuration
77
74
  */
@@ -1 +1 @@
1
- {"version":3,"file":"hookManager.d.ts","sourceRoot":"","sources":["../../src/managers/hookManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,YAAY,EAAe,MAAM,yBAAyB,CAAC;AAMzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,WAAW,YAAY;IAE3B,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI,CAAC;IAGR,6BAA6B,IAAI,IAAI,CAAC;IAGtC,YAAY,CACV,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,GAC3D,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAGlC,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAGvD,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB,CAAC;IAGnE,gBAAgB,IAAI,wBAAwB,GAAG,SAAS,CAAC;CAC1D;AAED,qBAAa,WAAY,YAAW,YAAY;IAC9C,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAgC,EACzC,MAAM,CAAC,EAAE,MAAM;IAOjB;;;OAGG;IACH,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI;IAyBP;;;OAGG;IACH,6BAA6B,IAAI,IAAI;IAqCrC;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,GAC3D,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAqHjC;;;OAGG;IACH,kBAAkB,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,cAAc,CAAC,EAAE,cAAc,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,kBAAkB,CAAC,EAAE,MAAM,GAC1B;QACD,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAuCD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAuD3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAWtD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;IA8ClE;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAyCpC;;OAEG;IACH,gBAAgB,IAAI,wBAAwB,GAAG,SAAS;IAOxD;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAmDhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAa/B;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqC3B;;OAEG;IACH,qBAAqB,IAAI;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KAC3C;CA2CF"}
1
+ {"version":3,"file":"hookManager.d.ts","sourceRoot":"","sources":["../../src/managers/hookManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,qBAAa,WAAW;IACtB,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAA+B,EACxC,MAAM,CAAC,EAAE,MAAM;IAOjB;;;OAGG;IACH,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI;IAyBP;;;OAGG;IACH,6BAA6B,IAAI,IAAI;IA6CrC;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,GAC3D,OAAO,CAAC,mBAAmB,EAAE,CAAC;IA0HjC;;;OAGG;IACH,kBAAkB,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,cAAc,CAAC,EAAE,cAAc,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB;QACD,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAuCD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyD3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAWtD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;IA8DlE;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAyCpC;;OAEG;IACH,gBAAgB,IAAI,wBAAwB,GAAG,SAAS;IAOxD;;OAEG;IACH,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAOxD;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAmDhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAa/B;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqC3B;;OAEG;IACH,qBAAqB,IAAI;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KAC3C;CA6CF"}
@@ -6,7 +6,8 @@
6
6
  */
7
7
  import { HookConfigurationError, isValidHookEvent, isValidHookEventConfig, } from "../types/hooks.js";
8
8
  import { HookMatcher } from "../utils/hookMatcher.js";
9
- import { executeCommand, isCommandSafe, loadMergedHooksConfig, } from "../services/hook.js";
9
+ import { executeCommand, isCommandSafe, loadMergedWaveConfig, } from "../services/hook.js";
10
+ import { MessageSource } from "../types/index.js";
10
11
  export class HookManager {
11
12
  constructor(workdir, matcher = new HookMatcher(), logger) {
12
13
  this.workdir = workdir;
@@ -36,26 +37,28 @@ export class HookManager {
36
37
  }
37
38
  /**
38
39
  * Load configuration from filesystem settings
39
- * Automatically loads and merges user and project hooks configuration
40
+ * Automatically loads and merges user and project Wave configuration (hooks + environment)
40
41
  */
41
42
  loadConfigurationFromSettings() {
42
43
  try {
43
44
  this.logger?.debug(`[HookManager] Loading configuration...`);
44
- const mergedConfig = loadMergedHooksConfig(this.workdir);
45
- this.logger?.debug(`[HookManager] Merged config result:`, mergedConfig);
46
- this.configuration = mergedConfig || undefined;
45
+ const mergedWaveConfig = loadMergedWaveConfig(this.workdir);
46
+ this.logger?.debug(`[HookManager] Merged config result:`, mergedWaveConfig);
47
+ this.configuration = mergedWaveConfig?.hooks || undefined;
48
+ this.environmentVars = mergedWaveConfig?.env || undefined;
47
49
  // Validate the loaded configuration if it exists
48
- if (mergedConfig) {
49
- const validation = this.validatePartialConfiguration(mergedConfig);
50
+ if (mergedWaveConfig?.hooks) {
51
+ const validation = this.validatePartialConfiguration(mergedWaveConfig.hooks);
50
52
  if (!validation.valid) {
51
53
  throw new HookConfigurationError("filesystem settings", validation.errors);
52
54
  }
53
55
  }
54
- this.logger?.debug(`[HookManager] Configuration loaded successfully with ${Object.keys(mergedConfig || {}).length} event types`);
56
+ this.logger?.debug(`[HookManager] Configuration loaded successfully with ${Object.keys(mergedWaveConfig?.hooks || {}).length} event types and ${Object.keys(this.environmentVars || {}).length} environment variables`);
55
57
  }
56
58
  catch (error) {
57
59
  // If loading fails, start with undefined configuration (no hooks)
58
60
  this.configuration = undefined;
61
+ this.environmentVars = undefined;
59
62
  // Re-throw configuration errors, but handle file system errors gracefully
60
63
  if (error instanceof HookConfigurationError) {
61
64
  throw error;
@@ -107,14 +110,14 @@ export class HookManager {
107
110
  const hookCommand = config.hooks[commandIndex];
108
111
  try {
109
112
  this.logger?.debug(`[HookManager] Executing command ${commandIndex + 1}/${config.hooks.length} in configuration ${configIndex + 1}`);
110
- const result = await executeCommand(hookCommand.command, context);
113
+ const result = await executeCommand(hookCommand.command, context, undefined, this.environmentVars);
111
114
  results.push(result);
112
115
  // Report individual command result
113
116
  if (result.success) {
114
117
  this.logger?.debug(`[HookManager] Command ${commandIndex + 1} completed successfully in ${result.duration}ms`);
115
118
  }
116
119
  else {
117
- this.logger?.warn(`[HookManager] Command ${commandIndex + 1} failed in ${result.duration}ms (exit code: ${result.exitCode}, timed out: ${result.timedOut})`);
120
+ this.logger?.debug(`[HookManager] Command ${commandIndex + 1} failed in ${result.duration}ms (exit code: ${result.exitCode}, timed out: ${result.timedOut})`);
118
121
  }
119
122
  // Continue with next command even if this one fails
120
123
  // This allows for non-critical hooks to fail without stopping the workflow
@@ -142,7 +145,7 @@ export class HookManager {
142
145
  * Process hook execution results and determine appropriate actions
143
146
  * based on exit codes and hook event type
144
147
  */
145
- processHookResults(event, results, messageManager, toolId, originalToolResult) {
148
+ processHookResults(event, results, messageManager, toolId, toolParameters) {
146
149
  if (!messageManager || results.length === 0) {
147
150
  return { shouldBlock: false };
148
151
  }
@@ -151,7 +154,7 @@ export class HookManager {
151
154
  for (const result of results) {
152
155
  if (result.exitCode === 2) {
153
156
  // Handle blocking error immediately and return
154
- return this.handleBlockingError(event, result, messageManager, toolId, originalToolResult);
157
+ return this.handleBlockingError(event, result, messageManager, toolId, toolParameters);
155
158
  }
156
159
  }
157
160
  // Second pass: Process all non-blocking results
@@ -177,14 +180,17 @@ export class HookManager {
177
180
  handleHookSuccess(event, result, messageManager) {
178
181
  if (event === "UserPromptSubmit" && result.stdout?.trim()) {
179
182
  // Inject stdout as user message context for UserPromptSubmit
180
- messageManager.addUserMessage(result.stdout.trim());
183
+ messageManager.addUserMessage({
184
+ content: result.stdout.trim(),
185
+ source: MessageSource.HOOK,
186
+ });
181
187
  }
182
188
  // For other hook types (PreToolUse, PostToolUse, Stop), ignore stdout
183
189
  }
184
190
  /**
185
191
  * Handle blocking error (exit code 2) - behavior varies by hook type
186
192
  */
187
- handleBlockingError(event, result, messageManager, toolId, originalToolResult) {
193
+ handleBlockingError(event, result, messageManager, toolId, toolParameters) {
188
194
  const errorMessage = result.stderr?.trim() || "Hook execution failed";
189
195
  switch (event) {
190
196
  case "UserPromptSubmit":
@@ -199,26 +205,28 @@ export class HookManager {
199
205
  // Block tool execution and show error to Wave Agent via tool block
200
206
  if (toolId) {
201
207
  messageManager.updateToolBlock({
202
- toolId,
208
+ id: toolId,
209
+ parameters: toolParameters || "",
203
210
  result: errorMessage,
204
211
  success: false,
205
212
  error: "Hook blocked tool execution",
213
+ stage: "end", // Hook blocking results in end stage with error
206
214
  });
207
215
  }
208
216
  return { shouldBlock: true };
209
217
  case "PostToolUse":
210
- // Show error to Wave Agent via tool block, execution continues
211
- if (toolId && originalToolResult !== undefined) {
212
- messageManager.updateToolBlock({
213
- toolId,
214
- result: `${originalToolResult}\n\nHook feedback: ${errorMessage}`,
215
- success: false,
216
- });
217
- }
218
+ // Show error to Wave Agent via user message and allow AI to continue
219
+ messageManager.addUserMessage({
220
+ content: errorMessage,
221
+ source: MessageSource.HOOK,
222
+ });
218
223
  return { shouldBlock: false };
219
224
  case "Stop":
220
225
  // Show error to Wave Agent via user message and block stopping to continue conversation
221
- messageManager.addUserMessage(errorMessage);
226
+ messageManager.addUserMessage({
227
+ content: errorMessage,
228
+ source: MessageSource.HOOK,
229
+ });
222
230
  return { shouldBlock: true, errorMessage };
223
231
  default:
224
232
  return { shouldBlock: false };
@@ -243,35 +251,53 @@ export class HookManager {
243
251
  return eventConfigs.some((config) => this.configApplies(config, event, toolName));
244
252
  }
245
253
  /**
246
- * Validate hook configuration structure and content
254
+ * Validate Wave configuration structure and content
247
255
  */
248
256
  validateConfiguration(config) {
249
257
  const errors = [];
250
258
  if (!config || typeof config !== "object") {
251
259
  return { valid: false, errors: ["Configuration must be an object"] };
252
260
  }
253
- if (!config.hooks || typeof config.hooks !== "object") {
254
- return {
255
- valid: false,
256
- errors: ["Configuration must have a hooks property"],
257
- };
261
+ // Validate hooks if present
262
+ if (config.hooks) {
263
+ if (typeof config.hooks !== "object") {
264
+ errors.push("hooks property must be an object");
265
+ }
266
+ else {
267
+ // Validate each hook event
268
+ for (const [eventName, eventConfigs] of Object.entries(config.hooks)) {
269
+ // Validate event name
270
+ if (!isValidHookEvent(eventName)) {
271
+ errors.push(`Invalid hook event: ${eventName}`);
272
+ continue;
273
+ }
274
+ // Validate event configurations
275
+ if (!Array.isArray(eventConfigs)) {
276
+ errors.push(`Hook event ${eventName} must be an array of configurations`);
277
+ continue;
278
+ }
279
+ eventConfigs.forEach((eventConfig, index) => {
280
+ const configErrors = this.validateEventConfig(eventName, eventConfig, index);
281
+ errors.push(...configErrors);
282
+ });
283
+ }
284
+ }
258
285
  }
259
- // Validate each hook event
260
- for (const [eventName, eventConfigs] of Object.entries(config.hooks)) {
261
- // Validate event name
262
- if (!isValidHookEvent(eventName)) {
263
- errors.push(`Invalid hook event: ${eventName}`);
264
- continue;
286
+ // Validate environment variables if present
287
+ if (config.env) {
288
+ if (typeof config.env !== "object" || Array.isArray(config.env)) {
289
+ errors.push("env property must be an object");
265
290
  }
266
- // Validate event configurations
267
- if (!Array.isArray(eventConfigs)) {
268
- errors.push(`Hook event ${eventName} must be an array of configurations`);
269
- continue;
291
+ else {
292
+ for (const [key, value] of Object.entries(config.env)) {
293
+ if (typeof key !== "string" || key.trim() === "") {
294
+ errors.push(`Invalid environment variable key: ${key}`);
295
+ }
296
+ if (typeof value !== "string") {
297
+ errors.push(`Environment variable ${key} must have a string value`);
298
+ }
299
+ }
270
300
  }
271
- eventConfigs.forEach((eventConfig, index) => {
272
- const configErrors = this.validateEventConfig(eventName, eventConfig, index);
273
- errors.push(...configErrors);
274
- });
275
301
  }
276
302
  return {
277
303
  valid: errors.length === 0,
@@ -317,6 +343,15 @@ export class HookManager {
317
343
  // Deep clone to prevent external modification
318
344
  return JSON.parse(JSON.stringify(this.configuration));
319
345
  }
346
+ /**
347
+ * Get current environment variables
348
+ */
349
+ getEnvironmentVars() {
350
+ if (!this.environmentVars)
351
+ return undefined;
352
+ // Deep clone to prevent external modification
353
+ return JSON.parse(JSON.stringify(this.environmentVars));
354
+ }
320
355
  /**
321
356
  * Clear current configuration
322
357
  */
@@ -457,6 +492,7 @@ export class HookManager {
457
492
  PostToolUse: 0,
458
493
  UserPromptSubmit: 0,
459
494
  Stop: 0,
495
+ SubagentStop: 0,
460
496
  },
461
497
  };
462
498
  }
@@ -465,6 +501,7 @@ export class HookManager {
465
501
  PostToolUse: 0,
466
502
  UserPromptSubmit: 0,
467
503
  Stop: 0,
504
+ SubagentStop: 0,
468
505
  };
469
506
  let totalConfigs = 0;
470
507
  let totalCommands = 0;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Live Configuration Manager
3
+ *
4
+ * Orchestrates live configuration reload functionality including:
5
+ * - Hook configuration watching and reloading
6
+ * - Memory store management for AGENTS.md files
7
+ * - Coordination between file watchers and configuration updates
8
+ */
9
+ import type { Logger } from "../types/index.js";
10
+ export interface LiveConfigManagerOptions {
11
+ workdir: string;
12
+ logger?: Logger;
13
+ onConfigurationChanged?: () => void;
14
+ onMemoryStoreFileChanged?: (filePath: string, changeType: "add" | "change" | "unlink") => Promise<void>;
15
+ }
16
+ export declare class LiveConfigManager {
17
+ private readonly workdir;
18
+ private readonly logger?;
19
+ private readonly onConfigurationChanged?;
20
+ private readonly onMemoryStoreFileChanged?;
21
+ private configurationWatcher?;
22
+ private isInitialized;
23
+ constructor(options: LiveConfigManagerOptions);
24
+ /**
25
+ * Initialize live configuration management
26
+ */
27
+ initialize(): Promise<void>;
28
+ /**
29
+ * Shutdown live configuration management
30
+ */
31
+ shutdown(): Promise<void>;
32
+ /**
33
+ * Initialize configuration watcher for hook settings
34
+ */
35
+ private initializeConfigurationWatcher;
36
+ /**
37
+ * Initialize memory store watching for AGENTS.md files
38
+ */
39
+ private initializeMemoryStoreWatching;
40
+ /**
41
+ * Handle configuration change events
42
+ */
43
+ private handleConfigurationChange;
44
+ /**
45
+ * Handle AGENTS.md file change events
46
+ */
47
+ private handleMemoryStoreFileChange;
48
+ /**
49
+ * Get initialization status
50
+ */
51
+ get initialized(): boolean;
52
+ /**
53
+ * Get configuration file paths for user and project settings
54
+ * Returns paths in priority order (local.json first, then .json)
55
+ */
56
+ private getConfigurationPaths;
57
+ }
58
+ //# sourceMappingURL=liveConfigManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveConfigManager.d.ts","sourceRoot":"","sources":["../../src/managers/liveConfigManager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAehD,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IACpC,wBAAwB,CAAC,EAAE,CACzB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,KACpC,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAGvB;IACnB,OAAO,CAAC,oBAAoB,CAAC,CAAuB;IACpD,OAAO,CAAC,aAAa,CAAkB;gBAE3B,OAAO,EAAE,wBAAwB;IAO7C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BjC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB/B;;OAEG;YACW,8BAA8B;IAoB5C;;OAEG;YACW,6BAA6B;IA4B3C;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA8BjC;;OAEG;YACW,2BAA2B;IA8BzC;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CAQ9B"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Live Configuration Manager
3
+ *
4
+ * Orchestrates live configuration reload functionality including:
5
+ * - Hook configuration watching and reloading
6
+ * - Memory store management for AGENTS.md files
7
+ * - Coordination between file watchers and configuration updates
8
+ */
9
+ import { ConfigurationWatcher, } from "../services/configurationWatcher.js";
10
+ import { configResolver } from "../utils/configResolver.js";
11
+ import { join } from "path";
12
+ import { getUserConfigPaths, getProjectConfigPaths, } from "../utils/configPaths.js";
13
+ import { CONFIGURATION_EVENTS } from "../constants/events.js";
14
+ export class LiveConfigManager {
15
+ constructor(options) {
16
+ this.isInitialized = false;
17
+ this.workdir = options.workdir;
18
+ this.logger = options.logger;
19
+ this.onConfigurationChanged = options.onConfigurationChanged;
20
+ this.onMemoryStoreFileChanged = options.onMemoryStoreFileChanged;
21
+ }
22
+ /**
23
+ * Initialize live configuration management
24
+ */
25
+ async initialize() {
26
+ if (this.isInitialized) {
27
+ this.logger?.debug("[LiveConfigManager] Already initialized");
28
+ return;
29
+ }
30
+ try {
31
+ // Initialize configuration watcher for hook settings
32
+ await this.initializeConfigurationWatcher();
33
+ // Initialize memory store watching for AGENTS.md if callback is available
34
+ if (this.onMemoryStoreFileChanged) {
35
+ await this.initializeMemoryStoreWatching();
36
+ }
37
+ this.isInitialized = true;
38
+ this.logger?.info("Live Config: Live configuration management initialized successfully");
39
+ }
40
+ catch (error) {
41
+ this.logger?.error(`Live Config: Failed to initialize: ${error.message}`);
42
+ throw error;
43
+ }
44
+ }
45
+ /**
46
+ * Shutdown live configuration management
47
+ */
48
+ async shutdown() {
49
+ if (!this.isInitialized) {
50
+ return;
51
+ }
52
+ try {
53
+ if (this.configurationWatcher) {
54
+ await this.configurationWatcher.shutdown();
55
+ this.configurationWatcher = undefined;
56
+ }
57
+ this.isInitialized = false;
58
+ this.logger?.info("Live Config: Live configuration management shutdown completed");
59
+ }
60
+ catch (error) {
61
+ this.logger?.error(`Live Config: Error during shutdown: ${error.message}`);
62
+ throw error;
63
+ }
64
+ }
65
+ /**
66
+ * Initialize configuration watcher for hook settings
67
+ */
68
+ async initializeConfigurationWatcher() {
69
+ this.configurationWatcher = new ConfigurationWatcher(this.workdir, this.logger);
70
+ // Set up configuration change handler using EventEmitter pattern
71
+ this.configurationWatcher.on(CONFIGURATION_EVENTS.CONFIGURATION_CHANGE, (event) => {
72
+ this.handleConfigurationChange(event);
73
+ });
74
+ // Initialize watching for user and project settings
75
+ const { userPaths, projectPaths } = this.getConfigurationPaths();
76
+ await this.configurationWatcher.initializeWatching(userPaths, projectPaths);
77
+ this.logger?.info("Live Config: Configuration watching initialized");
78
+ }
79
+ /**
80
+ * Initialize memory store watching for AGENTS.md files
81
+ */
82
+ async initializeMemoryStoreWatching() {
83
+ if (!this.onMemoryStoreFileChanged || !this.configurationWatcher) {
84
+ this.logger?.debug("Live Config: Memory store callback or configuration watcher not available, skipping AGENTS.md watching");
85
+ return;
86
+ }
87
+ try {
88
+ const agentsFilePath = join(this.workdir, "AGENTS.md");
89
+ // Add AGENTS.md to file watcher
90
+ await this.configurationWatcher.watchAdditionalFile(agentsFilePath, async (event) => {
91
+ await this.handleMemoryStoreFileChange(event);
92
+ });
93
+ this.logger?.info("Live Config: AGENTS.md file watching initialized");
94
+ }
95
+ catch (error) {
96
+ this.logger?.warn(`Live Config: Failed to initialize AGENTS.md watching: ${error.message}`);
97
+ // Don't throw - memory optimization is not critical for core functionality
98
+ }
99
+ }
100
+ /**
101
+ * Handle configuration change events
102
+ */
103
+ handleConfigurationChange(event) {
104
+ this.logger?.info(`Live Config: Configuration change detected: ${event.type} at ${event.path}`);
105
+ // Invalidate and refresh configuration cache for live environment variable updates
106
+ configResolver.invalidateCache(this.workdir);
107
+ configResolver.refreshCache(this.workdir);
108
+ // Trigger Agent configuration update callback if provided
109
+ if (this.onConfigurationChanged) {
110
+ try {
111
+ this.logger?.info("Live Config: Triggering Agent configuration update");
112
+ this.onConfigurationChanged();
113
+ }
114
+ catch (error) {
115
+ this.logger?.error(`Live Config: Error in configuration change callback: ${error.message}`);
116
+ }
117
+ }
118
+ // Log cache status after refresh
119
+ const cacheStatus = configResolver.getCacheStatus();
120
+ if (cacheStatus) {
121
+ this.logger?.info(`Live Config: Configuration cache refreshed - ${cacheStatus.envVarCount} environment variables loaded`);
122
+ }
123
+ }
124
+ /**
125
+ * Handle AGENTS.md file change events
126
+ */
127
+ async handleMemoryStoreFileChange(event) {
128
+ if (!this.onMemoryStoreFileChanged) {
129
+ return;
130
+ }
131
+ try {
132
+ this.logger?.info(`Live Config: AGENTS.md ${event.type} detected: ${event.path}`);
133
+ const changeType = event.type === "delete"
134
+ ? "unlink"
135
+ : event.type === "create"
136
+ ? "add"
137
+ : "change";
138
+ await this.onMemoryStoreFileChanged(event.path, changeType);
139
+ this.logger?.info(`Live Config: Memory store updated for AGENTS.md ${event.type}`);
140
+ }
141
+ catch (error) {
142
+ this.logger?.error(`Live Config: Failed to handle AGENTS.md file change: ${error.message}`);
143
+ }
144
+ }
145
+ /**
146
+ * Get initialization status
147
+ */
148
+ get initialized() {
149
+ return this.isInitialized;
150
+ }
151
+ /**
152
+ * Get configuration file paths for user and project settings
153
+ * Returns paths in priority order (local.json first, then .json)
154
+ */
155
+ getConfigurationPaths() {
156
+ const userPaths = getUserConfigPaths();
157
+ const projectPaths = getProjectConfigPaths(this.workdir);
158
+ return { userPaths, projectPaths };
159
+ }
160
+ }