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.
- package/dist/agent.d.ts +63 -9
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +103 -27
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/managers/aiManager.d.ts +5 -2
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +121 -53
- package/dist/managers/backgroundBashManager.d.ts +1 -1
- package/dist/managers/backgroundBashManager.d.ts.map +1 -1
- package/dist/{hooks/manager.d.ts → managers/hookManager.d.ts} +26 -7
- package/dist/managers/hookManager.d.ts.map +1 -0
- package/dist/{hooks/manager.js → managers/hookManager.js} +108 -18
- package/dist/managers/mcpManager.d.ts +1 -1
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +5 -5
- package/dist/managers/messageManager.d.ts +29 -5
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +33 -12
- package/dist/managers/skillManager.d.ts +1 -1
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +3 -3
- package/dist/managers/slashCommandManager.d.ts +1 -1
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +1 -1
- package/dist/managers/subagentManager.d.ts +9 -12
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +43 -45
- package/dist/managers/toolManager.d.ts +1 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/services/aiService.d.ts +10 -2
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +25 -4
- package/dist/services/hook.d.ts +56 -0
- package/dist/services/hook.d.ts.map +1 -0
- package/dist/services/hook.js +276 -0
- package/dist/services/memory.js +3 -3
- package/dist/services/session.d.ts +65 -16
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +85 -34
- package/dist/tools/bashTool.js +2 -2
- package/dist/tools/deleteFileTool.js +1 -1
- package/dist/tools/editTool.js +1 -1
- package/dist/tools/multiEditTool.js +2 -2
- package/dist/tools/taskTool.d.ts.map +1 -1
- package/dist/tools/taskTool.js +7 -3
- package/dist/tools/writeTool.js +1 -1
- package/dist/types/commands.d.ts +24 -0
- package/dist/types/commands.d.ts.map +1 -0
- package/dist/types/commands.js +5 -0
- package/dist/types/config.d.ts +13 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +5 -0
- package/dist/types/core.d.ts +38 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/{types.js → types/core.js} +4 -13
- package/dist/{hooks/types.d.ts → types/hooks.d.ts} +2 -1
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/index.d.ts +20 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/mcp.d.ts +28 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +5 -0
- package/dist/types/messaging.d.ts +80 -0
- package/dist/types/messaging.d.ts.map +1 -0
- package/dist/types/messaging.js +5 -0
- package/dist/types/processes.d.ts +17 -0
- package/dist/types/processes.d.ts.map +1 -0
- package/dist/types/processes.js +5 -0
- package/dist/types/skills.d.ts +78 -0
- package/dist/types/skills.d.ts.map +1 -0
- package/dist/types/skills.js +17 -0
- package/dist/utils/configResolver.d.ts +1 -1
- package/dist/utils/configResolver.d.ts.map +1 -1
- package/dist/utils/configResolver.js +1 -1
- package/dist/utils/configValidator.d.ts +1 -1
- package/dist/utils/configValidator.d.ts.map +1 -1
- package/dist/utils/configValidator.js +1 -1
- package/dist/utils/convertMessagesForAPI.d.ts +1 -1
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/customCommands.d.ts +1 -1
- package/dist/utils/customCommands.d.ts.map +1 -1
- package/dist/{hooks/matcher.d.ts → utils/hookMatcher.d.ts} +1 -1
- package/dist/utils/hookMatcher.d.ts.map +1 -0
- package/dist/utils/markdownParser.d.ts +1 -1
- package/dist/utils/markdownParser.d.ts.map +1 -1
- package/dist/utils/mcpUtils.d.ts +1 -1
- package/dist/utils/mcpUtils.d.ts.map +1 -1
- package/dist/utils/messageOperations.d.ts +7 -2
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +18 -1
- package/dist/utils/skillParser.d.ts +1 -1
- package/dist/utils/skillParser.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/agent.ts +150 -50
- package/src/index.ts +3 -4
- package/src/managers/aiManager.ts +282 -164
- package/src/managers/backgroundBashManager.ts +1 -1
- package/src/{hooks/manager.ts → managers/hookManager.ts} +163 -28
- package/src/managers/mcpManager.ts +6 -6
- package/src/managers/messageManager.ts +69 -10
- package/src/managers/skillManager.ts +4 -4
- package/src/managers/slashCommandManager.ts +6 -2
- package/src/managers/subagentManager.ts +58 -53
- package/src/managers/toolManager.ts +1 -1
- package/src/services/aiService.ts +37 -7
- package/src/services/hook.ts +360 -0
- package/src/services/memory.ts +3 -3
- package/src/services/session.ts +99 -33
- package/src/tools/bashTool.ts +2 -2
- package/src/tools/deleteFileTool.ts +1 -1
- package/src/tools/editTool.ts +1 -1
- package/src/tools/multiEditTool.ts +2 -2
- package/src/tools/taskTool.ts +13 -5
- package/src/tools/writeTool.ts +1 -1
- package/src/types/commands.ts +26 -0
- package/src/types/config.ts +14 -0
- package/src/types/core.ts +49 -0
- package/src/{hooks/types.ts → types/hooks.ts} +1 -0
- package/src/types/index.ts +23 -0
- package/src/{types.ts → types/index.ts.backup} +13 -0
- package/src/types/mcp.ts +31 -0
- package/src/types/messaging.ts +103 -0
- package/src/types/processes.ts +18 -0
- package/src/types/skills.ts +91 -0
- package/src/utils/configResolver.ts +1 -1
- package/src/utils/configValidator.ts +5 -1
- package/src/utils/convertMessagesForAPI.ts +1 -1
- package/src/utils/customCommands.ts +1 -1
- package/src/utils/markdownParser.ts +1 -1
- package/src/utils/mcpUtils.ts +1 -1
- package/src/utils/messageOperations.ts +22 -1
- package/src/utils/skillParser.ts +1 -1
- package/dist/hooks/executor.d.ts +0 -56
- package/dist/hooks/executor.d.ts.map +0 -1
- package/dist/hooks/executor.js +0 -312
- package/dist/hooks/index.d.ts +0 -17
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -14
- package/dist/hooks/manager.d.ts.map +0 -1
- package/dist/hooks/matcher.d.ts.map +0 -1
- package/dist/hooks/settings.d.ts +0 -46
- package/dist/hooks/settings.d.ts.map +0 -1
- package/dist/hooks/settings.js +0 -100
- package/dist/hooks/types.d.ts.map +0 -1
- package/dist/types.d.ts +0 -276
- package/dist/types.d.ts.map +0 -1
- package/src/hooks/executor.ts +0 -440
- package/src/hooks/index.ts +0 -52
- package/src/hooks/settings.ts +0 -129
- /package/dist/{hooks/types.js → types/hooks.js} +0 -0
- /package/dist/{hooks/matcher.js → utils/hookMatcher.js} +0 -0
- /package/src/{hooks/matcher.ts → utils/hookMatcher.ts} +0 -0
package/src/services/session.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
58
|
+
export function getSessionFilePath(
|
|
59
|
+
sessionId: string,
|
|
60
|
+
sessionDir?: string,
|
|
61
|
+
): string {
|
|
48
62
|
const shortId = sessionId.split("_")[2] || sessionId.slice(-8);
|
|
49
|
-
|
|
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
|
|
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(
|
|
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
|
-
//
|
|
195
|
-
|
|
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(
|
|
212
|
-
|
|
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(
|
|
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
|
|
248
|
-
|
|
249
|
-
|
|
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(
|
|
262
|
-
|
|
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);
|
package/src/tools/bashTool.ts
CHANGED
|
@@ -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:
|
|
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 :
|
|
50
|
+
(runInBackground ? undefined : 60000);
|
|
51
51
|
|
|
52
52
|
if (!command || typeof command !== "string") {
|
|
53
53
|
return {
|
package/src/tools/editTool.ts
CHANGED
|
@@ -160,7 +160,7 @@ export const editTool: ToolPlugin = {
|
|
|
160
160
|
? `Replaced ${replacementCount} instances`
|
|
161
161
|
: "Text replaced successfully";
|
|
162
162
|
|
|
163
|
-
// logger.
|
|
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.
|
|
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.
|
|
239
|
+
// logger.debug(`MultiEdit tool: ${shortResult}`);
|
|
240
240
|
|
|
241
241
|
return {
|
|
242
242
|
success: true,
|
package/src/tools/taskTool.ts
CHANGED
|
@@ -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 (
|
|
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,
|
package/src/tools/writeTool.ts
CHANGED
|
@@ -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.
|
|
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,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:
|
package/src/types/mcp.ts
ADDED
|
@@ -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
|
+
}
|