wave-agent-sdk 0.13.4 → 0.13.6

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 (91) hide show
  1. package/builtin/skills/settings/HOOKS.md +25 -0
  2. package/builtin/skills/settings/MCP.md +22 -0
  3. package/builtin/skills/settings/SKILL.md +4 -1
  4. package/dist/agent.d.ts +21 -0
  5. package/dist/agent.d.ts.map +1 -1
  6. package/dist/agent.js +102 -1
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -0
  10. package/dist/managers/aiManager.d.ts +5 -0
  11. package/dist/managers/aiManager.d.ts.map +1 -1
  12. package/dist/managers/aiManager.js +19 -4
  13. package/dist/managers/bangManager.d.ts +1 -0
  14. package/dist/managers/bangManager.d.ts.map +1 -1
  15. package/dist/managers/bangManager.js +1 -0
  16. package/dist/managers/hookManager.d.ts +5 -1
  17. package/dist/managers/hookManager.d.ts.map +1 -1
  18. package/dist/managers/hookManager.js +55 -5
  19. package/dist/managers/lspManager.d.ts.map +1 -1
  20. package/dist/managers/lspManager.js +17 -2
  21. package/dist/managers/mcpManager.d.ts.map +1 -1
  22. package/dist/managers/mcpManager.js +20 -6
  23. package/dist/managers/messageManager.d.ts.map +1 -1
  24. package/dist/managers/messageManager.js +22 -0
  25. package/dist/managers/messageQueue.d.ts +20 -0
  26. package/dist/managers/messageQueue.d.ts.map +1 -0
  27. package/dist/managers/messageQueue.js +29 -0
  28. package/dist/managers/permissionManager.d.ts +5 -7
  29. package/dist/managers/permissionManager.d.ts.map +1 -1
  30. package/dist/managers/permissionManager.js +27 -22
  31. package/dist/managers/pluginManager.d.ts.map +1 -1
  32. package/dist/managers/pluginManager.js +5 -3
  33. package/dist/managers/skillManager.d.ts.map +1 -1
  34. package/dist/managers/skillManager.js +5 -0
  35. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  36. package/dist/managers/slashCommandManager.js +12 -1
  37. package/dist/managers/subagentManager.d.ts.map +1 -1
  38. package/dist/managers/subagentManager.js +6 -18
  39. package/dist/services/autoMemoryService.d.ts.map +1 -1
  40. package/dist/services/autoMemoryService.js +1 -0
  41. package/dist/services/hook.d.ts +4 -0
  42. package/dist/services/hook.d.ts.map +1 -1
  43. package/dist/services/hook.js +10 -0
  44. package/dist/services/interactionService.d.ts.map +1 -1
  45. package/dist/services/interactionService.js +3 -0
  46. package/dist/services/pluginLoader.d.ts.map +1 -1
  47. package/dist/services/pluginLoader.js +3 -1
  48. package/dist/tools/bashTool.d.ts.map +1 -1
  49. package/dist/tools/bashTool.js +33 -2
  50. package/dist/tools/types.d.ts +2 -0
  51. package/dist/tools/types.d.ts.map +1 -1
  52. package/dist/types/agent.d.ts +4 -0
  53. package/dist/types/agent.d.ts.map +1 -1
  54. package/dist/types/hooks.d.ts +6 -1
  55. package/dist/types/hooks.d.ts.map +1 -1
  56. package/dist/types/hooks.js +4 -0
  57. package/dist/types/lsp.d.ts +2 -0
  58. package/dist/types/lsp.d.ts.map +1 -1
  59. package/dist/types/mcp.d.ts +2 -0
  60. package/dist/types/mcp.d.ts.map +1 -1
  61. package/dist/types/skills.d.ts +1 -0
  62. package/dist/types/skills.d.ts.map +1 -1
  63. package/dist/utils/containerSetup.d.ts.map +1 -1
  64. package/dist/utils/containerSetup.js +4 -1
  65. package/package.json +1 -1
  66. package/src/agent.ts +122 -2
  67. package/src/index.ts +1 -0
  68. package/src/managers/aiManager.ts +35 -5
  69. package/src/managers/bangManager.ts +2 -0
  70. package/src/managers/hookManager.ts +78 -19
  71. package/src/managers/lspManager.ts +23 -2
  72. package/src/managers/mcpManager.ts +29 -6
  73. package/src/managers/messageManager.ts +38 -0
  74. package/src/managers/messageQueue.ts +41 -0
  75. package/src/managers/permissionManager.ts +32 -26
  76. package/src/managers/pluginManager.ts +5 -3
  77. package/src/managers/skillManager.ts +9 -0
  78. package/src/managers/slashCommandManager.ts +16 -4
  79. package/src/managers/subagentManager.ts +10 -25
  80. package/src/services/autoMemoryService.ts +1 -0
  81. package/src/services/hook.ts +15 -0
  82. package/src/services/interactionService.ts +3 -0
  83. package/src/services/pluginLoader.ts +3 -1
  84. package/src/tools/bashTool.ts +39 -2
  85. package/src/tools/types.ts +2 -0
  86. package/src/types/agent.ts +4 -0
  87. package/src/types/hooks.ts +13 -2
  88. package/src/types/lsp.ts +2 -0
  89. package/src/types/mcp.ts +2 -0
  90. package/src/types/skills.ts +1 -0
  91. package/src/utils/containerSetup.ts +5 -1
@@ -90,6 +90,31 @@ Hooks can communicate status and control Wave's behavior using exit codes:
90
90
 
91
91
  Hook configurations support **live reload**. When you modify hooks in `settings.json`, the changes take effect immediately without restarting Wave.
92
92
 
93
+ ## Plugin Hooks
94
+
95
+ When hooks are registered via a **plugin**, Wave automatically:
96
+
97
+ 1. Substitutes `${WAVE_PLUGIN_ROOT}` with the plugin's directory path in the command string
98
+ 2. Injects `WAVE_PLUGIN_ROOT` as an environment variable into the hook process
99
+
100
+ ```json
101
+ {
102
+ "hooks": {
103
+ "WorktreeCreate": [
104
+ {
105
+ "hooks": [
106
+ {
107
+ "command": "${WAVE_PLUGIN_ROOT}/scripts/setup-worktree.sh"
108
+ }
109
+ ]
110
+ }
111
+ ]
112
+ }
113
+ }
114
+ ```
115
+
116
+ The shell also receives `WAVE_PLUGIN_ROOT` as an env var, so `$WAVE_PLUGIN_ROOT` works in the hook script itself.
117
+
93
118
  ## Best Practices
94
119
 
95
120
  - **Keep hooks fast**: Long-running hooks can slow down your workflow unless they are `async`.
@@ -63,6 +63,28 @@ For example, if you have a server named `sqlite` with a tool named `query`, it w
63
63
 
64
64
  By default, MCP tools require user permission before execution. When you grant permission, you can choose to "Allow always" for a specific tool. These persistent rules are stored in your `settings.json` under the `permissions` field.
65
65
 
66
+ ## Plugin MCP Servers
67
+
68
+ When MCP servers are registered via a **plugin**, Wave automatically injects the `WAVE_PLUGIN_ROOT` environment variable into the server process. Additionally, `${WAVE_PLUGIN_ROOT}` in the `command`, `args`, and `env` fields is substituted with the plugin's directory path before the server is spawned (matching Claude Code's `${CLAUDE_PLUGIN_ROOT}` behavior).
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "my-plugin-server": {
74
+ "command": "${WAVE_PLUGIN_ROOT}/bin/mcp-server",
75
+ "args": ["--config", "${WAVE_PLUGIN_ROOT}/config/server.json"]
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ Your MCP server code can also read `WAVE_PLUGIN_ROOT` as an environment variable:
82
+
83
+ ```ts
84
+ // Inside your MCP server (e.g., a Node.js script)
85
+ const pluginRoot = process.env.WAVE_PLUGIN_ROOT;
86
+ ```
87
+
66
88
  ## Troubleshooting
67
89
 
68
90
  - **Server Connection**: If a server fails to connect, Wave will log an error. You can check the status of MCP servers by asking the agent.
@@ -91,7 +91,10 @@ For detailed guidance on creating skills, see [SKILLS.md](${WAVE_SKILL_DIR}/SKIL
91
91
  Delegate tasks to specialized AI personalities.
92
92
  For detailed guidance on creating subagents, see [SUBAGENTS.md](${WAVE_SKILL_DIR}/SUBAGENTS.md).
93
93
 
94
- ### 9. Other Settings
94
+ ### 9. Plugins
95
+ Enable or disable plugins via `enabledPlugins`. Plugin skills, hooks, MCP servers, and LSP servers can reference their parent plugin's directory using the `${WAVE_PLUGIN_ROOT}` placeholder. Wave substitutes `${WAVE_PLUGIN_ROOT}` with the plugin's directory path at load time (same as `${WAVE_SKILL_DIR}`), and also injects `WAVE_PLUGIN_ROOT` as an environment variable into the spawned process.
96
+
97
+ ### 10. Other Settings
95
98
  - `language`: Preferred language for agent communication (e.g., `"en"`, `"zh"`).
96
99
  - `autoMemoryEnabled`: Enable or disable auto-memory (default: `true`).
97
100
  - `autoMemoryFrequency`: Frequency of auto-memory extraction turns (default: `1`).
package/dist/agent.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type QueuedMessage } from "./managers/messageQueue.js";
1
2
  import { SlashCommand, CustomSlashCommand, AgentOptions } from "./types/index.js";
2
3
  import type { Message, McpServerStatus, GatewayConfig, ModelConfig, Usage, PermissionMode, ForegroundTask } from "./types/index.js";
3
4
  export declare class Agent {
@@ -20,6 +21,8 @@ export declare class Agent {
20
21
  private hookManager;
21
22
  private reversionManager;
22
23
  private notificationQueue;
24
+ private messageQueue;
25
+ private pendingNotificationPromises;
23
26
  private memoryRuleManager;
24
27
  private liveConfigManager;
25
28
  private taskManager;
@@ -63,6 +66,11 @@ export declare class Agent {
63
66
  get latestTotalTokens(): number;
64
67
  /** Get working directory */
65
68
  get workingDirectory(): string;
69
+ /**
70
+ * Set the working directory
71
+ * @param newCwd - The new working directory
72
+ */
73
+ setWorkdir(newCwd: string): void;
66
74
  /** Get project memory content */
67
75
  get projectMemory(): string;
68
76
  /** Get user memory content */
@@ -75,6 +83,19 @@ export declare class Agent {
75
83
  get isCompressing(): boolean;
76
84
  /** Get bash command execution status */
77
85
  get isCommandRunning(): boolean;
86
+ /** Get queued messages */
87
+ get queuedMessages(): QueuedMessage[];
88
+ /**
89
+ * Remove a queued message by index
90
+ * @param index - The index of the message to remove
91
+ * @returns true if the message was removed, false if the index was out of bounds
92
+ */
93
+ removeQueuedMessage(index: number): boolean;
94
+ /**
95
+ * Process the next queued message when the agent becomes idle.
96
+ * Dequeues the next message and handles it based on type.
97
+ */
98
+ private processQueuedMessage;
78
99
  /** Get background bash shell output */
79
100
  getBackgroundShellOutput(id: string, filter?: string): {
80
101
  stdout: string;
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/agent.js CHANGED
@@ -47,6 +47,7 @@ export class Agent {
47
47
  */
48
48
  constructor(options) {
49
49
  this.bangManager = null;
50
+ this.pendingNotificationPromises = []; // Track pending notification processing
50
51
  // Memory content storage
51
52
  this._projectMemoryContent = "";
52
53
  this._userMemoryContent = "";
@@ -108,13 +109,48 @@ export class Agent {
108
109
  this.bangManager = this.container.get("BangManager");
109
110
  this.cronManager = this.container.get("CronManager");
110
111
  this.notificationQueue = this.container.get("NotificationQueue");
112
+ this.messageQueue = this.container.get("MessageQueue");
111
113
  // Wire up notification queue to trigger AI when notifications arrive while idle
112
114
  this.notificationQueue.onNotificationsEnqueued = () => {
113
115
  // If the AI is NOT loading (idle), trigger a new AI cycle to process notifications
114
116
  if (!this.aiManager.isLoading) {
115
- this.processPendingNotifications().catch((error) => {
117
+ const pendingPromise = this.processPendingNotifications().catch((error) => {
116
118
  this.logger?.error("Failed to process pending notifications:", error);
117
119
  });
120
+ this.pendingNotificationPromises.push(pendingPromise);
121
+ }
122
+ };
123
+ // Wire up CWD change callback from AIManager to sync Agent's workdir
124
+ this.aiManager.setOnCwdChange((newCwd) => {
125
+ this.workdir = newCwd;
126
+ this.container.register("Workdir", newCwd);
127
+ this.options.callbacks?.onWorkdirChange?.(newCwd);
128
+ });
129
+ // Wire up message queue to process when agent becomes idle
130
+ this.messageQueue.onMessageEnqueued = () => {
131
+ // If the AI is NOT loading and command is not running, trigger dequeue
132
+ if (!this.aiManager.isLoading && !this.isCommandRunning) {
133
+ this.processQueuedMessage().catch((error) => {
134
+ this.logger?.error("Failed to process queued message:", error);
135
+ });
136
+ }
137
+ };
138
+ // Wire up AI loading changes to process queue when AI becomes idle
139
+ this.aiManager.onLoadingChange = (loading) => {
140
+ if (!loading && !this.isCommandRunning) {
141
+ this.processQueuedMessage().catch((error) => {
142
+ this.logger?.error("Failed to process queued message:", error);
143
+ });
144
+ }
145
+ };
146
+ // Wire up bang manager callback for command running changes
147
+ this.bangManager.onCommandRunningChange = (running) => {
148
+ this.options.callbacks?.onCommandRunningChange?.(running);
149
+ // When command stops and AI is idle, process queue
150
+ if (!running && !this.aiManager.isLoading) {
151
+ this.processQueuedMessage().catch((error) => {
152
+ this.logger?.error("Failed to process queued message:", error);
153
+ });
118
154
  }
119
155
  };
120
156
  // Set initial permission mode if provided
@@ -142,6 +178,15 @@ export class Agent {
142
178
  get workingDirectory() {
143
179
  return this.workdir;
144
180
  }
181
+ /**
182
+ * Set the working directory
183
+ * @param newCwd - The new working directory
184
+ */
185
+ setWorkdir(newCwd) {
186
+ this.workdir = newCwd;
187
+ this.container.register("Workdir", newCwd);
188
+ this.options.callbacks?.onWorkdirChange?.(newCwd);
189
+ }
145
190
  /** Get project memory content */
146
191
  get projectMemory() {
147
192
  return this._projectMemoryContent;
@@ -166,6 +211,39 @@ export class Agent {
166
211
  get isCommandRunning() {
167
212
  return this.bangManager?.isCommandRunning ?? false;
168
213
  }
214
+ /** Get queued messages */
215
+ get queuedMessages() {
216
+ return this.messageQueue.getQueue();
217
+ }
218
+ /**
219
+ * Remove a queued message by index
220
+ * @param index - The index of the message to remove
221
+ * @returns true if the message was removed, false if the index was out of bounds
222
+ */
223
+ removeQueuedMessage(index) {
224
+ const removed = this.messageQueue.removeAt(index);
225
+ if (removed) {
226
+ this.options.callbacks?.onQueuedMessagesChange?.(this.queuedMessages);
227
+ }
228
+ return removed;
229
+ }
230
+ /**
231
+ * Process the next queued message when the agent becomes idle.
232
+ * Dequeues the next message and handles it based on type.
233
+ */
234
+ async processQueuedMessage() {
235
+ const next = this.messageQueue.dequeue();
236
+ if (!next)
237
+ return;
238
+ this.options.callbacks?.onQueuedMessagesChange?.(this.queuedMessages);
239
+ if (next.type === "bang") {
240
+ await this.bangManager?.executeCommand(next.content);
241
+ await this.messageManager.saveSession();
242
+ }
243
+ else {
244
+ await this.sendMessage(next.content, next.images);
245
+ }
246
+ }
169
247
  /** Get background bash shell output */
170
248
  getBackgroundShellOutput(id, filter) {
171
249
  return this.backgroundTaskManager.getOutput(id, filter);
@@ -323,6 +401,12 @@ export class Agent {
323
401
  }
324
402
  /** Execute bash command (bang command) */
325
403
  async bang(command) {
404
+ // If the agent is busy, enqueue the bang command
405
+ if (this.aiManager.isLoading || this.isCommandRunning) {
406
+ this.messageQueue.enqueue({ type: "bang", content: command });
407
+ this.options.callbacks?.onQueuedMessagesChange?.(this.queuedMessages);
408
+ return;
409
+ }
326
410
  await this.bangManager?.executeCommand(command);
327
411
  await this.messageManager.saveSession();
328
412
  }
@@ -334,6 +418,8 @@ export class Agent {
334
418
  this.abortAIMessage(); // This will abort tools including Agent tool (subagents)
335
419
  this.abortBashCommand();
336
420
  this.abortSlashCommand();
421
+ this.messageQueue.clear();
422
+ this.options.callbacks?.onQueuedMessagesChange?.(this.queuedMessages);
337
423
  }
338
424
  /** Interrupt bash command execution */
339
425
  abortBashCommand() {
@@ -364,6 +450,15 @@ export class Agent {
364
450
  }
365
451
  /** Destroy managers, clean up resources */
366
452
  async destroy() {
453
+ // Clear notification callback first to prevent any late triggers from
454
+ // starting async work during teardown
455
+ this.notificationQueue.onNotificationsEnqueued = undefined;
456
+ // Await any pending notification processing to prevent race conditions
457
+ // with test teardown (e.g., V8 coverage stream cleanup)
458
+ if (this.pendingNotificationPromises.length > 0) {
459
+ await Promise.allSettled(this.pendingNotificationPromises);
460
+ this.pendingNotificationPromises = [];
461
+ }
367
462
  await this.messageManager.saveSession();
368
463
  this.abortAIMessage(); // This will abort tools including Agent tool (subagents)
369
464
  this.abortBashCommand();
@@ -440,6 +535,12 @@ export class Agent {
440
535
  * ```
441
536
  */
442
537
  async sendMessage(content, images) {
538
+ // If the agent is busy, enqueue the message
539
+ if (this.aiManager.isLoading || this.isCommandRunning) {
540
+ this.messageQueue.enqueue({ content, images });
541
+ this.options.callbacks?.onQueuedMessagesChange?.(this.queuedMessages);
542
+ return;
543
+ }
443
544
  await InteractionService.sendMessage({
444
545
  messageManager: this.messageManager,
445
546
  slashCommandManager: this.slashCommandManager,
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./constants/tools.js";
3
3
  export * from "./agent.js";
4
4
  export * from "./core/plugin.js";
5
5
  export * from "./managers/cronManager.js";
6
+ export * from "./managers/messageQueue.js";
6
7
  export * from "./utils/bashParser.js";
7
8
  export * from "./utils/convertMessagesForAPI.js";
8
9
  export * from "./utils/fileSearch.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAG1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAG3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ export * from "./constants/tools.js";
6
6
  export * from "./agent.js";
7
7
  export * from "./core/plugin.js";
8
8
  export * from "./managers/cronManager.js";
9
+ export * from "./managers/messageQueue.js";
9
10
  // Export all utilities
10
11
  export * from "./utils/bashParser.js";
11
12
  export * from "./utils/convertMessagesForAPI.js";
@@ -3,6 +3,7 @@ import { Container } from "../utils/container.js";
3
3
  export interface AIManagerCallbacks {
4
4
  onCompressionStateChange?: (isCompressing: boolean) => void;
5
5
  onUsageAdded?: (usage: Usage) => void;
6
+ onCwdChange?: (newCwd: string) => void;
6
7
  }
7
8
  export interface AIManagerOptions {
8
9
  callbacks?: AIManagerCallbacks;
@@ -18,12 +19,14 @@ export declare class AIManager {
18
19
  private container;
19
20
  isLoading: boolean;
20
21
  private abortController;
22
+ onLoadingChange?: (loading: boolean) => void;
21
23
  private toolAbortController;
22
24
  private workdir;
23
25
  private systemPrompt?;
24
26
  private subagentType?;
25
27
  private stream;
26
28
  private modelOverride?;
29
+ private _onCwdChange?;
27
30
  constructor(container: Container, options: AIManagerOptions);
28
31
  private get toolManager();
29
32
  private get messageManager();
@@ -39,6 +42,8 @@ export declare class AIManager {
39
42
  getMaxInputTokens(): number;
40
43
  getLanguage(): string | undefined;
41
44
  getAutoMemoryEnabled(): boolean;
45
+ getWorkdir(): string;
46
+ setOnCwdChange(callback: (newCwd: string) => void): void;
42
47
  private isCompressing;
43
48
  private callbacks;
44
49
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/managers/aiManager.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,KAAK,EAGN,MAAM,mBAAmB,CAAC;AAa3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKlD,MAAM,WAAW,kBAAkB;IACjC,wBAAwB,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,SAAS;IAYlB,OAAO,CAAC,SAAS;IAXZ,SAAS,EAAE,OAAO,CAAS;IAClC,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,mBAAmB,CAAgC;IAC3D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,aAAa,CAAC,CAAS;gBAIrB,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,gBAAgB;IAU3B,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,KAAK,aAAa,GAIxB;IAED,OAAO,KAAK,WAAW,GAItB;IAED,OAAO,KAAK,qBAAqB,GAEhC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,gBAAgB,GAM3B;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,oBAAoB,GAE/B;IAGM,gBAAgB,IAAI,aAAa;IAIjC,cAAc,IAAI,WAAW;IA6B7B,iBAAiB,IAAI,MAAM;IAI3B,WAAW,IAAI,MAAM,GAAG,SAAS;IAIjC,oBAAoB,IAAI,OAAO;IAItC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,SAAS,CAAqB;IAEtC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAevB,YAAY,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAStC,cAAc,IAAI,IAAI;IAuB7B,OAAO,CAAC,qBAAqB;YAsBf,8BAA8B;IAgFrC,gBAAgB,IAAI,OAAO;IAI3B,gBAAgB,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI;IAOrD,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,KAAK,YAAY,GAEvB;IAEY,aAAa,CACxB,OAAO,GAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,oEAAoE;QACpE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;KACf,GACL,OAAO,CAAC,IAAI,CAAC;IA+nBhB;;;;OAIG;YACW,gBAAgB;IAkF9B;;;OAGG;YACW,sBAAsB;IA+DpC;;OAEG;YACW,uBAAuB;CA0DtC"}
1
+ {"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/managers/aiManager.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,KAAK,EAGN,MAAM,mBAAmB,CAAC;AAa3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKlD,MAAM,WAAW,kBAAkB;IACjC,wBAAwB,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,SAAS;IAclB,OAAO,CAAC,SAAS;IAbZ,SAAS,EAAE,OAAO,CAAS;IAClC,OAAO,CAAC,eAAe,CAAgC;IACvD,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,OAAO,CAAC,mBAAmB,CAAgC;IAC3D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAC,CAA2B;gBAItC,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,gBAAgB;IAW3B,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,KAAK,aAAa,GAIxB;IAED,OAAO,KAAK,WAAW,GAItB;IAED,OAAO,KAAK,qBAAqB,GAEhC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,gBAAgB,GAM3B;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,oBAAoB,GAE/B;IAGM,gBAAgB,IAAI,aAAa;IAIjC,cAAc,IAAI,WAAW;IA6B7B,iBAAiB,IAAI,MAAM;IAI3B,WAAW,IAAI,MAAM,GAAG,SAAS;IAIjC,oBAAoB,IAAI,OAAO;IAI/B,UAAU,IAAI,MAAM;IAIpB,cAAc,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI/D,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,SAAS,CAAqB;IAEtC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAevB,YAAY,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAUtC,cAAc,IAAI,IAAI;IAuB7B,OAAO,CAAC,qBAAqB;YAsBf,8BAA8B;IAgFrC,gBAAgB,IAAI,OAAO;IAI3B,gBAAgB,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI;IAOrD,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,KAAK,YAAY,GAEvB;IAEY,aAAa,CACxB,OAAO,GAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,oEAAoE;QACpE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;KACf,GACL,OAAO,CAAC,IAAI,CAAC;IAgpBhB;;;;OAIG;YACW,gBAAgB;IAkF9B;;;OAGG;YACW,sBAAsB;IA+DpC;;OAEG;YACW,uBAAuB;CA0DtC"}
@@ -19,6 +19,7 @@ export class AIManager {
19
19
  this.stream = options.stream ?? true; // Default to true if not specified
20
20
  this.callbacks = options.callbacks ?? {};
21
21
  this.modelOverride = options.modelOverride;
22
+ this._onCwdChange = options.callbacks?.onCwdChange; // Initialize onCwdChange
22
23
  }
23
24
  get toolManager() {
24
25
  return this.container.get("ToolManager");
@@ -76,6 +77,12 @@ export class AIManager {
76
77
  getAutoMemoryEnabled() {
77
78
  return this.configurationService.resolveAutoMemoryEnabled();
78
79
  }
80
+ getWorkdir() {
81
+ return this.workdir;
82
+ }
83
+ setOnCwdChange(callback) {
84
+ this._onCwdChange = callback;
85
+ }
79
86
  /**
80
87
  * Get filtered tool configuration based on tools list
81
88
  */
@@ -94,6 +101,7 @@ export class AIManager {
94
101
  }
95
102
  setIsLoading(isLoading) {
96
103
  this.isLoading = isLoading;
104
+ this.onLoadingChange?.(isLoading);
97
105
  const options = this.container.get("AgentOptions");
98
106
  options?.callbacks?.onLoadingChange?.(isLoading);
99
107
  }
@@ -212,10 +220,6 @@ export class AIManager {
212
220
  }
213
221
  async sendAIMessage(options = {}) {
214
222
  const { recursionDepth = 0, model, allowedRules, maxTokens } = options;
215
- // Only check isLoading for the initial call (recursionDepth === 0)
216
- if (recursionDepth === 0 && this.isLoading) {
217
- return;
218
- }
219
223
  // Set loading state early for the initial call, before any async work
220
224
  if (recursionDepth === 0) {
221
225
  this.setIsLoading(true);
@@ -517,6 +521,17 @@ export class AIManager {
517
521
  stage: "running", // Keep it in running stage while updating result
518
522
  });
519
523
  },
524
+ onCwdChange: async (newCwd) => {
525
+ const oldCwd = this.workdir;
526
+ this.workdir = newCwd;
527
+ this._onCwdChange?.(newCwd);
528
+ if (this.hookManager) {
529
+ const sessionId = this.messageManager.getSessionId();
530
+ const transcriptPath = this.messageManager.getTranscriptPath();
531
+ const env = Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined));
532
+ await this.hookManager.executeCwdChangedHooks(oldCwd, newCwd, sessionId, transcriptPath, env);
533
+ }
534
+ },
520
535
  };
521
536
  // Execute tool
522
537
  const toolResult = await this.toolManager.execute(functionToolCall.function?.name || "", toolArgs, context);
@@ -11,6 +11,7 @@ export declare class BangManager {
11
11
  private workdir;
12
12
  isCommandRunning: boolean;
13
13
  private currentProcess;
14
+ onCommandRunningChange?: (running: boolean) => void;
14
15
  constructor(container: Container, options: BangManagerOptions);
15
16
  private get messageManager();
16
17
  private setCommandRunning;
@@ -1 +1 @@
1
- {"version":3,"file":"bangManager.d.ts","sourceRoot":"","sources":["../../src/managers/bangManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,WAAW;IAMpB,OAAO,CAAC,SAAS;IALnB,OAAO,CAAC,OAAO,CAAS;IACjB,gBAAgB,UAAS;IAChC,OAAO,CAAC,cAAc,CAA6B;gBAGzC,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,kBAAkB;IAK7B,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,CAAC,iBAAiB;IAIZ,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4DtD,YAAY,IAAI,IAAI;CAO5B"}
1
+ {"version":3,"file":"bangManager.d.ts","sourceRoot":"","sources":["../../src/managers/bangManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,WAAW;IAOpB,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,OAAO,CAAS;IACjB,gBAAgB,UAAS;IAChC,OAAO,CAAC,cAAc,CAA6B;IACnD,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;gBAG1C,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,kBAAkB;IAK7B,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,CAAC,iBAAiB;IAKZ,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4DtD,YAAY,IAAI,IAAI;CAO5B"}
@@ -11,6 +11,7 @@ export class BangManager {
11
11
  }
12
12
  setCommandRunning(isRunning) {
13
13
  this.isCommandRunning = isRunning;
14
+ this.onCommandRunningChange?.(isRunning);
14
15
  }
15
16
  async executeCommand(command) {
16
17
  if (this.isCommandRunning) {
@@ -98,9 +98,13 @@ export declare class HookManager {
98
98
  totalCommands: number;
99
99
  eventBreakdown: Record<HookEvent, number>;
100
100
  };
101
+ /**
102
+ * Execute CwdChanged hooks.
103
+ */
104
+ executeCwdChangedHooks(oldCwd: string, newCwd: string, sessionId: string, transcriptPath: string, env: Record<string, string>): Promise<HookExecutionResult[]>;
101
105
  /**
102
106
  * Register hooks provided by a plugin
103
107
  */
104
- registerPluginHooks(hooks: PartialHookConfiguration): void;
108
+ registerPluginHooks(pluginRoot: string, hooks: PartialHookConfiguration): void;
105
109
  }
106
110
  //# sourceMappingURL=hookManager.d.ts.map
@@ -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,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAI1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIlD,qBAAa,WAAW;IAMpB,OAAO,CAAC,SAAS;IALnB,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAGvB,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAA+B;IAM1C;;;OAGG;IACH,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI;IAyBP;;;OAGG;IACH,+BAA+B,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IA6B3E;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,GAC3D,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAoGjC;;;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;IA2CD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA2E3B;;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,oBAAoB;IA8DtE;;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;IA0DhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAa/B;;OAEG;IACH,OAAO,CAAC,aAAa;IAqCrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgD3B;;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;IAkDD;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,IAAI;CAO3D"}
1
+ {"version":3,"file":"hookManager.d.ts","sourceRoot":"","sources":["../../src/managers/hookManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAI1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIlD,qBAAa,WAAW;IAMpB,OAAO,CAAC,SAAS;IALnB,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAGvB,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAA+B;IAM1C;;;OAGG;IACH,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI;IAyBP;;;OAGG;IACH,+BAA+B,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IA6B3E;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,GAC3D,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAkHjC;;;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;IA2CD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA2E3B;;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,oBAAoB;IA8DtE;;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;IA0DhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAa/B;;OAEG;IACH,OAAO,CAAC,aAAa;IAsCrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgD3B;;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;IAoDD;;OAEG;IACG,sBAAsB,CAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAoBjC;;OAEG;IACH,mBAAmB,CACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,wBAAwB,GAC9B,IAAI;CAiBR"}
@@ -101,9 +101,24 @@ export class HookManager {
101
101
  const options = hookCommand.timeout
102
102
  ? { timeout: hookCommand.timeout * 1000 }
103
103
  : undefined;
104
+ // Build execution context with WAVE_PLUGIN_ROOT if this is a plugin hook
105
+ let command = hookCommand.command;
106
+ const execContext = hookCommand.pluginRoot
107
+ ? {
108
+ ...context,
109
+ env: {
110
+ ...("env" in context ? (context.env ?? {}) : {}),
111
+ WAVE_PLUGIN_ROOT: hookCommand.pluginRoot,
112
+ },
113
+ }
114
+ : context;
115
+ // Substitute ${WAVE_PLUGIN_ROOT} in the command string (same pattern as Claude Code)
116
+ if (hookCommand.pluginRoot) {
117
+ command = command.replace(/\$\{WAVE_PLUGIN_ROOT\}/g, hookCommand.pluginRoot);
118
+ }
104
119
  if (hookCommand.async) {
105
120
  // Execute async command without awaiting
106
- executeCommand(hookCommand.command, context, options).catch((error) => {
121
+ executeCommand(command, execContext, options).catch((error) => {
107
122
  const errorMessage = error instanceof Error
108
123
  ? error.message
109
124
  : "Unknown execution error";
@@ -112,7 +127,7 @@ export class HookManager {
112
127
  // Async hooks are not included in results to prevent blocking
113
128
  continue;
114
129
  }
115
- const result = await executeCommand(hookCommand.command, context, options);
130
+ const result = await executeCommand(command, execContext, options);
116
131
  results.push(result);
117
132
  // Continue with next command even if this one fails
118
133
  // This allows for non-critical hooks to fail without stopping the workflow
@@ -442,7 +457,8 @@ export class HookManager {
442
457
  if (event === "UserPromptSubmit" ||
443
458
  event === "Stop" ||
444
459
  event === "SubagentStop" ||
445
- event === "WorktreeCreate") {
460
+ event === "WorktreeCreate" ||
461
+ event === "CwdChanged") {
446
462
  return true;
447
463
  }
448
464
  // For tool-based events, check matcher if present
@@ -513,6 +529,7 @@ export class HookManager {
513
529
  SubagentStop: 0,
514
530
  PermissionRequest: 0,
515
531
  WorktreeCreate: 0,
532
+ CwdChanged: 0,
516
533
  },
517
534
  };
518
535
  }
@@ -524,6 +541,7 @@ export class HookManager {
524
541
  SubagentStop: 0,
525
542
  PermissionRequest: 0,
526
543
  WorktreeCreate: 0,
544
+ CwdChanged: 0,
527
545
  };
528
546
  let totalConfigs = 0;
529
547
  let totalCommands = 0;
@@ -541,13 +559,45 @@ export class HookManager {
541
559
  eventBreakdown,
542
560
  };
543
561
  }
562
+ /**
563
+ * Execute CwdChanged hooks.
564
+ */
565
+ async executeCwdChangedHooks(oldCwd, newCwd, sessionId, transcriptPath, env) {
566
+ const context = {
567
+ event: "CwdChanged",
568
+ projectDir: this.workdir,
569
+ timestamp: new Date(),
570
+ sessionId,
571
+ transcriptPath,
572
+ cwd: newCwd,
573
+ oldCwd,
574
+ newCwd,
575
+ env,
576
+ };
577
+ const results = await this.executeHooks("CwdChanged", context);
578
+ if (results.length > 0) {
579
+ // For CwdChanged hooks, we don't block, just log errors
580
+ this.processHookResults("CwdChanged", results);
581
+ }
582
+ return results;
583
+ }
544
584
  /**
545
585
  * Register hooks provided by a plugin
546
586
  */
547
- registerPluginHooks(hooks) {
587
+ registerPluginHooks(pluginRoot, hooks) {
548
588
  if (!this.configuration) {
549
589
  this.configuration = {};
550
590
  }
551
- this.mergeHooksConfiguration(this.configuration, hooks);
591
+ // Stamp pluginRoot on each hook command
592
+ const stampedHooks = {};
593
+ for (const [event, configs] of Object.entries(hooks)) {
594
+ if (!isValidHookEvent(event))
595
+ continue;
596
+ stampedHooks[event] = configs.map((config) => ({
597
+ ...config,
598
+ hooks: config.hooks.map((cmd) => ({ ...cmd, pluginRoot })),
599
+ }));
600
+ }
601
+ this.mergeHooksConfiguration(this.configuration, stampedHooks);
552
602
  }
553
603
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lspManager.d.ts","sourceRoot":"","sources":["../../src/managers/lspManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAS,MAAM,eAAe,CAAC;AACpD,OAAO,EAEL,eAAe,EACf,WAAW,EAEZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,UAAU,UAAU;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,GAAG,CAClB,MAAM,EACN;QAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAC1E,CAAC;IACF,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC1B;AAID,qBAAa,UAAW,YAAW,WAAW;IAKhC,OAAO,CAAC,SAAS;IAJ7B,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,MAAM,CAAiB;gBAEX,SAAS,EAAE,SAAS;IAElC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhD,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;YAKjD,UAAU;IAclB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;YA0BvD,WAAW;IAgGzB,OAAO,CAAC,aAAa;YAiBP,WAAW;YA0CX,gBAAgB;IAgBxB,OAAO,CAAC,IAAI,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAoJ5C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAuB/B"}
1
+ {"version":3,"file":"lspManager.d.ts","sourceRoot":"","sources":["../../src/managers/lspManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAS,MAAM,eAAe,CAAC;AACpD,OAAO,EAEL,eAAe,EACf,WAAW,EAEZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,UAAU,UAAU;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,GAAG,CAClB,MAAM,EACN;QAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAC1E,CAAC;IACF,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC1B;AAID,qBAAa,UAAW,YAAW,WAAW;IAKhC,OAAO,CAAC,SAAS;IAJ7B,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,MAAM,CAAiB;gBAEX,SAAS,EAAE,SAAS;IAElC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhD,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;YAKjD,UAAU;IAclB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;YA0BvD,WAAW;IAqHzB,OAAO,CAAC,aAAa;YAiBP,WAAW;YA0CX,gBAAgB;IAgBxB,OAAO,CAAC,IAAI,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAoJ5C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAuB/B"}
@@ -56,9 +56,24 @@ export class LspManager {
56
56
  async startServer(language, config) {
57
57
  logger?.info(`Starting LSP server for ${language}: ${config.command} ${config.args?.join(" ") || ""}`);
58
58
  try {
59
- const proc = spawn(config.command, config.args || [], {
59
+ const env = { ...process.env, ...config.env };
60
+ // For plugin servers, substitute ${WAVE_PLUGIN_ROOT} in command/args/env
61
+ let command = config.command;
62
+ let args = config.args || [];
63
+ if (config.pluginRoot) {
64
+ env.WAVE_PLUGIN_ROOT = config.pluginRoot;
65
+ command = command.replace(/\$\{WAVE_PLUGIN_ROOT\}/g, config.pluginRoot);
66
+ args = args.map((arg) => arg.replace(/\$\{WAVE_PLUGIN_ROOT\}/g, config.pluginRoot));
67
+ // Also expand WAVE_PLUGIN_ROOT in user-provided env values
68
+ if (config.env) {
69
+ for (const [key, value] of Object.entries(config.env)) {
70
+ env[key] = value.replace(/\$\{WAVE_PLUGIN_ROOT\}/g, config.pluginRoot);
71
+ }
72
+ }
73
+ }
74
+ const proc = spawn(command, args, {
60
75
  cwd: config.workspaceFolder || this.workdir,
61
- env: { ...process.env, ...config.env },
76
+ env,
62
77
  stdio: ["pipe", "pipe", "pipe"],
63
78
  });
64
79
  const lspProc = {
@@ -1 +1 @@
1
- {"version":3,"file":"mcpManager.d.ts","sourceRoot":"","sources":["../../src/managers/mcpManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcpManager.d.ts","sourceRoot":"","sources":["../../src/managers/mcpManager.ts"],"names":[],"mappings":"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"}