wave-agent-sdk 0.0.4 → 0.0.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 (155) hide show
  1. package/dist/agent.d.ts +63 -9
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +103 -27
  4. package/dist/index.d.ts +3 -2
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +3 -3
  7. package/dist/managers/aiManager.d.ts +5 -2
  8. package/dist/managers/aiManager.d.ts.map +1 -1
  9. package/dist/managers/aiManager.js +121 -53
  10. package/dist/managers/backgroundBashManager.d.ts +1 -1
  11. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  12. package/dist/{hooks/manager.d.ts → managers/hookManager.d.ts} +26 -7
  13. package/dist/managers/hookManager.d.ts.map +1 -0
  14. package/dist/{hooks/manager.js → managers/hookManager.js} +108 -18
  15. package/dist/managers/mcpManager.d.ts +1 -1
  16. package/dist/managers/mcpManager.d.ts.map +1 -1
  17. package/dist/managers/mcpManager.js +5 -5
  18. package/dist/managers/messageManager.d.ts +29 -5
  19. package/dist/managers/messageManager.d.ts.map +1 -1
  20. package/dist/managers/messageManager.js +33 -12
  21. package/dist/managers/skillManager.d.ts +1 -1
  22. package/dist/managers/skillManager.d.ts.map +1 -1
  23. package/dist/managers/skillManager.js +3 -3
  24. package/dist/managers/slashCommandManager.d.ts +1 -1
  25. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  26. package/dist/managers/slashCommandManager.js +1 -1
  27. package/dist/managers/subagentManager.d.ts +9 -12
  28. package/dist/managers/subagentManager.d.ts.map +1 -1
  29. package/dist/managers/subagentManager.js +43 -45
  30. package/dist/managers/toolManager.d.ts +1 -1
  31. package/dist/managers/toolManager.d.ts.map +1 -1
  32. package/dist/services/aiService.d.ts +10 -2
  33. package/dist/services/aiService.d.ts.map +1 -1
  34. package/dist/services/aiService.js +25 -4
  35. package/dist/services/hook.d.ts +56 -0
  36. package/dist/services/hook.d.ts.map +1 -0
  37. package/dist/services/hook.js +276 -0
  38. package/dist/services/memory.js +3 -3
  39. package/dist/services/session.d.ts +65 -16
  40. package/dist/services/session.d.ts.map +1 -1
  41. package/dist/services/session.js +85 -34
  42. package/dist/tools/bashTool.js +2 -2
  43. package/dist/tools/deleteFileTool.js +1 -1
  44. package/dist/tools/editTool.js +1 -1
  45. package/dist/tools/multiEditTool.js +2 -2
  46. package/dist/tools/taskTool.d.ts.map +1 -1
  47. package/dist/tools/taskTool.js +7 -3
  48. package/dist/tools/writeTool.js +1 -1
  49. package/dist/types/commands.d.ts +24 -0
  50. package/dist/types/commands.d.ts.map +1 -0
  51. package/dist/types/commands.js +5 -0
  52. package/dist/types/config.d.ts +13 -0
  53. package/dist/types/config.d.ts.map +1 -0
  54. package/dist/types/config.js +5 -0
  55. package/dist/types/core.d.ts +38 -0
  56. package/dist/types/core.d.ts.map +1 -0
  57. package/dist/{types.js → types/core.js} +4 -13
  58. package/dist/{hooks/types.d.ts → types/hooks.d.ts} +2 -1
  59. package/dist/types/hooks.d.ts.map +1 -0
  60. package/dist/types/index.d.ts +20 -0
  61. package/dist/types/index.d.ts.map +1 -0
  62. package/dist/types/index.js +21 -0
  63. package/dist/types/mcp.d.ts +28 -0
  64. package/dist/types/mcp.d.ts.map +1 -0
  65. package/dist/types/mcp.js +5 -0
  66. package/dist/types/messaging.d.ts +80 -0
  67. package/dist/types/messaging.d.ts.map +1 -0
  68. package/dist/types/messaging.js +5 -0
  69. package/dist/types/processes.d.ts +17 -0
  70. package/dist/types/processes.d.ts.map +1 -0
  71. package/dist/types/processes.js +5 -0
  72. package/dist/types/skills.d.ts +78 -0
  73. package/dist/types/skills.d.ts.map +1 -0
  74. package/dist/types/skills.js +17 -0
  75. package/dist/utils/configResolver.d.ts +1 -1
  76. package/dist/utils/configResolver.d.ts.map +1 -1
  77. package/dist/utils/configResolver.js +1 -1
  78. package/dist/utils/configValidator.d.ts +1 -1
  79. package/dist/utils/configValidator.d.ts.map +1 -1
  80. package/dist/utils/configValidator.js +1 -1
  81. package/dist/utils/convertMessagesForAPI.d.ts +1 -1
  82. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  83. package/dist/utils/customCommands.d.ts +1 -1
  84. package/dist/utils/customCommands.d.ts.map +1 -1
  85. package/dist/{hooks/matcher.d.ts → utils/hookMatcher.d.ts} +1 -1
  86. package/dist/utils/hookMatcher.d.ts.map +1 -0
  87. package/dist/utils/markdownParser.d.ts +1 -1
  88. package/dist/utils/markdownParser.d.ts.map +1 -1
  89. package/dist/utils/mcpUtils.d.ts +1 -1
  90. package/dist/utils/mcpUtils.d.ts.map +1 -1
  91. package/dist/utils/messageOperations.d.ts +7 -2
  92. package/dist/utils/messageOperations.d.ts.map +1 -1
  93. package/dist/utils/messageOperations.js +18 -1
  94. package/dist/utils/skillParser.d.ts +1 -1
  95. package/dist/utils/skillParser.d.ts.map +1 -1
  96. package/package.json +1 -1
  97. package/src/agent.ts +150 -50
  98. package/src/index.ts +3 -4
  99. package/src/managers/aiManager.ts +282 -164
  100. package/src/managers/backgroundBashManager.ts +1 -1
  101. package/src/{hooks/manager.ts → managers/hookManager.ts} +163 -28
  102. package/src/managers/mcpManager.ts +6 -6
  103. package/src/managers/messageManager.ts +69 -10
  104. package/src/managers/skillManager.ts +4 -4
  105. package/src/managers/slashCommandManager.ts +6 -2
  106. package/src/managers/subagentManager.ts +58 -53
  107. package/src/managers/toolManager.ts +1 -1
  108. package/src/services/aiService.ts +37 -7
  109. package/src/services/hook.ts +360 -0
  110. package/src/services/memory.ts +3 -3
  111. package/src/services/session.ts +99 -33
  112. package/src/tools/bashTool.ts +2 -2
  113. package/src/tools/deleteFileTool.ts +1 -1
  114. package/src/tools/editTool.ts +1 -1
  115. package/src/tools/multiEditTool.ts +2 -2
  116. package/src/tools/taskTool.ts +13 -5
  117. package/src/tools/writeTool.ts +1 -1
  118. package/src/types/commands.ts +26 -0
  119. package/src/types/config.ts +14 -0
  120. package/src/types/core.ts +49 -0
  121. package/src/{hooks/types.ts → types/hooks.ts} +1 -0
  122. package/src/types/index.ts +23 -0
  123. package/src/{types.ts → types/index.ts.backup} +13 -0
  124. package/src/types/mcp.ts +31 -0
  125. package/src/types/messaging.ts +103 -0
  126. package/src/types/processes.ts +18 -0
  127. package/src/types/skills.ts +91 -0
  128. package/src/utils/configResolver.ts +1 -1
  129. package/src/utils/configValidator.ts +5 -1
  130. package/src/utils/convertMessagesForAPI.ts +1 -1
  131. package/src/utils/customCommands.ts +1 -1
  132. package/src/utils/markdownParser.ts +1 -1
  133. package/src/utils/mcpUtils.ts +1 -1
  134. package/src/utils/messageOperations.ts +22 -1
  135. package/src/utils/skillParser.ts +1 -1
  136. package/dist/hooks/executor.d.ts +0 -56
  137. package/dist/hooks/executor.d.ts.map +0 -1
  138. package/dist/hooks/executor.js +0 -312
  139. package/dist/hooks/index.d.ts +0 -17
  140. package/dist/hooks/index.d.ts.map +0 -1
  141. package/dist/hooks/index.js +0 -14
  142. package/dist/hooks/manager.d.ts.map +0 -1
  143. package/dist/hooks/matcher.d.ts.map +0 -1
  144. package/dist/hooks/settings.d.ts +0 -46
  145. package/dist/hooks/settings.d.ts.map +0 -1
  146. package/dist/hooks/settings.js +0 -100
  147. package/dist/hooks/types.d.ts.map +0 -1
  148. package/dist/types.d.ts +0 -276
  149. package/dist/types.d.ts.map +0 -1
  150. package/src/hooks/executor.ts +0 -440
  151. package/src/hooks/index.ts +0 -52
  152. package/src/hooks/settings.ts +0 -129
  153. /package/dist/{hooks/types.js → types/hooks.js} +0 -0
  154. /package/dist/{hooks/matcher.js → utils/hookMatcher.js} +0 -0
  155. /package/src/{hooks/matcher.ts → utils/hookMatcher.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { promises as fs } from "fs";
2
2
  import { join } from "path";
3
3
  import { homedir } from "os";
4
- import type { Message } from "../types.js";
4
+ import type { Message } from "../types/index.js";
5
5
 
6
6
  export interface SessionData {
7
7
  id: string;
@@ -30,12 +30,23 @@ const SESSION_DIR = join(homedir(), ".wave", "sessions");
30
30
  const VERSION = "1.0.0";
31
31
  const MAX_SESSION_AGE_DAYS = 30;
32
32
 
33
+ /**
34
+ * Resolve session directory path with fallback to default
35
+ * @param sessionDir Optional custom session directory
36
+ * @returns Resolved session directory path
37
+ */
38
+ export function resolveSessionDir(sessionDir?: string): string {
39
+ return sessionDir || SESSION_DIR;
40
+ }
41
+
33
42
  /**
34
43
  * Ensure session directory exists
44
+ * @param sessionDir Optional custom session directory
35
45
  */
36
- async function ensureSessionDir(): Promise<void> {
46
+ export async function ensureSessionDir(sessionDir?: string): Promise<void> {
47
+ const resolvedDir = resolveSessionDir(sessionDir);
37
48
  try {
38
- await fs.mkdir(SESSION_DIR, { recursive: true });
49
+ await fs.mkdir(resolvedDir, { recursive: true });
39
50
  } catch (error) {
40
51
  throw new Error(`Failed to create session directory: ${error}`);
41
52
  }
@@ -44,9 +55,13 @@ async function ensureSessionDir(): Promise<void> {
44
55
  /**
45
56
  * Generate session file path
46
57
  */
47
- export function getSessionFilePath(sessionId: string): string {
58
+ export function getSessionFilePath(
59
+ sessionId: string,
60
+ sessionDir?: string,
61
+ ): string {
48
62
  const shortId = sessionId.split("_")[2] || sessionId.slice(-8);
49
- return join(SESSION_DIR, `session_${shortId}.json`);
63
+ const resolvedDir = resolveSessionDir(sessionDir);
64
+ return join(resolvedDir, `session_${shortId}.json`);
50
65
  }
51
66
 
52
67
  /**
@@ -62,7 +77,15 @@ function filterDiffBlocks(messages: Message[]): Message[] {
62
77
  }
63
78
 
64
79
  /**
65
- * Save session data
80
+ * Save session data to storage
81
+ *
82
+ * @param sessionId - Unique identifier for the session
83
+ * @param messages - Array of messages to save
84
+ * @param workdir - Working directory for the session
85
+ * @param latestTotalTokens - Total tokens used in the session
86
+ * @param startedAt - ISO timestamp when session started (defaults to current time)
87
+ * @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
88
+ * @throws {Error} When session cannot be saved due to permission or disk space issues
66
89
  */
67
90
  export async function saveSession(
68
91
  sessionId: string,
@@ -70,6 +93,7 @@ export async function saveSession(
70
93
  workdir: string,
71
94
  latestTotalTokens: number = 0,
72
95
  startedAt?: string,
96
+ sessionDir?: string,
73
97
  ): Promise<void> {
74
98
  // Do not save session files in test environment
75
99
  if (process.env.NODE_ENV === "test") {
@@ -81,7 +105,7 @@ export async function saveSession(
81
105
  return;
82
106
  }
83
107
 
84
- await ensureSessionDir();
108
+ await ensureSessionDir(sessionDir);
85
109
 
86
110
  // Filter out diff blocks before saving
87
111
  const filteredMessages = filterDiffBlocks(messages);
@@ -100,7 +124,7 @@ export async function saveSession(
100
124
  },
101
125
  };
102
126
 
103
- const filePath = getSessionFilePath(sessionId);
127
+ const filePath = getSessionFilePath(sessionId, sessionDir);
104
128
  try {
105
129
  await fs.writeFile(filePath, JSON.stringify(sessionData, null, 2), "utf-8");
106
130
  } catch (error) {
@@ -109,12 +133,18 @@ export async function saveSession(
109
133
  }
110
134
 
111
135
  /**
112
- * Load session data
136
+ * Load session data from storage
137
+ *
138
+ * @param sessionId - Unique identifier for the session to load
139
+ * @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
140
+ * @returns Promise that resolves to session data or null if session doesn't exist
141
+ * @throws {Error} When session exists but cannot be read or contains invalid data
113
142
  */
114
143
  export async function loadSession(
115
144
  sessionId: string,
145
+ sessionDir?: string,
116
146
  ): Promise<SessionData | null> {
117
- const filePath = getSessionFilePath(sessionId);
147
+ const filePath = getSessionFilePath(sessionId, sessionDir);
118
148
 
119
149
  try {
120
150
  const content = await fs.readFile(filePath, "utf-8");
@@ -135,12 +165,18 @@ export async function loadSession(
135
165
  }
136
166
 
137
167
  /**
138
- * Get most recent session
168
+ * Get the most recent session for a specific working directory
169
+ *
170
+ * @param workdir - Working directory to find the most recent session for
171
+ * @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
172
+ * @returns Promise that resolves to the most recent session data or null if no sessions exist
173
+ * @throws {Error} When session directory cannot be accessed or session data is corrupted
139
174
  */
140
175
  export async function getLatestSession(
141
176
  workdir: string,
177
+ sessionDir?: string,
142
178
  ): Promise<SessionData | null> {
143
- const sessions = await listSessions(workdir);
179
+ const sessions = await listSessions(workdir, false, sessionDir);
144
180
  if (sessions.length === 0) {
145
181
  return null;
146
182
  }
@@ -151,19 +187,27 @@ export async function getLatestSession(
151
187
  new Date(b.lastActiveAt).getTime() - new Date(a.lastActiveAt).getTime(),
152
188
  )[0];
153
189
 
154
- return loadSession(latestSession.id);
190
+ return loadSession(latestSession.id, sessionDir);
155
191
  }
156
192
 
157
193
  /**
158
- * List all sessions
194
+ * List all sessions for a specific working directory or across all working directories
195
+ *
196
+ * @param workdir - Working directory to filter sessions by
197
+ * @param includeAllWorkdirs - If true, returns sessions from all working directories
198
+ * @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
199
+ * @returns Promise that resolves to array of session metadata objects
200
+ * @throws {Error} When session directory cannot be accessed or read
159
201
  */
160
202
  export async function listSessions(
161
203
  workdir: string,
162
204
  includeAllWorkdirs = false,
205
+ sessionDir?: string,
163
206
  ): Promise<SessionMetadata[]> {
164
207
  try {
165
- await ensureSessionDir();
166
- const files = await fs.readdir(SESSION_DIR);
208
+ await ensureSessionDir(sessionDir);
209
+ const resolvedDir = resolveSessionDir(sessionDir);
210
+ const files = await fs.readdir(resolvedDir);
167
211
 
168
212
  const sessions: SessionMetadata[] = [];
169
213
 
@@ -173,7 +217,7 @@ export async function listSessions(
173
217
  }
174
218
 
175
219
  try {
176
- const filePath = join(SESSION_DIR, file);
220
+ const filePath = join(resolvedDir, file);
177
221
  const content = await fs.readFile(filePath, "utf-8");
178
222
  const sessionData = JSON.parse(content) as SessionData;
179
223
 
@@ -191,8 +235,8 @@ export async function listSessions(
191
235
  latestTotalTokens: sessionData.metadata.latestTotalTokens,
192
236
  });
193
237
  } catch {
194
- // Ignore corrupted session files
195
- console.warn(`Skipping corrupted session file: ${file}`);
238
+ // Skip corrupted session files and continue processing others
239
+ continue;
196
240
  }
197
241
  }
198
242
 
@@ -206,10 +250,18 @@ export async function listSessions(
206
250
  }
207
251
 
208
252
  /**
209
- * Delete session
253
+ * Delete a session from storage
254
+ *
255
+ * @param sessionId - Unique identifier for the session to delete
256
+ * @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
257
+ * @returns Promise that resolves to true if session was deleted, false if it didn't exist
258
+ * @throws {Error} When session exists but cannot be deleted due to permission issues
210
259
  */
211
- export async function deleteSession(sessionId: string): Promise<boolean> {
212
- const filePath = getSessionFilePath(sessionId);
260
+ export async function deleteSession(
261
+ sessionId: string,
262
+ sessionDir?: string,
263
+ ): Promise<boolean> {
264
+ const filePath = getSessionFilePath(sessionId, sessionDir);
213
265
 
214
266
  try {
215
267
  await fs.unlink(filePath);
@@ -223,15 +275,23 @@ export async function deleteSession(sessionId: string): Promise<boolean> {
223
275
  }
224
276
 
225
277
  /**
226
- * Clean up expired sessions
278
+ * Clean up expired sessions older than the configured maximum age
279
+ *
280
+ * @param workdir - Working directory to clean up sessions for
281
+ * @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
282
+ * @returns Promise that resolves to the number of sessions that were deleted
283
+ * @throws {Error} When session directory cannot be accessed or sessions cannot be deleted
227
284
  */
228
- export async function cleanupExpiredSessions(workdir: string): Promise<number> {
285
+ export async function cleanupExpiredSessions(
286
+ workdir: string,
287
+ sessionDir?: string,
288
+ ): Promise<number> {
229
289
  // Do not perform cleanup operations in test environment
230
290
  if (process.env.NODE_ENV === "test") {
231
291
  return 0;
232
292
  }
233
293
 
234
- const sessions = await listSessions(workdir, true);
294
+ const sessions = await listSessions(workdir, true, sessionDir);
235
295
  const now = new Date();
236
296
  const maxAge = MAX_SESSION_AGE_DAYS * 24 * 60 * 60 * 1000; // Convert to milliseconds
237
297
 
@@ -242,12 +302,11 @@ export async function cleanupExpiredSessions(workdir: string): Promise<number> {
242
302
 
243
303
  if (sessionAge > maxAge) {
244
304
  try {
245
- await deleteSession(session.id);
305
+ await deleteSession(session.id, sessionDir);
246
306
  deletedCount++;
247
- } catch (error) {
248
- console.warn(
249
- `Failed to delete expired session ${session.id}: ${error}`,
250
- );
307
+ } catch {
308
+ // Skip failed deletions and continue processing other sessions
309
+ continue;
251
310
  }
252
311
  }
253
312
  }
@@ -256,10 +315,17 @@ export async function cleanupExpiredSessions(workdir: string): Promise<number> {
256
315
  }
257
316
 
258
317
  /**
259
- * Check if session exists
318
+ * Check if a session exists in storage
319
+ *
320
+ * @param sessionId - Unique identifier for the session to check
321
+ * @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
322
+ * @returns Promise that resolves to true if session exists, false otherwise
260
323
  */
261
- export async function sessionExists(sessionId: string): Promise<boolean> {
262
- const filePath = getSessionFilePath(sessionId);
324
+ export async function sessionExists(
325
+ sessionId: string,
326
+ sessionDir?: string,
327
+ ): Promise<boolean> {
328
+ const filePath = getSessionFilePath(sessionId, sessionDir);
263
329
 
264
330
  try {
265
331
  await fs.access(filePath);
@@ -44,10 +44,10 @@ export const bashTool: ToolPlugin = {
44
44
  ): Promise<ToolResult> => {
45
45
  const command = args.command as string;
46
46
  const runInBackground = args.run_in_background as boolean | undefined;
47
- // Set default timeout: 30s for foreground, no timeout for background
47
+ // Set default timeout: 60s for foreground, no timeout for background
48
48
  const timeout =
49
49
  (args.timeout as number | undefined) ??
50
- (runInBackground ? undefined : 30000);
50
+ (runInBackground ? undefined : 60000);
51
51
 
52
52
  if (!command || typeof command !== "string") {
53
53
  return {
@@ -48,7 +48,7 @@ export const deleteFileTool: ToolPlugin = {
48
48
  // Delete file
49
49
  await unlink(filePath);
50
50
 
51
- // logger.info(`Successfully deleted file: ${filePath}`);
51
+ // logger.debug(`Successfully deleted file: ${filePath}`);
52
52
 
53
53
  return {
54
54
  success: true,
@@ -160,7 +160,7 @@ export const editTool: ToolPlugin = {
160
160
  ? `Replaced ${replacementCount} instances`
161
161
  : "Text replaced successfully";
162
162
 
163
- // logger.info(`Edit tool: ${shortResult}`);
163
+ // logger.debug(`Edit tool: ${shortResult}`);
164
164
 
165
165
  return {
166
166
  success: true,
@@ -149,7 +149,7 @@ export const multiEditTool: ToolPlugin = {
149
149
  if (edits[0] && edits[0].old_string === "") {
150
150
  originalContent = "";
151
151
  isNewFile = true;
152
- // logger.info(`Creating new file: ${resolvedPath}`);
152
+ // logger.debug(`Creating new file: ${resolvedPath}`);
153
153
  } else {
154
154
  return {
155
155
  success: false,
@@ -236,7 +236,7 @@ export const multiEditTool: ToolPlugin = {
236
236
 
237
237
  const detailedContent = `${shortResult}\n\nOperations performed:\n${appliedEdits.map((edit, i) => `${i + 1}. ${edit}`).join("\n")}`;
238
238
 
239
- // logger.info(`MultiEdit tool: ${shortResult}`);
239
+ // logger.debug(`MultiEdit tool: ${shortResult}`);
240
240
 
241
241
  return {
242
242
  success: true,
@@ -1,4 +1,4 @@
1
- import type { ToolPlugin, ToolResult } from "./types.js";
1
+ import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
2
2
  import type { SubagentManager } from "../managers/subagentManager.js";
3
3
 
4
4
  /**
@@ -47,7 +47,10 @@ ${subagentList || "No subagents configured"}`;
47
47
  },
48
48
  },
49
49
 
50
- execute: async (args: Record<string, unknown>): Promise<ToolResult> => {
50
+ execute: async (
51
+ args: Record<string, unknown>,
52
+ context: ToolContext,
53
+ ): Promise<ToolResult> => {
51
54
  // Input validation
52
55
  const description = args.description as string;
53
56
  const prompt = args.prompt as string;
@@ -98,11 +101,16 @@ ${subagentList || "No subagents configured"}`;
98
101
  }
99
102
 
100
103
  // Create subagent instance and execute task
101
- const instance = await subagentManager.createInstance(
102
- configuration,
104
+ const instance = await subagentManager.createInstance(configuration, {
103
105
  description,
106
+ prompt,
107
+ subagent_type,
108
+ });
109
+ const response = await subagentManager.executeTask(
110
+ instance,
111
+ prompt,
112
+ context.abortSignal,
104
113
  );
105
- const response = await subagentManager.executeTask(instance, prompt);
106
114
 
107
115
  return {
108
116
  success: true,
@@ -121,7 +121,7 @@ export const writeTool: ToolPlugin = {
121
121
  const chars = content.length;
122
122
  const detailedContent = `${shortResult} (${lines} lines, ${chars} characters)`;
123
123
 
124
- // logger.info(`Write tool: ${shortResult}`);
124
+ // logger.debug(`Write tool: ${shortResult}`);
125
125
 
126
126
  return {
127
127
  success: true,
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Slash command and custom command types
3
+ * Dependencies: None
4
+ */
5
+
6
+ export interface SlashCommand {
7
+ id: string;
8
+ name: string;
9
+ description: string;
10
+ handler: (args?: string) => Promise<void> | void;
11
+ }
12
+
13
+ export interface CustomSlashCommandConfig {
14
+ allowedTools?: string[];
15
+ model?: string;
16
+ description?: string;
17
+ }
18
+
19
+ export interface CustomSlashCommand {
20
+ id: string;
21
+ name: string;
22
+ description?: string; // Add description field
23
+ filePath: string;
24
+ content: string;
25
+ config?: CustomSlashCommandConfig;
26
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Agent and service configuration types
3
+ * Dependencies: None
4
+ */
5
+
6
+ export interface GatewayConfig {
7
+ apiKey: string;
8
+ baseURL: string;
9
+ }
10
+
11
+ export interface ModelConfig {
12
+ agentModel: string;
13
+ fastModel: string;
14
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Core foundational types used across multiple domains
3
+ * Dependencies: None (foundation layer)
4
+ */
5
+
6
+ /**
7
+ * Logger interface definition
8
+ * Compatible with OpenAI package Logger interface
9
+ */
10
+ export interface Logger {
11
+ error: (...args: unknown[]) => void;
12
+ warn: (...args: unknown[]) => void;
13
+ info: (...args: unknown[]) => void;
14
+ debug: (...args: unknown[]) => void;
15
+ }
16
+
17
+ /**
18
+ * Usage statistics for AI operations
19
+ * Extends OpenAI's Usage format with additional tracking fields
20
+ */
21
+ export interface Usage {
22
+ prompt_tokens: number; // Tokens used in prompts
23
+ completion_tokens: number; // Tokens generated in completions
24
+ total_tokens: number; // Sum of prompt + completion tokens
25
+ model?: string; // Model used for the operation (e.g., "gpt-4", "gpt-3.5-turbo")
26
+ operation_type?: "agent" | "compress"; // Type of operation that generated usage
27
+ }
28
+
29
+ export class ConfigurationError extends Error {
30
+ constructor(
31
+ message: string,
32
+ public readonly field: string,
33
+ public readonly provided?: unknown,
34
+ ) {
35
+ super(message);
36
+ this.name = "ConfigurationError";
37
+ }
38
+ }
39
+
40
+ // Standard error messages
41
+ export const CONFIG_ERRORS = {
42
+ MISSING_API_KEY:
43
+ "Gateway configuration requires apiKey. Provide via constructor or AIGW_TOKEN environment variable.",
44
+ MISSING_BASE_URL:
45
+ "Gateway configuration requires baseURL. Provide via constructor or AIGW_URL environment variable.",
46
+ INVALID_TOKEN_LIMIT: "Token limit must be a positive integer.",
47
+ EMPTY_API_KEY: "API key cannot be empty string.",
48
+ EMPTY_BASE_URL: "Base URL cannot be empty string.",
49
+ } as const;
@@ -68,6 +68,7 @@ export interface HookExecutionResult {
68
68
  export interface HookExecutionOptions {
69
69
  timeout?: number; // milliseconds, default 10000
70
70
  cwd?: string; // working directory, defaults to projectDir
71
+ continueOnFailure?: boolean; // continue executing remaining hooks on failure
71
72
  }
72
73
 
73
74
  // Validation result for hook configuration
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Main type index - Barrel export for backward compatibility
3
+ * Re-exports all domain types for legacy imports
4
+ *
5
+ * Legacy import pattern (continues to work):
6
+ * import { Message, Logger, McpTool } from 'wave-agent-sdk/types';
7
+ *
8
+ * New domain-specific import pattern:
9
+ * import { Message } from 'wave-agent-sdk/types/messaging';
10
+ * import { Logger } from 'wave-agent-sdk/types/core';
11
+ * import { McpTool } from 'wave-agent-sdk/types/mcp';
12
+ */
13
+
14
+ // Core foundational types
15
+ export * from "./core.js";
16
+
17
+ // Domain-specific types
18
+ export * from "./messaging.js";
19
+ export * from "./mcp.js";
20
+ export * from "./processes.js";
21
+ export * from "./commands.js";
22
+ export * from "./skills.js";
23
+ export * from "./config.js";
@@ -14,6 +14,7 @@ export interface Logger {
14
14
  export interface Message {
15
15
  role: "user" | "assistant";
16
16
  blocks: MessageBlock[];
17
+ usage?: Usage; // Usage data for this message's AI operation (assistant messages only)
17
18
  }
18
19
 
19
20
  export type MessageBlock =
@@ -332,6 +333,18 @@ export class ConfigurationError extends Error {
332
333
  }
333
334
  }
334
335
 
336
+ /**
337
+ * Usage statistics for AI operations
338
+ * Extends OpenAI's Usage format with additional tracking fields
339
+ */
340
+ export interface Usage {
341
+ prompt_tokens: number; // Tokens used in prompts
342
+ completion_tokens: number; // Tokens generated in completions
343
+ total_tokens: number; // Sum of prompt + completion tokens
344
+ model?: string; // Model used for the operation (e.g., "gpt-4", "gpt-3.5-turbo")
345
+ operation_type?: "agent" | "compress"; // Type of operation that generated usage
346
+ }
347
+
335
348
  // Standard error messages
336
349
  export const CONFIG_ERRORS = {
337
350
  MISSING_API_KEY:
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Model Context Protocol types
3
+ * Dependencies: None
4
+ */
5
+
6
+ export interface McpServerConfig {
7
+ command: string;
8
+ args?: string[];
9
+ env?: Record<string, string>;
10
+ }
11
+
12
+ export interface McpConfig {
13
+ mcpServers: Record<string, McpServerConfig>;
14
+ }
15
+
16
+ export interface McpTool {
17
+ name: string;
18
+ description?: string;
19
+ inputSchema: Record<string, unknown>;
20
+ }
21
+
22
+ export interface McpServerStatus {
23
+ name: string;
24
+ config: McpServerConfig;
25
+ status: "disconnected" | "connected" | "connecting" | "error";
26
+ tools?: McpTool[];
27
+ toolCount?: number;
28
+ capabilities?: string[];
29
+ lastConnected?: number;
30
+ error?: string;
31
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Message and communication block types
3
+ * Dependencies: Core (Usage)
4
+ */
5
+
6
+ import type { Usage } from "./core.js";
7
+
8
+ export interface Message {
9
+ role: "user" | "assistant";
10
+ blocks: MessageBlock[];
11
+ usage?: Usage; // Usage data for this message's AI operation (assistant messages only)
12
+ }
13
+
14
+ export type MessageBlock =
15
+ | TextBlock
16
+ | ErrorBlock
17
+ | ToolBlock
18
+ | ImageBlock
19
+ | DiffBlock
20
+ | CommandOutputBlock
21
+ | CompressBlock
22
+ | MemoryBlock
23
+ | CustomCommandBlock
24
+ | SubagentBlock;
25
+
26
+ export interface TextBlock {
27
+ type: "text";
28
+ content: string;
29
+ }
30
+
31
+ export interface ErrorBlock {
32
+ type: "error";
33
+ content: string;
34
+ }
35
+
36
+ export interface ToolBlock {
37
+ type: "tool";
38
+ parameters?: string;
39
+ result?: string;
40
+ shortResult?: string; // Add shortResult field
41
+ images?: Array<{
42
+ // Add image data support
43
+ data: string; // Base64 encoded image data
44
+ mediaType?: string; // Media type of the image
45
+ }>;
46
+ id?: string;
47
+ name?: string;
48
+ isRunning?: boolean; // Mark if tool is actually executing
49
+ success?: boolean;
50
+ error?: string | Error;
51
+ compactParams?: string; // Compact parameter display
52
+ }
53
+
54
+ export interface ImageBlock {
55
+ type: "image";
56
+ imageUrls?: string[];
57
+ }
58
+
59
+ export interface DiffBlock {
60
+ type: "diff";
61
+ path: string;
62
+ diffResult: Array<{
63
+ value: string;
64
+ added?: boolean;
65
+ removed?: boolean;
66
+ }>;
67
+ }
68
+
69
+ export interface CommandOutputBlock {
70
+ type: "command_output";
71
+ command: string;
72
+ output: string;
73
+ isRunning: boolean;
74
+ exitCode: number | null;
75
+ }
76
+
77
+ export interface CompressBlock {
78
+ type: "compress";
79
+ content: string;
80
+ }
81
+
82
+ export interface MemoryBlock {
83
+ type: "memory";
84
+ content: string;
85
+ isSuccess: boolean;
86
+ memoryType?: "project" | "user"; // Memory type
87
+ storagePath?: string; // Storage path text
88
+ }
89
+
90
+ export interface CustomCommandBlock {
91
+ type: "custom_command";
92
+ commandName: string;
93
+ content: string; // Complete command content, used when passing to AI
94
+ originalInput?: string; // Original user input, used for UI display (e.g., "/fix-issue 123 high")
95
+ }
96
+
97
+ export interface SubagentBlock {
98
+ type: "subagent";
99
+ subagentId: string;
100
+ subagentName: string;
101
+ status: "active" | "completed" | "error" | "aborted";
102
+ messages: Message[];
103
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Background process and shell management types
3
+ * Dependencies: None
4
+ */
5
+
6
+ import type { ChildProcess } from "child_process";
7
+
8
+ export interface BackgroundShell {
9
+ id: string;
10
+ process: ChildProcess;
11
+ command: string;
12
+ startTime: number;
13
+ status: "running" | "completed" | "killed";
14
+ stdout: string;
15
+ stderr: string;
16
+ exitCode?: number;
17
+ runtime?: number;
18
+ }