wave-agent-sdk 0.7.2 → 0.8.1

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 +9 -79
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +85 -302
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -1
  7. package/dist/managers/aiManager.d.ts.map +1 -1
  8. package/dist/managers/aiManager.js +20 -13
  9. package/dist/managers/backgroundTaskManager.d.ts +1 -1
  10. package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
  11. package/dist/managers/backgroundTaskManager.js +1 -1
  12. package/dist/managers/{bashManager.d.ts → bangManager.d.ts} +4 -4
  13. package/dist/managers/{bashManager.d.ts.map → bangManager.d.ts.map} +1 -1
  14. package/dist/managers/{bashManager.js → bangManager.js} +5 -6
  15. package/dist/managers/hookManager.d.ts.map +1 -1
  16. package/dist/managers/hookManager.js +12 -3
  17. package/dist/managers/messageManager.d.ts +18 -6
  18. package/dist/managers/messageManager.d.ts.map +1 -1
  19. package/dist/managers/messageManager.js +42 -20
  20. package/dist/managers/permissionManager.d.ts +22 -1
  21. package/dist/managers/permissionManager.d.ts.map +1 -1
  22. package/dist/managers/permissionManager.js +106 -85
  23. package/dist/managers/planManager.d.ts +6 -0
  24. package/dist/managers/planManager.d.ts.map +1 -1
  25. package/dist/managers/planManager.js +21 -0
  26. package/dist/managers/skillManager.d.ts +7 -2
  27. package/dist/managers/skillManager.d.ts.map +1 -1
  28. package/dist/managers/skillManager.js +30 -10
  29. package/dist/managers/slashCommandManager.d.ts +7 -0
  30. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  31. package/dist/managers/slashCommandManager.js +59 -59
  32. package/dist/managers/subagentManager.d.ts +4 -0
  33. package/dist/managers/subagentManager.d.ts.map +1 -1
  34. package/dist/managers/subagentManager.js +47 -13
  35. package/dist/managers/toolManager.d.ts +7 -1
  36. package/dist/managers/toolManager.d.ts.map +1 -1
  37. package/dist/managers/toolManager.js +15 -2
  38. package/dist/prompts/index.d.ts +0 -4
  39. package/dist/prompts/index.d.ts.map +1 -1
  40. package/dist/prompts/index.js +0 -9
  41. package/dist/services/aiService.d.ts.map +1 -1
  42. package/dist/services/aiService.js +9 -9
  43. package/dist/services/configurationService.d.ts +2 -2
  44. package/dist/services/configurationService.d.ts.map +1 -1
  45. package/dist/services/configurationService.js +4 -4
  46. package/dist/services/hook.d.ts.map +1 -1
  47. package/dist/services/hook.js +6 -0
  48. package/dist/services/initializationService.d.ts +44 -0
  49. package/dist/services/initializationService.d.ts.map +1 -0
  50. package/dist/services/initializationService.js +170 -0
  51. package/dist/services/interactionService.d.ts +29 -0
  52. package/dist/services/interactionService.d.ts.map +1 -0
  53. package/dist/services/interactionService.js +97 -0
  54. package/dist/services/session.js +1 -1
  55. package/dist/services/taskManager.d.ts +5 -0
  56. package/dist/services/taskManager.d.ts.map +1 -1
  57. package/dist/services/taskManager.js +16 -2
  58. package/dist/tools/bashTool.d.ts.map +1 -1
  59. package/dist/tools/bashTool.js +7 -18
  60. package/dist/tools/editTool.js +1 -1
  61. package/dist/tools/exitPlanMode.js +1 -1
  62. package/dist/tools/globTool.d.ts.map +1 -1
  63. package/dist/tools/globTool.js +12 -2
  64. package/dist/tools/lspTool.d.ts +2 -0
  65. package/dist/tools/lspTool.d.ts.map +1 -1
  66. package/dist/tools/lspTool.js +144 -52
  67. package/dist/tools/skillTool.d.ts.map +1 -1
  68. package/dist/tools/skillTool.js +97 -2
  69. package/dist/tools/taskManagementTools.d.ts.map +1 -1
  70. package/dist/tools/taskManagementTools.js +23 -2
  71. package/dist/tools/taskTool.d.ts.map +1 -1
  72. package/dist/tools/taskTool.js +9 -15
  73. package/dist/tools/types.d.ts +1 -2
  74. package/dist/tools/types.d.ts.map +1 -1
  75. package/dist/tools/writeTool.js +1 -1
  76. package/dist/types/agent.d.ts +64 -0
  77. package/dist/types/agent.d.ts.map +1 -0
  78. package/dist/types/agent.js +1 -0
  79. package/dist/types/commands.d.ts +0 -4
  80. package/dist/types/commands.d.ts.map +1 -1
  81. package/dist/types/config.d.ts +1 -1
  82. package/dist/types/config.d.ts.map +1 -1
  83. package/dist/types/hooks.d.ts +3 -1
  84. package/dist/types/hooks.d.ts.map +1 -1
  85. package/dist/types/hooks.js +1 -0
  86. package/dist/types/index.d.ts +1 -0
  87. package/dist/types/index.d.ts.map +1 -1
  88. package/dist/types/index.js +1 -0
  89. package/dist/types/messaging.d.ts +3 -3
  90. package/dist/types/messaging.d.ts.map +1 -1
  91. package/dist/types/skills.d.ts +13 -0
  92. package/dist/types/skills.d.ts.map +1 -1
  93. package/dist/utils/commandArgumentParser.d.ts.map +1 -1
  94. package/dist/utils/commandArgumentParser.js +7 -0
  95. package/dist/utils/commandPathResolver.d.ts +3 -36
  96. package/dist/utils/commandPathResolver.d.ts.map +1 -1
  97. package/dist/utils/commandPathResolver.js +16 -93
  98. package/dist/utils/configValidator.d.ts +2 -2
  99. package/dist/utils/configValidator.d.ts.map +1 -1
  100. package/dist/utils/configValidator.js +4 -6
  101. package/dist/utils/containerSetup.d.ts +3 -4
  102. package/dist/utils/containerSetup.d.ts.map +1 -1
  103. package/dist/utils/containerSetup.js +14 -9
  104. package/dist/utils/customCommands.d.ts +2 -3
  105. package/dist/utils/customCommands.d.ts.map +1 -1
  106. package/dist/utils/customCommands.js +20 -60
  107. package/dist/utils/gitUtils.d.ts +25 -0
  108. package/dist/utils/gitUtils.d.ts.map +1 -1
  109. package/dist/utils/gitUtils.js +75 -0
  110. package/dist/utils/markdownParser.d.ts +4 -0
  111. package/dist/utils/markdownParser.d.ts.map +1 -1
  112. package/dist/utils/markdownParser.js +33 -0
  113. package/dist/utils/messageOperations.d.ts +16 -7
  114. package/dist/utils/messageOperations.d.ts.map +1 -1
  115. package/dist/utils/messageOperations.js +45 -20
  116. package/dist/utils/nameGenerator.d.ts +1 -1
  117. package/dist/utils/nameGenerator.d.ts.map +1 -1
  118. package/dist/utils/nameGenerator.js +10 -6
  119. package/dist/utils/skillParser.d.ts.map +1 -1
  120. package/dist/utils/skillParser.js +48 -0
  121. package/package.json +1 -1
  122. package/src/agent.ts +103 -458
  123. package/src/index.ts +2 -2
  124. package/src/managers/aiManager.ts +23 -17
  125. package/src/managers/backgroundTaskManager.ts +2 -2
  126. package/src/managers/{bashManager.ts → bangManager.ts} +11 -8
  127. package/src/managers/hookManager.ts +13 -3
  128. package/src/managers/messageManager.ts +55 -26
  129. package/src/managers/permissionManager.ts +121 -98
  130. package/src/managers/planManager.ts +26 -0
  131. package/src/managers/skillManager.ts +51 -14
  132. package/src/managers/slashCommandManager.ts +83 -73
  133. package/src/managers/subagentManager.ts +57 -13
  134. package/src/managers/toolManager.ts +22 -2
  135. package/src/prompts/index.ts +0 -15
  136. package/src/services/aiService.ts +12 -15
  137. package/src/services/configurationService.ts +4 -4
  138. package/src/services/hook.ts +7 -0
  139. package/src/services/initializationService.ts +291 -0
  140. package/src/services/interactionService.ts +171 -0
  141. package/src/services/session.ts +1 -1
  142. package/src/services/taskManager.ts +18 -2
  143. package/src/tools/bashTool.ts +8 -18
  144. package/src/tools/editTool.ts +1 -1
  145. package/src/tools/exitPlanMode.ts +1 -1
  146. package/src/tools/globTool.ts +15 -2
  147. package/src/tools/lsTool.ts +1 -1
  148. package/src/tools/lspTool.ts +184 -52
  149. package/src/tools/skillTool.ts +127 -2
  150. package/src/tools/taskManagementTools.ts +32 -2
  151. package/src/tools/taskTool.ts +13 -15
  152. package/src/tools/types.ts +1 -2
  153. package/src/tools/writeTool.ts +1 -1
  154. package/src/types/agent.ts +83 -0
  155. package/src/types/commands.ts +0 -6
  156. package/src/types/config.ts +1 -1
  157. package/src/types/hooks.ts +5 -1
  158. package/src/types/index.ts +1 -0
  159. package/src/types/messaging.ts +3 -3
  160. package/src/types/skills.ts +13 -0
  161. package/src/utils/commandArgumentParser.ts +8 -0
  162. package/src/utils/commandPathResolver.ts +14 -117
  163. package/src/utils/configValidator.ts +5 -9
  164. package/src/utils/containerSetup.ts +17 -14
  165. package/src/utils/customCommands.ts +20 -83
  166. package/src/utils/gitUtils.ts +75 -0
  167. package/src/utils/markdownParser.ts +47 -0
  168. package/src/utils/messageOperations.ts +58 -28
  169. package/src/utils/nameGenerator.ts +10 -6
  170. package/src/utils/skillParser.ts +52 -0
  171. package/dist/managers/backgroundBashManager.d.ts +0 -27
  172. package/dist/managers/backgroundBashManager.d.ts.map +0 -1
  173. package/dist/managers/backgroundBashManager.js +0 -169
  174. package/src/managers/backgroundBashManager.ts +0 -206
@@ -0,0 +1,44 @@
1
+ import type { Message, Logger, AgentOptions, ILspManager } from "../types/index.js";
2
+ import type { SkillManager } from "../managers/skillManager.js";
3
+ import type { SubagentManager } from "../managers/subagentManager.js";
4
+ import type { Container } from "../utils/container.js";
5
+ import type { ToolManager } from "../managers/toolManager.js";
6
+ import type { PluginManager } from "../managers/pluginManager.js";
7
+ import type { SlashCommandManager } from "../managers/slashCommandManager.js";
8
+ import type { McpManager } from "../managers/mcpManager.js";
9
+ import type { ConfigurationService } from "./configurationService.js";
10
+ import type { HookManager } from "../managers/hookManager.js";
11
+ import type { MessageManager } from "../managers/messageManager.js";
12
+ import type { MemoryRuleManager } from "../managers/MemoryRuleManager.js";
13
+ import type { LiveConfigManager } from "../managers/liveConfigManager.js";
14
+ import type { TaskManager } from "./taskManager.js";
15
+ export interface InitializationContext {
16
+ skillManager: SkillManager;
17
+ subagentManager: SubagentManager;
18
+ container: Container;
19
+ toolManager: ToolManager;
20
+ pluginManager: PluginManager;
21
+ options: AgentOptions;
22
+ slashCommandManager: SlashCommandManager;
23
+ logger?: Logger;
24
+ mcpManager: McpManager;
25
+ workdir: string;
26
+ lspManager: ILspManager;
27
+ configurationService: ConfigurationService;
28
+ hookManager: HookManager;
29
+ messageManager: MessageManager;
30
+ memoryRuleManager: MemoryRuleManager;
31
+ liveConfigManager: LiveConfigManager;
32
+ taskManager: TaskManager;
33
+ setProjectMemory: (content: string) => void;
34
+ setUserMemory: (content: string) => void;
35
+ resolveAndValidateConfig: () => void;
36
+ }
37
+ export declare class InitializationService {
38
+ static initialize(context: InitializationContext, options?: {
39
+ restoreSessionId?: string;
40
+ continueLastSession?: boolean;
41
+ messages?: Message[];
42
+ }): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=initializationService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initializationService.d.ts","sourceRoot":"","sources":["../../src/services/initializationService.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,OAAO,EACP,MAAM,EACN,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,WAAW,CAAC;IACxB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAE,WAAW,CAAC;IACzB,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,wBAAwB,EAAE,MAAM,IAAI,CAAC;CACtC;AAED,qBAAa,qBAAqB;WACZ,UAAU,CAC5B,OAAO,EAAE,qBAAqB,EAC9B,OAAO,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,CAAC;CAwOjB"}
@@ -0,0 +1,170 @@
1
+ import path from "path";
2
+ import * as fs from "fs/promises";
3
+ import os from "os";
4
+ import { handleSessionRestoration } from "./session.js";
5
+ import { setGlobalLogger } from "../utils/globalLogger.js";
6
+ import { LspManager } from "../managers/lspManager.js";
7
+ export class InitializationService {
8
+ static async initialize(context, options) {
9
+ const { skillManager, subagentManager, container, toolManager, pluginManager, options: agentOptions, slashCommandManager, logger, mcpManager, workdir, lspManager, configurationService, hookManager, messageManager, memoryRuleManager, liveConfigManager, taskManager, setProjectMemory, setUserMemory, resolveAndValidateConfig, } = context;
10
+ // Initialize managers first
11
+ try {
12
+ // Initialize SkillManager
13
+ await skillManager.initialize();
14
+ // Initialize SubagentManager (load and cache configurations)
15
+ await subagentManager.initialize();
16
+ // Register managers in container for tool access
17
+ container.register("SubagentManager", subagentManager);
18
+ container.register("SkillManager", skillManager);
19
+ // Initialize built-in tools
20
+ toolManager.initializeBuiltInTools();
21
+ // Initialize plugins
22
+ await pluginManager.loadPlugins(agentOptions.plugins || []);
23
+ // Register skill commands
24
+ slashCommandManager.registerSkillCommands(skillManager.getAvailableSkills());
25
+ }
26
+ catch (error) {
27
+ logger?.error("Failed to initialize managers and tools:", error);
28
+ // Don't throw error to prevent app startup failure
29
+ }
30
+ // Initialize MCP servers with auto-connect
31
+ try {
32
+ await mcpManager.initialize(workdir, true);
33
+ if (lspManager instanceof LspManager) {
34
+ await lspManager.initialize(workdir);
35
+ }
36
+ }
37
+ catch (error) {
38
+ logger?.error("Failed to initialize MCP servers:", error);
39
+ // Don't throw error to prevent app startup failure
40
+ }
41
+ // Initialize hooks configuration
42
+ try {
43
+ // Load hooks configuration using ConfigurationService
44
+ logger?.debug("Loading hooks configuration...");
45
+ const configResult = await configurationService.loadMergedConfiguration(workdir);
46
+ hookManager.loadConfigurationFromWaveConfig(configResult.configuration);
47
+ // Update plugin manager with enabled plugins configuration
48
+ if (configResult.configuration?.enabledPlugins) {
49
+ pluginManager.updateEnabledPlugins(configResult.configuration.enabledPlugins);
50
+ }
51
+ // Initialize permission manager with loaded rules
52
+ if (configResult.configuration?.permissions) {
53
+ const permissionManager = context.container.get("PermissionManager");
54
+ if (permissionManager) {
55
+ if (configResult.configuration.permissions.allow) {
56
+ permissionManager.updateAllowedRules(configResult.configuration.permissions.allow);
57
+ }
58
+ if (configResult.configuration.permissions.deny) {
59
+ permissionManager.updateDeniedRules(configResult.configuration.permissions.deny);
60
+ }
61
+ if (configResult.configuration.permissions.defaultMode) {
62
+ permissionManager.updateConfiguredDefaultMode(configResult.configuration.permissions.defaultMode);
63
+ }
64
+ }
65
+ }
66
+ logger?.debug("Hooks system initialized successfully");
67
+ }
68
+ catch (error) {
69
+ logger?.error("Failed to initialize hooks system:", error);
70
+ // Don't throw error to prevent app startup failure
71
+ }
72
+ // Trigger WorktreeCreate hook if this is a new worktree
73
+ if (agentOptions.isNewWorktree && hookManager) {
74
+ try {
75
+ logger?.info(`Triggering WorktreeCreate hook for ${agentOptions.worktreeName}...`);
76
+ const hookResults = await hookManager.executeHooks("WorktreeCreate", {
77
+ event: "WorktreeCreate",
78
+ projectDir: workdir,
79
+ timestamp: new Date(),
80
+ sessionId: messageManager.getSessionId(),
81
+ transcriptPath: messageManager.getTranscriptPath(),
82
+ cwd: workdir,
83
+ worktreeName: agentOptions.worktreeName,
84
+ env: configurationService.getEnvironmentVars(),
85
+ });
86
+ // Process hook results
87
+ hookManager.processHookResults("WorktreeCreate", hookResults, messageManager);
88
+ }
89
+ catch (error) {
90
+ logger?.warn("WorktreeCreate hooks execution failed:", error);
91
+ }
92
+ }
93
+ // Resolve and validate configuration after loading settings.json
94
+ resolveAndValidateConfig();
95
+ // Set global logger for SDK-wide access before discovering rules
96
+ setGlobalLogger(logger || null);
97
+ // Discover modular memory rules
98
+ try {
99
+ await memoryRuleManager.discoverRules();
100
+ }
101
+ catch (error) {
102
+ logger?.error("Failed to discover memory rules:", error);
103
+ }
104
+ // Initialize live configuration reload
105
+ try {
106
+ logger?.debug("Initializing live configuration reload...");
107
+ await liveConfigManager.initialize();
108
+ logger?.debug("Live configuration reload initialized successfully");
109
+ }
110
+ catch (error) {
111
+ logger?.error("Failed to initialize live configuration reload:", error);
112
+ // Don't throw error to prevent app startup failure - continue without live reload
113
+ }
114
+ // Load memory files during initialization
115
+ try {
116
+ logger?.debug("Loading memory files...");
117
+ // Load project memory from AGENTS.md (bypass memory store for direct file access)
118
+ try {
119
+ const projectMemoryPath = path.join(workdir, "AGENTS.md");
120
+ const projectMemoryContent = await fs.readFile(projectMemoryPath, "utf-8");
121
+ setProjectMemory(projectMemoryContent);
122
+ logger?.debug("Project memory loaded successfully");
123
+ }
124
+ catch (error) {
125
+ setProjectMemory("");
126
+ logger?.debug("Project memory file not found or unreadable, using empty content:", error instanceof Error ? error.message : String(error));
127
+ }
128
+ // Load user memory (bypass memory store for direct file access)
129
+ try {
130
+ const userMemoryPath = path.join(os.homedir(), ".wave", "AGENTS.md");
131
+ const userMemoryContent = await fs.readFile(userMemoryPath, "utf-8");
132
+ setUserMemory(userMemoryContent);
133
+ logger?.debug("User memory loaded successfully");
134
+ }
135
+ catch (error) {
136
+ setUserMemory("");
137
+ logger?.debug("User memory file not found or unreadable, using empty content:", error instanceof Error ? error.message : String(error));
138
+ }
139
+ logger?.debug("Memory initialization completed");
140
+ }
141
+ catch (error) {
142
+ // Ensure memory is always initialized even if loading fails
143
+ setProjectMemory("");
144
+ setUserMemory("");
145
+ logger?.error("Failed to load memory files:", error);
146
+ // Don't throw error to prevent app startup failure
147
+ }
148
+ // Handle session restoration or set provided messages
149
+ if (options?.messages) {
150
+ // If messages are provided, use them directly (useful for testing)
151
+ messageManager.setMessages(options.messages);
152
+ // Rebuild usage array from restored messages
153
+ messageManager.rebuildUsageFromMessages(options.messages);
154
+ }
155
+ else {
156
+ // Otherwise, handle session restoration
157
+ const sessionToRestore = await handleSessionRestoration(options?.restoreSessionId, options?.continueLastSession, messageManager.getWorkdir());
158
+ // Rebuild usage array from restored messages
159
+ messageManager.rebuildUsageFromMessages(sessionToRestore?.messages || []);
160
+ if (sessionToRestore) {
161
+ messageManager.initializeFromSession(sessionToRestore);
162
+ // Update task manager with the root session ID to ensure continuity across compressions
163
+ taskManager.setTaskListId(sessionToRestore.rootSessionId || sessionToRestore.id);
164
+ // After session is initialized, load tasks for the session
165
+ const tasks = await taskManager.listTasks();
166
+ agentOptions.callbacks?.onTasksChange?.(tasks);
167
+ }
168
+ }
169
+ }
170
+ }
@@ -0,0 +1,29 @@
1
+ import type { Logger, AgentOptions } from "../types/index.js";
2
+ import type { MessageManager } from "../managers/messageManager.js";
3
+ import type { SlashCommandManager } from "../managers/slashCommandManager.js";
4
+ import type { HookManager } from "../managers/hookManager.js";
5
+ import type { ConfigurationService } from "./configurationService.js";
6
+ import type { AIManager } from "../managers/aiManager.js";
7
+ import type { SubagentManager } from "../managers/subagentManager.js";
8
+ import type { TaskManager } from "./taskManager.js";
9
+ export interface InteractionContext {
10
+ messageManager: MessageManager;
11
+ slashCommandManager: SlashCommandManager;
12
+ hookManager: HookManager;
13
+ workdir: string;
14
+ configurationService: ConfigurationService;
15
+ logger?: Logger;
16
+ aiManager: AIManager;
17
+ subagentManager: SubagentManager;
18
+ taskManager: TaskManager;
19
+ options: AgentOptions;
20
+ abortMessage: () => void;
21
+ }
22
+ export declare class InteractionService {
23
+ static sendMessage(context: InteractionContext, content: string, images?: Array<{
24
+ path: string;
25
+ mimeType: string;
26
+ }>): Promise<void>;
27
+ static restoreSession(context: InteractionContext, sessionId: string): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=interactionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactionService.d.ts","sourceRoot":"","sources":["../../src/services/interactionService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,cAAc,CAAC;IAC/B,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,qBAAa,kBAAkB;WACT,WAAW,CAC7B,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GACjD,OAAO,CAAC,IAAI,CAAC;WAyFI,cAAc,CAChC,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;CAiDjB"}
@@ -0,0 +1,97 @@
1
+ import { loadSessionFromJsonl } from "./session.js";
2
+ export class InteractionService {
3
+ static async sendMessage(context, content, images) {
4
+ const { messageManager, slashCommandManager, hookManager, workdir, configurationService, logger, aiManager, } = context;
5
+ try {
6
+ // Handle slash command - check if it's a slash command (starts with /)
7
+ if (content.startsWith("/")) {
8
+ const command = content.trim();
9
+ if (!command || command === "/")
10
+ return;
11
+ // Parse and validate slash command
12
+ const { isValid, commandId, args } = slashCommandManager.parseAndValidateSlashCommand(command);
13
+ if (isValid && commandId !== undefined) {
14
+ // Execute valid slash command
15
+ await slashCommandManager.executeCommand(commandId, args);
16
+ return;
17
+ }
18
+ // If command doesn't exist, continue as normal message processing
19
+ // Don't add to history, let normal message processing logic below handle it
20
+ }
21
+ // Handle normal AI message
22
+ // Add user message first, will automatically sync to UI
23
+ messageManager.addUserMessage({
24
+ content,
25
+ images: images?.map((img) => ({
26
+ path: img.path,
27
+ mimeType: img.mimeType,
28
+ })),
29
+ });
30
+ // Execute UserPromptSubmit hooks after adding the user message
31
+ if (hookManager) {
32
+ try {
33
+ const hookResults = await hookManager.executeHooks("UserPromptSubmit", {
34
+ event: "UserPromptSubmit",
35
+ projectDir: workdir,
36
+ timestamp: new Date(),
37
+ // UserPromptSubmit doesn't need toolName
38
+ sessionId: messageManager.getSessionId(),
39
+ transcriptPath: messageManager.getTranscriptPath(),
40
+ cwd: workdir,
41
+ userPrompt: content,
42
+ env: configurationService.getEnvironmentVars(), // Include configuration environment variables
43
+ });
44
+ // Process hook results and determine if we should continue
45
+ const processResult = hookManager.processHookResults("UserPromptSubmit", hookResults, messageManager);
46
+ // If hook processing indicates we should block (exit code 2), stop here
47
+ if (processResult.shouldBlock) {
48
+ logger?.info("UserPromptSubmit hook blocked prompt processing with error:", processResult.errorMessage);
49
+ return; // Don't send to AI
50
+ }
51
+ }
52
+ catch (error) {
53
+ logger?.warn("UserPromptSubmit hooks execution failed:", error);
54
+ // Continue processing even if hooks fail
55
+ }
56
+ }
57
+ // Send AI message
58
+ await aiManager.sendAIMessage();
59
+ }
60
+ catch (error) {
61
+ console.error("Failed to add user message:", error);
62
+ // Loading state will be automatically updated by the useEffect that watches messages
63
+ }
64
+ }
65
+ static async restoreSession(context, sessionId) {
66
+ const { messageManager, logger, subagentManager, taskManager, options, abortMessage, } = context;
67
+ // 1. Validation
68
+ if (!sessionId || sessionId === messageManager.getSessionId()) {
69
+ return; // No-op if session ID is invalid or already current
70
+ }
71
+ // 2. Auto-save current session
72
+ try {
73
+ await messageManager.saveSession();
74
+ }
75
+ catch (error) {
76
+ logger?.warn("Failed to save current session before restore:", error);
77
+ // Continue with restoration even if save fails
78
+ }
79
+ // 3. Load target session
80
+ const sessionData = await loadSessionFromJsonl(sessionId, messageManager.getWorkdir());
81
+ if (!sessionData) {
82
+ throw new Error(`Session not found: ${sessionId}`);
83
+ }
84
+ // 4. Clean current state
85
+ abortMessage(); // Abort any running operations
86
+ subagentManager.cleanup(); // Clean up active subagents
87
+ // 5. Rebuild usage (in correct order)
88
+ messageManager.rebuildUsageFromMessages(sessionData.messages);
89
+ // 6. Initialize session state last
90
+ messageManager.initializeFromSession(sessionData);
91
+ // Update task manager with the root session ID to ensure continuity across compressions
92
+ taskManager.setTaskListId(sessionData.rootSessionId || sessionData.id);
93
+ // 7. Load tasks for the restored session
94
+ const tasks = await taskManager.listTasks();
95
+ options.callbacks?.onTasksChange?.(tasks);
96
+ }
97
+ }
@@ -584,7 +584,7 @@ export async function getFirstMessageContent(sessionId, workdir) {
584
584
  if (textBlock && "content" in textBlock) {
585
585
  return textBlock.content;
586
586
  }
587
- const commandBlock = message.blocks.find((block) => block.type === "command_output");
587
+ const commandBlock = message.blocks.find((block) => block.type === "bang");
588
588
  if (commandBlock && "command" in commandBlock) {
589
589
  return commandBlock.command;
590
590
  }
@@ -8,6 +8,11 @@ export declare class TaskManager extends EventEmitter {
8
8
  constructor(container: Container, taskListId: string);
9
9
  getTaskListId(): string;
10
10
  setTaskListId(taskListId: string): void;
11
+ /**
12
+ * Syncs the task list ID with the current session's root session ID.
13
+ * This is typically called when the session is cleared or compressed.
14
+ */
15
+ syncWithSession(): Promise<void>;
11
16
  private getSessionDir;
12
17
  getTaskPath(taskId: string): string;
13
18
  private getLockPath;
@@ -1 +1 @@
1
- {"version":3,"file":"taskManager.d.ts","sourceRoot":"","sources":["../../src/services/taskManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,qBAAa,WAAY,SAAQ,YAAY;IAKzC,OAAO,CAAC,SAAS;IAJnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,UAAU,CAAS;gBAGjB,SAAS,EAAE,SAAS,EAC5B,UAAU,EAAE,MAAM;IAOb,aAAa,IAAI,MAAM;IAIvB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAI9C,OAAO,CAAC,aAAa;IAId,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI1C,OAAO,CAAC,WAAW;IAIb,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;YAIzB,QAAQ;IA2CtB,OAAO,CAAC,YAAY;IAed,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAcnD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAmB7C,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrC,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IA+B5B,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IActC;;OAEG;IACU,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAG3C"}
1
+ {"version":3,"file":"taskManager.d.ts","sourceRoot":"","sources":["../../src/services/taskManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,qBAAa,WAAY,SAAQ,YAAY;IAKzC,OAAO,CAAC,SAAS;IAJnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,UAAU,CAAS;gBAGjB,SAAS,EAAE,SAAS,EAC5B,UAAU,EAAE,MAAM;IAOb,aAAa,IAAI,MAAM;IAIvB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAI9C;;;OAGG;IACU,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAW7C,OAAO,CAAC,aAAa;IAId,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI1C,OAAO,CAAC,WAAW;IAIb,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;YAIzB,QAAQ;IA2CtB,OAAO,CAAC,YAAY;IAed,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAcnD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAmB7C,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrC,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IA+B5B,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IActC;;OAEG;IACU,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAG3C"}
@@ -16,6 +16,20 @@ export class TaskManager extends EventEmitter {
16
16
  setTaskListId(taskListId) {
17
17
  this.taskListId = taskListId;
18
18
  }
19
+ /**
20
+ * Syncs the task list ID with the current session's root session ID.
21
+ * This is typically called when the session is cleared or compressed.
22
+ */
23
+ async syncWithSession() {
24
+ const messageManager = this.container.get("MessageManager");
25
+ if (!messageManager)
26
+ return;
27
+ const rootSessionId = messageManager.getRootSessionId();
28
+ if (this.taskListId !== rootSessionId && !process.env.WAVE_TASK_LIST_ID) {
29
+ this.setTaskListId(rootSessionId);
30
+ await this.refreshTasks();
31
+ }
32
+ }
19
33
  getSessionDir() {
20
34
  return join(this.baseDir, this.taskListId);
21
35
  }
@@ -86,7 +100,7 @@ export class TaskManager extends EventEmitter {
86
100
  const content = JSON.stringify(fullTask, null, 2);
87
101
  await fs.writeFile(taskPath, content, "utf8");
88
102
  this.emit("tasksChange", this.taskListId);
89
- logger.info(`Task ${taskId} created in task list ${this.taskListId}`);
103
+ logger.debug(`Task ${taskId} created in task list ${this.taskListId}`);
90
104
  return taskId;
91
105
  });
92
106
  }
@@ -117,7 +131,7 @@ export class TaskManager extends EventEmitter {
117
131
  const content = JSON.stringify(task, null, 2);
118
132
  await fs.writeFile(taskPath, content, "utf8");
119
133
  this.emit("tasksChange", this.taskListId);
120
- logger.info(`Task ${task.id} updated in task list ${this.taskListId}`);
134
+ logger.debug(`Task ${task.id} updated in task list ${this.taskListId}`);
121
135
  });
122
136
  }
123
137
  async listTasks() {
@@ -1 +1 @@
1
- {"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AActE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAiYtB,CAAC"}
1
+ {"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AActE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAuXtB,CAAC"}
@@ -125,7 +125,7 @@ Usage notes:
125
125
  return {
126
126
  success: false,
127
127
  content: "",
128
- error: `${BASH_TOOL_NAME} operation denied, reason: ${permissionResult.message || "No reason provided"}`,
128
+ error: `${BASH_TOOL_NAME} operation denied by user, reason: ${permissionResult.message || "No reason provided"}`,
129
129
  };
130
130
  }
131
131
  }
@@ -166,23 +166,8 @@ Usage notes:
166
166
  });
167
167
  let outputBuffer = "";
168
168
  let errorBuffer = "";
169
- let shortResultBuffer = "";
170
169
  let isAborted = false;
171
170
  let isBackgrounded = false;
172
- const updateShortResult = (chunk) => {
173
- if (!chunk)
174
- return;
175
- shortResultBuffer += chunk;
176
- if (shortResultBuffer.length > MAX_OUTPUT_LENGTH) {
177
- shortResultBuffer = shortResultBuffer.slice(-MAX_OUTPUT_LENGTH);
178
- }
179
- const lastLines = shortResultBuffer
180
- .trim()
181
- .split("\n")
182
- .slice(-3)
183
- .join("\n");
184
- context.onShortResultUpdate?.(lastLines || "");
185
- };
186
171
  const foregroundTaskId = `bash_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
187
172
  // Register as foreground task
188
173
  if (context.foregroundTaskManager && command) {
@@ -279,14 +264,12 @@ Usage notes:
279
264
  if (!isAborted && !isBackgrounded && !runInBackground) {
280
265
  const chunk = stripAnsiColors(data.toString());
281
266
  outputBuffer += chunk;
282
- updateShortResult(chunk);
283
267
  }
284
268
  });
285
269
  child.stderr?.on("data", (data) => {
286
270
  if (!isAborted && !isBackgrounded && !runInBackground) {
287
271
  const chunk = stripAnsiColors(data.toString());
288
272
  errorBuffer += chunk;
289
- updateShortResult(chunk);
290
273
  }
291
274
  });
292
275
  child.on("exit", (code) => {
@@ -305,9 +288,15 @@ Usage notes:
305
288
  ? finalOutput.substring(0, MAX_OUTPUT_LENGTH) +
306
289
  "\n\n... (output truncated)"
307
290
  : finalOutput;
291
+ const shortResult = combinedOutput
292
+ .trim()
293
+ .split("\n")
294
+ .slice(-3)
295
+ .join("\n");
308
296
  resolve({
309
297
  success: exitCode === 0,
310
298
  content,
299
+ shortResult: shortResult || undefined,
311
300
  error: exitCode !== 0
312
301
  ? `Command failed with exit code: ${exitCode}`
313
302
  : undefined,
@@ -153,7 +153,7 @@ Usage:
153
153
  return {
154
154
  success: false,
155
155
  content: "",
156
- error: `${EDIT_TOOL_NAME} operation denied, reason: ${permissionResult.message || "No reason provided"}`,
156
+ error: `${EDIT_TOOL_NAME} operation denied by user, reason: ${permissionResult.message || "No reason provided"}`,
157
157
  };
158
158
  }
159
159
  }
@@ -77,7 +77,7 @@ Ensure your plan is complete and unambiguous:
77
77
  if (permissionResult.behavior === "deny") {
78
78
  return {
79
79
  success: false,
80
- content: `User feedback: ${permissionResult.message || "Plan rejected by user"}. Please update your proposal accordingly.`,
80
+ content: `Please update your proposal based on the following user feedback: ${permissionResult.message || "Plan rejected by user"}`,
81
81
  error: permissionResult.message ? undefined : "Plan rejected by user",
82
82
  };
83
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"globTool.d.ts","sourceRoot":"","sources":["../../src/tools/globTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAKtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAoItB,CAAC"}
1
+ {"version":3,"file":"globTool.d.ts","sourceRoot":"","sources":["../../src/tools/globTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAUtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA4ItB,CAAC"}
@@ -3,6 +3,10 @@ import { stat } from "fs/promises";
3
3
  import { resolvePath, getDisplayPath } from "../utils/path.js";
4
4
  import { getGlobIgnorePatterns } from "../utils/fileFilter.js";
5
5
  import { GLOB_TOOL_NAME } from "../constants/tools.js";
6
+ /**
7
+ * Maximum number of files returned by glob tool
8
+ */
9
+ const MAX_GLOB_RESULTS = 1000;
6
10
  /**
7
11
  * Glob Tool Plugin - Fast file pattern matching
8
12
  */
@@ -90,14 +94,20 @@ export const globTool = {
90
94
  .value)
91
95
  .sort((a, b) => b.mtime.getTime() - a.mtime.getTime()) // Most recently modified files first
92
96
  .map((item) => item.path);
97
+ const totalCount = sortedFiles.length;
98
+ const finalFiles = sortedFiles.slice(0, MAX_GLOB_RESULTS);
93
99
  // Format output
94
- const output = sortedFiles
100
+ const output = finalFiles
95
101
  .map((file, index) => `${index + 1}. ${file}`)
96
102
  .join("\n");
103
+ const isTruncated = totalCount > MAX_GLOB_RESULTS;
104
+ const shortResult = isTruncated
105
+ ? `Found ${totalCount} files (showing first ${MAX_GLOB_RESULTS})`
106
+ : `Found ${totalCount} file${totalCount === 1 ? "" : "s"}`;
97
107
  return {
98
108
  success: true,
99
109
  content: output,
100
- shortResult: `Found ${sortedFiles.length} file${sortedFiles.length === 1 ? "" : "s"}`,
110
+ shortResult,
101
111
  };
102
112
  }
103
113
  catch (error) {
@@ -1,4 +1,6 @@
1
1
  import type { ToolPlugin } from "./types.js";
2
+ export declare const MAX_RESULTS = 1000;
3
+ export declare const MAX_FILES = 100;
2
4
  /**
3
5
  * LSP tool plugin - interact with LSP servers for code intelligence
4
6
  */
@@ -1 +1 @@
1
- {"version":3,"file":"lspTool.d.ts","sourceRoot":"","sources":["../../src/tools/lspTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AA+dtE;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,UAkLrB,CAAC"}
1
+ {"version":3,"file":"lspTool.d.ts","sourceRoot":"","sources":["../../src/tools/lspTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAgBtE,eAAO,MAAM,WAAW,OAAO,CAAC;AAChC,eAAO,MAAM,SAAS,MAAM,CAAC;AAglB7B;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,UAoLrB,CAAC"}