wave-agent-sdk 0.6.4 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/agent.d.ts +8 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +49 -240
  4. package/dist/constants/tools.d.ts +0 -2
  5. package/dist/constants/tools.d.ts.map +1 -1
  6. package/dist/constants/tools.js +0 -2
  7. package/dist/core/plugin.d.ts +86 -0
  8. package/dist/core/plugin.d.ts.map +1 -0
  9. package/dist/core/plugin.js +164 -0
  10. package/dist/index.d.ts +1 -4
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -5
  13. package/dist/managers/MemoryRuleManager.d.ts +3 -1
  14. package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
  15. package/dist/managers/MemoryRuleManager.js +2 -1
  16. package/dist/managers/aiManager.d.ts +13 -23
  17. package/dist/managers/aiManager.d.ts.map +1 -1
  18. package/dist/managers/aiManager.js +59 -32
  19. package/dist/managers/backgroundTaskManager.d.ts +3 -1
  20. package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
  21. package/dist/managers/backgroundTaskManager.js +2 -1
  22. package/dist/managers/bashManager.d.ts +4 -4
  23. package/dist/managers/bashManager.d.ts.map +1 -1
  24. package/dist/managers/bashManager.js +5 -2
  25. package/dist/managers/foregroundTaskManager.d.ts +3 -0
  26. package/dist/managers/foregroundTaskManager.d.ts.map +1 -1
  27. package/dist/managers/foregroundTaskManager.js +2 -1
  28. package/dist/managers/hookManager.d.ts +3 -3
  29. package/dist/managers/hookManager.d.ts.map +1 -1
  30. package/dist/managers/hookManager.js +20 -19
  31. package/dist/managers/liveConfigManager.d.ts +6 -13
  32. package/dist/managers/liveConfigManager.d.ts.map +1 -1
  33. package/dist/managers/liveConfigManager.js +50 -45
  34. package/dist/managers/lspManager.d.ts +4 -5
  35. package/dist/managers/lspManager.d.ts.map +1 -1
  36. package/dist/managers/lspManager.js +13 -12
  37. package/dist/managers/mcpManager.d.ts +3 -2
  38. package/dist/managers/mcpManager.d.ts.map +1 -1
  39. package/dist/managers/mcpManager.js +16 -15
  40. package/dist/managers/messageManager.d.ts +5 -7
  41. package/dist/managers/messageManager.d.ts.map +1 -1
  42. package/dist/managers/messageManager.js +12 -7
  43. package/dist/managers/permissionManager.d.ts +6 -4
  44. package/dist/managers/permissionManager.d.ts.map +1 -1
  45. package/dist/managers/permissionManager.js +39 -63
  46. package/dist/managers/planManager.d.ts +4 -6
  47. package/dist/managers/planManager.d.ts.map +1 -1
  48. package/dist/managers/planManager.js +18 -4
  49. package/dist/managers/pluginManager.d.ts +10 -22
  50. package/dist/managers/pluginManager.d.ts.map +1 -1
  51. package/dist/managers/pluginManager.js +27 -14
  52. package/dist/managers/reversionManager.d.ts +4 -3
  53. package/dist/managers/reversionManager.d.ts.map +1 -1
  54. package/dist/managers/reversionManager.js +5 -2
  55. package/dist/managers/skillManager.d.ts +3 -2
  56. package/dist/managers/skillManager.d.ts.map +1 -1
  57. package/dist/managers/skillManager.js +15 -14
  58. package/dist/managers/slashCommandManager.d.ts +9 -16
  59. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  60. package/dist/managers/slashCommandManager.js +21 -10
  61. package/dist/managers/subagentManager.d.ts +7 -17
  62. package/dist/managers/subagentManager.d.ts.map +1 -1
  63. package/dist/managers/subagentManager.js +41 -34
  64. package/dist/managers/toolManager.d.ts +15 -38
  65. package/dist/managers/toolManager.d.ts.map +1 -1
  66. package/dist/managers/toolManager.js +66 -56
  67. package/dist/prompts/index.d.ts +6 -3
  68. package/dist/prompts/index.d.ts.map +1 -1
  69. package/dist/prompts/index.js +8 -16
  70. package/dist/services/MarketplaceService.d.ts.map +1 -1
  71. package/dist/services/MarketplaceService.js +13 -0
  72. package/dist/services/aiService.d.ts +4 -0
  73. package/dist/services/aiService.d.ts.map +1 -1
  74. package/dist/services/aiService.js +47 -7
  75. package/dist/services/configurationService.d.ts.map +1 -1
  76. package/dist/services/configurationService.js +30 -11
  77. package/dist/services/taskManager.d.ts +3 -1
  78. package/dist/services/taskManager.d.ts.map +1 -1
  79. package/dist/services/taskManager.js +2 -1
  80. package/dist/tools/bashTool.js +2 -2
  81. package/dist/tools/editTool.d.ts.map +1 -1
  82. package/dist/tools/editTool.js +9 -1
  83. package/dist/tools/readTool.d.ts.map +1 -1
  84. package/dist/tools/readTool.js +2 -2
  85. package/dist/tools/skillTool.d.ts +2 -4
  86. package/dist/tools/skillTool.d.ts.map +1 -1
  87. package/dist/tools/skillTool.js +61 -61
  88. package/dist/tools/taskOutputTool.js +1 -1
  89. package/dist/tools/taskTool.d.ts +2 -4
  90. package/dist/tools/taskTool.d.ts.map +1 -1
  91. package/dist/tools/taskTool.js +192 -187
  92. package/dist/tools/types.d.ts +11 -1
  93. package/dist/tools/types.d.ts.map +1 -1
  94. package/dist/tools/writeTool.d.ts.map +1 -1
  95. package/dist/tools/writeTool.js +4 -2
  96. package/dist/types/marketplace.d.ts +8 -0
  97. package/dist/types/marketplace.d.ts.map +1 -1
  98. package/dist/types/permissions.d.ts +1 -1
  99. package/dist/types/permissions.d.ts.map +1 -1
  100. package/dist/types/permissions.js +1 -3
  101. package/dist/types/skills.d.ts +0 -2
  102. package/dist/types/skills.d.ts.map +1 -1
  103. package/dist/types/tools.d.ts +0 -15
  104. package/dist/types/tools.d.ts.map +1 -1
  105. package/dist/utils/container.d.ts +31 -0
  106. package/dist/utils/container.d.ts.map +1 -0
  107. package/dist/utils/container.js +79 -0
  108. package/dist/utils/containerSetup.d.ts +26 -0
  109. package/dist/utils/containerSetup.d.ts.map +1 -0
  110. package/dist/utils/containerSetup.js +165 -0
  111. package/dist/utils/editUtils.d.ts +0 -3
  112. package/dist/utils/editUtils.d.ts.map +1 -1
  113. package/dist/utils/editUtils.js +4 -3
  114. package/dist/utils/hookMatcher.d.ts +1 -1
  115. package/dist/utils/hookMatcher.d.ts.map +1 -1
  116. package/dist/utils/hookMatcher.js +2 -2
  117. package/dist/utils/openaiClient.js +2 -2
  118. package/dist/utils/stringUtils.d.ts +6 -0
  119. package/dist/utils/stringUtils.d.ts.map +1 -1
  120. package/dist/utils/stringUtils.js +8 -0
  121. package/package.json +1 -1
  122. package/src/agent.ts +60 -282
  123. package/src/constants/tools.ts +0 -2
  124. package/src/core/plugin.ts +224 -0
  125. package/src/index.ts +1 -6
  126. package/src/managers/MemoryRuleManager.ts +6 -1
  127. package/src/managers/aiManager.ts +83 -58
  128. package/src/managers/backgroundTaskManager.ts +5 -1
  129. package/src/managers/bashManager.ts +9 -4
  130. package/src/managers/foregroundTaskManager.ts +3 -0
  131. package/src/managers/hookManager.ts +21 -23
  132. package/src/managers/liveConfigManager.ts +57 -53
  133. package/src/managers/lspManager.ts +14 -19
  134. package/src/managers/mcpManager.ts +20 -20
  135. package/src/managers/messageManager.ts +19 -12
  136. package/src/managers/permissionManager.ts +45 -70
  137. package/src/managers/planManager.ts +26 -7
  138. package/src/managers/pluginManager.ts +37 -33
  139. package/src/managers/reversionManager.ts +5 -3
  140. package/src/managers/skillManager.ts +19 -20
  141. package/src/managers/slashCommandManager.ts +30 -25
  142. package/src/managers/subagentManager.ts +53 -53
  143. package/src/managers/toolManager.ts +91 -90
  144. package/src/prompts/index.ts +12 -24
  145. package/src/services/MarketplaceService.ts +13 -0
  146. package/src/services/aiService.ts +61 -15
  147. package/src/services/configurationService.ts +34 -13
  148. package/src/services/taskManager.ts +5 -1
  149. package/src/tools/bashTool.ts +2 -2
  150. package/src/tools/editTool.ts +9 -1
  151. package/src/tools/readTool.ts +2 -2
  152. package/src/tools/skillTool.ts +75 -71
  153. package/src/tools/taskOutputTool.ts +1 -1
  154. package/src/tools/taskTool.ts +224 -225
  155. package/src/tools/types.ts +12 -1
  156. package/src/tools/writeTool.ts +4 -2
  157. package/src/types/marketplace.ts +9 -0
  158. package/src/types/permissions.ts +0 -4
  159. package/src/types/skills.ts +0 -3
  160. package/src/types/tools.ts +0 -17
  161. package/src/utils/container.ts +92 -0
  162. package/src/utils/containerSetup.ts +256 -0
  163. package/src/utils/editUtils.ts +4 -3
  164. package/src/utils/hookMatcher.ts +2 -2
  165. package/src/utils/openaiClient.ts +2 -2
  166. package/src/utils/stringUtils.ts +9 -0
  167. package/dist/tools/deleteFileTool.d.ts +0 -6
  168. package/dist/tools/deleteFileTool.d.ts.map +0 -1
  169. package/dist/tools/deleteFileTool.js +0 -100
  170. package/dist/tools/multiEditTool.d.ts +0 -6
  171. package/dist/tools/multiEditTool.d.ts.map +0 -1
  172. package/dist/tools/multiEditTool.js +0 -246
  173. package/src/tools/deleteFileTool.ts +0 -127
  174. package/src/tools/multiEditTool.ts +0 -306
package/src/agent.ts CHANGED
@@ -20,7 +20,6 @@ import { SlashCommandManager } from "./managers/slashCommandManager.js";
20
20
  import { PluginManager } from "./managers/pluginManager.js";
21
21
  import { HookManager } from "./managers/hookManager.js";
22
22
  import { ReversionManager } from "./managers/reversionManager.js";
23
- import { ReversionService } from "./services/reversionService.js";
24
23
  import { PermissionManager } from "./managers/permissionManager.js";
25
24
  import { PlanManager } from "./managers/planManager.js";
26
25
  import type {
@@ -57,6 +56,9 @@ import path from "path";
57
56
  import os from "os";
58
57
  import { ClientOptions } from "openai";
59
58
 
59
+ import { Container } from "./utils/container.js";
60
+ import { setupAgentContainer } from "./utils/containerSetup.js";
61
+
60
62
  /**
61
63
  * Configuration options for Agent instances
62
64
  *
@@ -98,6 +100,13 @@ export interface AgentOptions {
98
100
  lspManager?: ILspManager;
99
101
  /**Optional local plugins to load */
100
102
  plugins?: PluginConfig[];
103
+ /**
104
+ * Optional list of tool names to enable.
105
+ * - undefined: Enable all built-in tools and plugins (default).
106
+ * - []: Disable all tools.
107
+ * - string[]: Enable only the tools with the specified names.
108
+ */
109
+ tools?: string[];
101
110
  }
102
111
 
103
112
  export interface AgentCallbacks
@@ -137,6 +146,7 @@ export class Agent {
137
146
  private liveConfigManager: LiveConfigManager; // Add live configuration manager
138
147
  private taskManager: TaskManager;
139
148
  private foregroundTaskManager: ForegroundTaskManager;
149
+ private container: Container;
140
150
  private configurationService: ConfigurationService; // Add configuration service
141
151
  private workdir: string; // Working directory
142
152
  private systemPrompt?: string; // Custom system prompt
@@ -190,13 +200,7 @@ export class Agent {
190
200
  * @param options - Configuration options for the Agent instance
191
201
  */
192
202
  private constructor(options: AgentOptions) {
193
- const {
194
- callbacks = {},
195
- logger,
196
- workdir,
197
- systemPrompt,
198
- stream = true,
199
- } = options;
203
+ const { logger, workdir, systemPrompt, stream = true } = options;
200
204
 
201
205
  // Set working directory early as we need it for loading configuration
202
206
  this.workdir = workdir || process.cwd();
@@ -211,232 +215,58 @@ export class Agent {
211
215
  // Store options for dynamic configuration resolution
212
216
  this.options = options;
213
217
 
214
- this.foregroundTaskManager = new ForegroundTaskManager();
215
-
216
- // Initialize memory rule manager
217
- this.memoryRuleManager = new MemoryRuleManager({
218
+ this.container = setupAgentContainer({
219
+ options,
218
220
  workdir: this.workdir,
219
- });
220
-
221
- // Initialize MessageManager
222
- this.messageManager = new MessageManager({
223
- callbacks: {
224
- ...callbacks,
225
- onSessionIdChange: (sessionId) => {
226
- // When session ID changes (e.g. due to compression),
227
- // we update the task manager to use the root session ID
228
- // to ensure the task list remains consistent.
229
- this.taskManager.setTaskListId(
230
- this.messageManager.getRootSessionId(),
231
- );
232
- callbacks.onSessionIdChange?.(sessionId);
233
- },
221
+ configurationService: this.configurationService,
222
+ systemPrompt: this.systemPrompt,
223
+ stream: this.stream,
224
+ onSessionIdChange: () => {
225
+ this.taskManager.setTaskListId(this.messageManager.getRootSessionId());
234
226
  },
235
- workdir: this.workdir,
236
- logger: this.logger,
237
- memoryRuleManager: this.memoryRuleManager,
238
- });
239
-
240
- // Resolve taskListId once during construction to ensure stability
241
- const resolvedTaskListId =
242
- this.configurationService.getEnvironmentVars().WAVE_TASK_LIST_ID ||
243
- process.env.WAVE_TASK_LIST_ID ||
244
- this.messageManager.getRootSessionId();
245
-
246
- this.taskManager = new TaskManager(resolvedTaskListId);
247
- this.taskManager.on("tasksChange", async () => {
248
- const tasks = await this.taskManager.listTasks();
249
- this.options.callbacks?.onSessionTasksChange?.(tasks);
250
- });
251
-
252
- // Initialize BackgroundTaskManager
253
- this.backgroundTaskManager = new BackgroundTaskManager({
254
- callbacks: {
255
- ...callbacks,
256
- onTasksChange: (tasks) => {
257
- callbacks.onTasksChange?.(tasks);
258
- },
227
+ onSessionTasksChange: (tasks) => {
228
+ this.options.callbacks?.onSessionTasksChange?.(tasks);
259
229
  },
260
- workdir: this.workdir,
261
- });
262
- this.mcpManager = new McpManager({ callbacks, logger: this.logger }); // Initialize MCP manager
263
- this.lspManager =
264
- options.lspManager || new LspManager({ logger: this.logger }); // Initialize LSP manager
265
-
266
- // Initialize permission manager
267
- this.permissionManager = new PermissionManager({
268
- logger: this.logger,
269
- workdir: this.workdir,
270
- });
271
- this.permissionManager.setOnConfiguredDefaultModeChange((mode) => {
272
- this.handlePlanModeTransition(mode);
273
- this.options.callbacks?.onPermissionModeChange?.(mode);
274
- });
275
-
276
- // Initialize plan manager
277
- this.planManager = new PlanManager(this.logger);
278
-
279
- // Initialize configuration service and hooks manager
280
- this.hookManager = new HookManager(this.workdir, undefined, this.logger); // Initialize hooks manager
281
-
282
- // Initialize skill manager
283
- this.skillManager = new SkillManager({
284
- logger: this.logger,
285
- workdir: this.workdir,
286
- });
287
-
288
- // ReversionManager depends on MessageManager
289
- this.reversionManager = new ReversionManager(
290
- new ReversionService(this.messageManager.getTranscriptPath()),
291
- );
292
-
293
- // Create a wrapper for canUseTool that triggers notification hooks
294
- const canUseToolWithNotification: PermissionCallback | undefined =
295
- options.canUseTool
296
- ? async (context) => {
297
- try {
298
- // Trigger notification hooks before calling the original callback
299
- const notificationMessage = `Claude needs your permission to use ${context.toolName}`;
300
- await this.hookManager.executeHooks("Notification", {
301
- event: "Notification",
302
- projectDir: this.workdir,
303
- timestamp: new Date(),
304
- sessionId: this.sessionId,
305
- transcriptPath: this.messageManager.getTranscriptPath(),
306
- cwd: this.workdir,
307
- message: notificationMessage,
308
- notificationType: "permission_prompt",
309
- env: this.configurationService.getEnvironmentVars(), // Include configuration environment variables
310
- });
311
- } catch (error) {
312
- this.logger?.warn("Failed to execute notification hooks", {
313
- toolName: context.toolName,
314
- error: error instanceof Error ? error.message : String(error),
315
- });
316
- // Continue with permission check even if hooks fail
317
- }
318
-
319
- // Call the original callback
320
- const decision = await options.canUseTool!(context);
321
-
322
- // Handle state changes from decision
323
- if (decision.newPermissionMode) {
324
- this.setPermissionMode(decision.newPermissionMode);
325
- }
326
-
327
- if (decision.newPermissionRule) {
328
- await this.addPermissionRule(decision.newPermissionRule);
329
- }
330
-
331
- return decision;
332
- }
333
- : undefined;
334
-
335
- // Initialize tool manager with permission context
336
- this.toolManager = new ToolManager({
337
- mcpManager: this.mcpManager,
338
- lspManager: this.lspManager,
339
- logger: this.logger,
340
- permissionManager: this.permissionManager,
341
- reversionManager: this.reversionManager,
342
- permissionMode: options.permissionMode, // Let PermissionManager handle defaultMode resolution
343
- canUseToolCallback: canUseToolWithNotification,
344
- taskManager: this.taskManager,
345
- backgroundTaskManager: this.backgroundTaskManager,
346
- foregroundTaskManager: this.foregroundTaskManager,
347
- }); // Initialize tool registry with permission support
348
- this.liveConfigManager = new LiveConfigManager({
349
- workdir: this.workdir,
350
- logger: this.logger,
351
- hookManager: this.hookManager,
352
- permissionManager: this.permissionManager,
353
- configurationService: this.configurationService,
354
- }); // Initialize live configuration manager
355
-
356
- // Initialize subagent manager with all dependencies in constructor
357
- // IMPORTANT: Must be initialized AFTER MessageManager
358
- this.subagentManager = new SubagentManager({
359
- workdir: this.workdir,
360
- parentToolManager: this.toolManager,
361
- callbacks: {
362
- onSubagentUserMessageAdded: callbacks.onSubagentUserMessageAdded,
363
- onSubagentAssistantMessageAdded:
364
- callbacks.onSubagentAssistantMessageAdded,
365
- onSubagentAssistantContentUpdated:
366
- callbacks.onSubagentAssistantContentUpdated,
367
- onSubagentAssistantReasoningUpdated:
368
- callbacks.onSubagentAssistantReasoningUpdated,
369
- onSubagentToolBlockUpdated: callbacks.onSubagentToolBlockUpdated,
370
- onSubagentMessagesChange: callbacks.onSubagentMessagesChange,
371
- onSubagentLatestTotalTokensChange:
372
- callbacks.onSubagentLatestTotalTokensChange,
373
- }, // Pass subagent callbacks for forwarding
374
- logger: this.logger,
375
- getGatewayConfig: () => this.getGatewayConfig(),
376
- getModelConfig: () => this.getModelConfig(),
377
- getMaxInputTokens: () => this.getMaxInputTokens(),
378
- getLanguage: () => this.getLanguage(),
379
- hookManager: this.hookManager,
380
- onUsageAdded: (usage) => this.addUsage(usage),
381
- backgroundTaskManager: this.backgroundTaskManager,
382
- taskManager: this.taskManager,
383
- memoryRuleManager: this.memoryRuleManager,
384
- });
385
-
386
- // Initialize AI manager with resolved configuration
387
- this.aiManager = new AIManager({
388
- messageManager: this.messageManager,
389
- toolManager: this.toolManager,
390
- taskManager: this.taskManager,
391
- logger: this.logger,
392
- backgroundTaskManager: this.backgroundTaskManager,
393
- hookManager: this.hookManager,
394
- permissionManager: this.permissionManager,
395
- callbacks: {
396
- ...callbacks,
397
- onUsageAdded: (usage: Usage) => {
398
- this.addUsage(usage);
399
- },
230
+ onTasksChange: (tasks) => {
231
+ this.options.callbacks?.onTasksChange?.(tasks);
400
232
  },
401
- workdir: this.workdir,
402
- systemPrompt: this.systemPrompt,
403
- stream: this.stream, // Pass streaming mode flag
404
- reversionManager: this.reversionManager,
233
+ onPermissionModeChange: (mode) => {
234
+ this.options.callbacks?.onPermissionModeChange?.(mode);
235
+ },
236
+ handlePlanModeTransition: (mode) => {
237
+ this.handlePlanModeTransition(mode);
238
+ },
239
+ setPermissionMode: (mode) => {
240
+ this.setPermissionMode(mode);
241
+ },
242
+ addPermissionRule: (rule) => this.addPermissionRule(rule),
243
+ addUsage: (usage) => this.addUsage(usage),
405
244
  getGatewayConfig: () => this.getGatewayConfig(),
406
245
  getModelConfig: () => this.getModelConfig(),
407
246
  getMaxInputTokens: () => this.getMaxInputTokens(),
408
247
  getLanguage: () => this.getLanguage(),
409
- getEnvironmentVars: () => this.configurationService.getEnvironmentVars(), // Provide access to configuration environment variables
410
248
  });
411
249
 
412
- // Initialize command manager
413
- this.slashCommandManager = new SlashCommandManager({
414
- messageManager: this.messageManager,
415
- aiManager: this.aiManager,
416
- backgroundTaskManager: this.backgroundTaskManager,
417
- taskManager: this.taskManager,
418
- workdir: this.workdir,
419
- logger: this.logger,
420
- });
421
-
422
- // Initialize plugin manager
423
- this.pluginManager = new PluginManager({
424
- workdir: this.workdir,
425
- logger: this.logger,
426
- slashCommandManager: this.slashCommandManager,
427
- mcpManager: this.mcpManager,
428
- lspManager:
429
- this.lspManager instanceof LspManager ? this.lspManager : undefined,
430
- hookManager: this.hookManager,
431
- skillManager: this.skillManager,
432
- configurationService: this.configurationService,
433
- });
434
-
435
- // Initialize bash manager
436
- this.bashManager = new BashManager({
437
- messageManager: this.messageManager,
438
- workdir: this.workdir,
439
- });
250
+ // Retrieve managers from container
251
+ this.foregroundTaskManager = this.container.get("ForegroundTaskManager")!;
252
+ this.memoryRuleManager = this.container.get("MemoryRuleManager")!;
253
+ this.messageManager = this.container.get("MessageManager")!;
254
+ this.taskManager = this.container.get("TaskManager")!;
255
+ this.backgroundTaskManager = this.container.get("BackgroundTaskManager")!;
256
+ this.mcpManager = this.container.get("McpManager")!;
257
+ this.lspManager = this.container.get("LspManager")!;
258
+ this.permissionManager = this.container.get("PermissionManager")!;
259
+ this.planManager = this.container.get("PlanManager")!;
260
+ this.hookManager = this.container.get("HookManager")!;
261
+ this.skillManager = this.container.get("SkillManager")!;
262
+ this.reversionManager = this.container.get("ReversionManager")!;
263
+ this.toolManager = this.container.get("ToolManager")!;
264
+ this.liveConfigManager = this.container.get("LiveConfigManager")!;
265
+ this.subagentManager = this.container.get("SubagentManager")!;
266
+ this.aiManager = this.container.get("AIManager")!;
267
+ this.slashCommandManager = this.container.get("SlashCommandManager")!;
268
+ this.pluginManager = this.container.get("PluginManager")!;
269
+ this.bashManager = this.container.get("BashManager")!;
440
270
 
441
271
  // Set initial permission mode if provided
442
272
  if (options.permissionMode) {
@@ -635,11 +465,12 @@ export class Agent {
635
465
  // Initialize SubagentManager (load and cache configurations)
636
466
  await this.subagentManager.initialize();
637
467
 
638
- // Initialize built-in tools with dependencies
639
- this.toolManager.initializeBuiltInTools({
640
- subagentManager: this.subagentManager,
641
- skillManager: this.skillManager,
642
- });
468
+ // Register managers in container for tool access
469
+ this.container.register("SubagentManager", this.subagentManager);
470
+ this.container.register("SkillManager", this.skillManager);
471
+
472
+ // Initialize built-in tools
473
+ this.toolManager.initializeBuiltInTools();
643
474
 
644
475
  // Initialize plugins
645
476
  await this.pluginManager.loadPlugins(this.options.plugins || []);
@@ -701,59 +532,6 @@ export class Agent {
701
532
  this.logger?.debug("Initializing live configuration reload...");
702
533
  await this.liveConfigManager.initialize();
703
534
  this.logger?.debug("Live configuration reload initialized successfully");
704
-
705
- // Update permission manager with configuration-based defaultMode
706
- const currentConfig = this.liveConfigManager.getCurrentConfiguration();
707
- if (currentConfig?.permissions?.defaultMode) {
708
- this.logger?.debug(
709
- "Applying configured defaultMode to PermissionManager",
710
- {
711
- defaultMode: currentConfig.permissions.defaultMode,
712
- },
713
- );
714
- this.permissionManager.updateConfiguredDefaultMode(
715
- currentConfig.permissions.defaultMode,
716
- );
717
- }
718
-
719
- // Update permission manager with configuration-based allowed rules
720
- if (currentConfig?.permissions?.allow) {
721
- this.logger?.debug(
722
- "Applying configured allowed rules to PermissionManager",
723
- {
724
- count: currentConfig.permissions.allow.length,
725
- },
726
- );
727
- this.permissionManager.updateAllowedRules(
728
- currentConfig.permissions.allow,
729
- );
730
- }
731
-
732
- // Update permission manager with configuration-based denied rules
733
- if (currentConfig?.permissions?.deny) {
734
- this.logger?.debug(
735
- "Applying configured denied rules to PermissionManager",
736
- {
737
- count: currentConfig.permissions.deny.length,
738
- },
739
- );
740
- this.permissionManager.updateDeniedRules(
741
- currentConfig.permissions.deny,
742
- );
743
- }
744
-
745
- // Update permission manager with configuration-based additionalDirectories
746
- if (currentConfig?.permissions?.additionalDirectories) {
747
- this.logger?.debug(
748
- "Applying configured additionalDirectories to PermissionManager",
749
- {
750
- count: currentConfig.permissions.additionalDirectories.length,
751
- },
752
- );
753
- this.permissionManager.updateAdditionalDirectories(
754
- currentConfig.permissions.additionalDirectories,
755
- );
756
- }
757
535
  } catch (error) {
758
536
  this.logger?.error(
759
537
  "Failed to initialize live configuration reload:",
@@ -2,14 +2,12 @@ export const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
2
2
  export const BASH_TOOL_NAME = "Bash";
3
3
  export const TASK_OUTPUT_TOOL_NAME = "TaskOutput";
4
4
  export const TASK_STOP_TOOL_NAME = "TaskStop";
5
- export const DELETE_FILE_TOOL_NAME = "Delete";
6
5
  export const EDIT_TOOL_NAME = "Edit";
7
6
  export const EXIT_PLAN_MODE_TOOL_NAME = "ExitPlanMode";
8
7
  export const GLOB_TOOL_NAME = "Glob";
9
8
  export const GREP_TOOL_NAME = "Grep";
10
9
  export const LSP_TOOL_NAME = "LSP";
11
10
  export const LS_TOOL_NAME = "LS";
12
- export const MULTI_EDIT_TOOL_NAME = "MultiEdit";
13
11
  export const READ_TOOL_NAME = "Read";
14
12
  export const SKILL_TOOL_NAME = "Skill";
15
13
  export const TASK_TOOL_NAME = "Task";
@@ -0,0 +1,224 @@
1
+ import { Container } from "../utils/container.js";
2
+ import { PluginManager } from "../managers/pluginManager.js";
3
+ import { PluginScopeManager } from "../managers/pluginScopeManager.js";
4
+ import { MarketplaceService } from "../services/MarketplaceService.js";
5
+ import { ConfigurationService } from "../services/configurationService.js";
6
+ import {
7
+ Scope,
8
+ InstalledPlugin,
9
+ KnownMarketplace,
10
+ MarketplaceManifest,
11
+ InstalledPluginsRegistry,
12
+ MarketplacePluginStatus,
13
+ } from "../types/index.js";
14
+
15
+ /**
16
+ * PluginCore
17
+ *
18
+ * Encapsulates plugin management logic, providing a high-level API for
19
+ * installing, uninstalling, enabling, and disabling plugins.
20
+ */
21
+ export class PluginCore {
22
+ private container: Container;
23
+ private pluginManager: PluginManager;
24
+ private pluginScopeManager: PluginScopeManager;
25
+ private marketplaceService: MarketplaceService;
26
+ private configurationService: ConfigurationService;
27
+ private workdir: string;
28
+
29
+ constructor(workdir: string = process.cwd()) {
30
+ this.workdir = workdir;
31
+ this.container = new Container();
32
+ this.configurationService = new ConfigurationService();
33
+ this.marketplaceService = new MarketplaceService();
34
+
35
+ // Wire up ConfigurationService in the container for PluginManager to use
36
+ this.container.register("ConfigurationService", this.configurationService);
37
+
38
+ this.pluginManager = new PluginManager(this.container, {
39
+ workdir: this.workdir,
40
+ });
41
+
42
+ this.pluginScopeManager = new PluginScopeManager({
43
+ workdir: this.workdir,
44
+ configurationService: this.configurationService,
45
+ pluginManager: this.pluginManager,
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Installs a plugin from a marketplace
51
+ */
52
+ async installPlugin(
53
+ pluginId: string,
54
+ scope?: Scope,
55
+ ): Promise<InstalledPlugin> {
56
+ const installedPlugin =
57
+ await this.marketplaceService.installPlugin(pluginId);
58
+ if (scope) {
59
+ await this.enablePlugin(pluginId, scope);
60
+ }
61
+ return installedPlugin;
62
+ }
63
+
64
+ /**
65
+ * Uninstalls a plugin and removes it from all configuration scopes
66
+ */
67
+ async uninstallPlugin(pluginId: string): Promise<void> {
68
+ await this.marketplaceService.uninstallPlugin(pluginId);
69
+ await this.pluginScopeManager.removePluginFromAllScopes(pluginId);
70
+ }
71
+
72
+ /**
73
+ * Enables a plugin in the specified scope. If no scope is provided, it tries to find
74
+ * the scope where the plugin is already configured, or defaults to "user".
75
+ */
76
+ async enablePlugin(pluginId: string, scope?: Scope): Promise<Scope> {
77
+ const targetScope = scope || this.findPluginScope(pluginId) || "user";
78
+ await this.pluginScopeManager.enablePlugin(targetScope, pluginId);
79
+ return targetScope;
80
+ }
81
+
82
+ /**
83
+ * Disables a plugin in the specified scope. If no scope is provided, it tries to find
84
+ * the scope where the plugin is already configured, or defaults to "user".
85
+ */
86
+ async disablePlugin(pluginId: string, scope?: Scope): Promise<Scope> {
87
+ const targetScope = scope || this.findPluginScope(pluginId) || "user";
88
+ await this.pluginScopeManager.disablePlugin(targetScope, pluginId);
89
+ return targetScope;
90
+ }
91
+
92
+ /**
93
+ * Updates an installed plugin to the latest version from its marketplace
94
+ */
95
+ async updatePlugin(pluginId: string): Promise<InstalledPlugin> {
96
+ return await this.marketplaceService.updatePlugin(pluginId);
97
+ }
98
+
99
+ /**
100
+ * Lists all plugins from all registered marketplaces with their installation and enabled status
101
+ */
102
+ async listPlugins(): Promise<{
103
+ plugins: MarketplacePluginStatus[];
104
+ mergedEnabled: Record<string, boolean>;
105
+ }> {
106
+ const installedPlugins =
107
+ await this.marketplaceService.getInstalledPlugins();
108
+ const marketplaces = await this.marketplaceService.listMarketplaces();
109
+ const mergedEnabled = this.configurationService.getMergedEnabledPlugins(
110
+ this.workdir,
111
+ );
112
+
113
+ const allMarketplacePlugins: MarketplacePluginStatus[] = [];
114
+
115
+ for (const m of marketplaces) {
116
+ try {
117
+ const manifest = await this.marketplaceService.loadMarketplaceManifest(
118
+ this.marketplaceService.getMarketplacePath(m),
119
+ );
120
+ manifest.plugins.forEach((p) => {
121
+ const pluginId = `${p.name}@${m.name}`;
122
+ const installed = installedPlugins.plugins.find(
123
+ (ip) => ip.name === p.name && ip.marketplace === m.name,
124
+ );
125
+ allMarketplacePlugins.push({
126
+ ...p,
127
+ marketplace: m.name,
128
+ installed: !!installed,
129
+ version: installed?.version,
130
+ cachePath: installed?.cachePath,
131
+ projectPath: installed?.projectPath,
132
+ scope:
133
+ this.pluginScopeManager.findPluginScope(pluginId) || undefined,
134
+ });
135
+ });
136
+ } catch {
137
+ // Skip marketplaces that fail to load
138
+ }
139
+ }
140
+
141
+ return {
142
+ plugins: allMarketplacePlugins,
143
+ mergedEnabled,
144
+ };
145
+ }
146
+
147
+ /**
148
+ * Adds a new marketplace
149
+ */
150
+ async addMarketplace(input: string): Promise<KnownMarketplace> {
151
+ return await this.marketplaceService.addMarketplace(input);
152
+ }
153
+
154
+ /**
155
+ * Removes a marketplace by name
156
+ */
157
+ async removeMarketplace(name: string): Promise<void> {
158
+ await this.marketplaceService.removeMarketplace(name);
159
+ }
160
+
161
+ /**
162
+ * Updates a specific marketplace or all marketplaces
163
+ */
164
+ async updateMarketplace(name?: string): Promise<void> {
165
+ await this.marketplaceService.updateMarketplace(name);
166
+ }
167
+
168
+ /**
169
+ * Lists all registered marketplaces
170
+ */
171
+ async listMarketplaces(): Promise<KnownMarketplace[]> {
172
+ return await this.marketplaceService.listMarketplaces();
173
+ }
174
+
175
+ /**
176
+ * Gets the registry of all installed plugins
177
+ */
178
+ async getInstalledPlugins(): Promise<InstalledPluginsRegistry> {
179
+ return await this.marketplaceService.getInstalledPlugins();
180
+ }
181
+
182
+ /**
183
+ * Gets the merged enabled state of all plugins across all scopes
184
+ */
185
+ getMergedEnabledPlugins(): Record<string, boolean> {
186
+ return this.configurationService.getMergedEnabledPlugins(this.workdir);
187
+ }
188
+
189
+ /**
190
+ * Loads a marketplace manifest from a local path
191
+ */
192
+ async loadMarketplaceManifest(
193
+ marketplacePath: string,
194
+ ): Promise<MarketplaceManifest> {
195
+ return await this.marketplaceService.loadMarketplaceManifest(
196
+ marketplacePath,
197
+ );
198
+ }
199
+
200
+ /**
201
+ * Resolves the local path for a marketplace
202
+ */
203
+ getMarketplacePath(marketplace: KnownMarketplace): string {
204
+ return this.marketplaceService.getMarketplacePath(marketplace);
205
+ }
206
+
207
+ /**
208
+ * Finds the scope where a plugin is currently enabled/disabled
209
+ */
210
+ findPluginScope(pluginId: string): Scope | null {
211
+ return this.pluginScopeManager.findPluginScope(pluginId);
212
+ }
213
+
214
+ /**
215
+ * Removes a plugin from the enabled plugins in the specified scope
216
+ */
217
+ async removeEnabledPlugin(scope: Scope, pluginId: string): Promise<void> {
218
+ await this.configurationService.removeEnabledPlugin(
219
+ this.workdir,
220
+ scope,
221
+ pluginId,
222
+ );
223
+ }
224
+ }
package/src/index.ts CHANGED
@@ -4,18 +4,13 @@ export * from "./services/memory.js";
4
4
  export * from "./services/session.js";
5
5
  export * from "./services/hook.js";
6
6
  export * from "./services/jsonlHandler.js";
7
- export * from "./services/configurationService.js"; // New configuration management service
8
- export * from "./services/MarketplaceService.js";
9
7
 
10
8
  // Export constants
11
9
  export * from "./constants/tools.js";
12
10
 
13
- // Export managers
14
- export * from "./managers/pluginManager.js";
15
- export * from "./managers/pluginScopeManager.js";
16
-
17
11
  // Export main agent
18
12
  export * from "./agent.js";
13
+ export * from "./core/plugin.js";
19
14
 
20
15
  // Export all utilities
21
16
  export * from "./utils/bashParser.js";
@@ -5,6 +5,8 @@ import * as path from "node:path";
5
5
  import * as os from "node:os";
6
6
  import { logger } from "../utils/globalLogger.js";
7
7
 
8
+ import { Container } from "../utils/container.js";
9
+
8
10
  export interface MemoryRuleRegistryState {
9
11
  /** All discovered rules, indexed by ID */
10
12
  rules: Record<string, MemoryRule>;
@@ -25,7 +27,10 @@ export class MemoryRuleManager {
25
27
  private workdir: string;
26
28
  private service: MemoryRuleService;
27
29
 
28
- constructor(options: MemoryRuleManagerOptions) {
30
+ constructor(
31
+ private container: Container,
32
+ options: MemoryRuleManagerOptions,
33
+ ) {
29
34
  this.workdir = options.workdir;
30
35
  this.service = new MemoryRuleService();
31
36
  }