wave-agent-sdk 0.0.5 → 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 (140) hide show
  1. package/dist/agent.d.ts +3 -6
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +21 -21
  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 +4 -2
  8. package/dist/managers/aiManager.d.ts.map +1 -1
  9. package/dist/managers/aiManager.js +84 -47
  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} +107 -17
  15. package/dist/managers/mcpManager.d.ts +1 -1
  16. package/dist/managers/mcpManager.d.ts.map +1 -1
  17. package/dist/managers/messageManager.d.ts +17 -4
  18. package/dist/managers/messageManager.d.ts.map +1 -1
  19. package/dist/managers/messageManager.js +13 -5
  20. package/dist/managers/skillManager.d.ts +1 -1
  21. package/dist/managers/skillManager.d.ts.map +1 -1
  22. package/dist/managers/slashCommandManager.d.ts +1 -1
  23. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  24. package/dist/managers/subagentManager.d.ts +7 -12
  25. package/dist/managers/subagentManager.d.ts.map +1 -1
  26. package/dist/managers/subagentManager.js +39 -45
  27. package/dist/managers/toolManager.d.ts +1 -1
  28. package/dist/managers/toolManager.d.ts.map +1 -1
  29. package/dist/services/aiService.d.ts +1 -1
  30. package/dist/services/aiService.d.ts.map +1 -1
  31. package/dist/services/aiService.js +8 -1
  32. package/dist/services/hook.d.ts +56 -0
  33. package/dist/services/hook.d.ts.map +1 -0
  34. package/dist/services/hook.js +276 -0
  35. package/dist/services/session.d.ts +1 -1
  36. package/dist/services/session.d.ts.map +1 -1
  37. package/dist/services/session.js +5 -4
  38. package/dist/tools/taskTool.d.ts.map +1 -1
  39. package/dist/tools/taskTool.js +7 -3
  40. package/dist/types/commands.d.ts +24 -0
  41. package/dist/types/commands.d.ts.map +1 -0
  42. package/dist/types/commands.js +5 -0
  43. package/dist/types/config.d.ts +13 -0
  44. package/dist/types/config.d.ts.map +1 -0
  45. package/dist/types/config.js +5 -0
  46. package/dist/types/core.d.ts +38 -0
  47. package/dist/types/core.d.ts.map +1 -0
  48. package/dist/{types.js → types/core.js} +4 -13
  49. package/dist/{hooks/types.d.ts → types/hooks.d.ts} +2 -1
  50. package/dist/types/hooks.d.ts.map +1 -0
  51. package/dist/types/index.d.ts +20 -0
  52. package/dist/types/index.d.ts.map +1 -0
  53. package/dist/types/index.js +21 -0
  54. package/dist/types/mcp.d.ts +28 -0
  55. package/dist/types/mcp.d.ts.map +1 -0
  56. package/dist/types/mcp.js +5 -0
  57. package/dist/types/messaging.d.ts +80 -0
  58. package/dist/types/messaging.d.ts.map +1 -0
  59. package/dist/types/messaging.js +5 -0
  60. package/dist/types/processes.d.ts +17 -0
  61. package/dist/types/processes.d.ts.map +1 -0
  62. package/dist/types/processes.js +5 -0
  63. package/dist/types/skills.d.ts +78 -0
  64. package/dist/types/skills.d.ts.map +1 -0
  65. package/dist/types/skills.js +17 -0
  66. package/dist/utils/configResolver.d.ts +1 -1
  67. package/dist/utils/configResolver.d.ts.map +1 -1
  68. package/dist/utils/configResolver.js +1 -1
  69. package/dist/utils/configValidator.d.ts +1 -1
  70. package/dist/utils/configValidator.d.ts.map +1 -1
  71. package/dist/utils/configValidator.js +1 -1
  72. package/dist/utils/convertMessagesForAPI.d.ts +1 -1
  73. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  74. package/dist/utils/customCommands.d.ts +1 -1
  75. package/dist/utils/customCommands.d.ts.map +1 -1
  76. package/dist/{hooks/matcher.d.ts → utils/hookMatcher.d.ts} +1 -1
  77. package/dist/utils/hookMatcher.d.ts.map +1 -0
  78. package/dist/utils/markdownParser.d.ts +1 -1
  79. package/dist/utils/markdownParser.d.ts.map +1 -1
  80. package/dist/utils/mcpUtils.d.ts +1 -1
  81. package/dist/utils/mcpUtils.d.ts.map +1 -1
  82. package/dist/utils/messageOperations.d.ts +6 -1
  83. package/dist/utils/messageOperations.d.ts.map +1 -1
  84. package/dist/utils/messageOperations.js +16 -0
  85. package/dist/utils/skillParser.d.ts +1 -1
  86. package/dist/utils/skillParser.d.ts.map +1 -1
  87. package/package.json +1 -1
  88. package/src/agent.ts +49 -43
  89. package/src/index.ts +3 -4
  90. package/src/managers/aiManager.ts +240 -158
  91. package/src/managers/backgroundBashManager.ts +1 -1
  92. package/src/{hooks/manager.ts → managers/hookManager.ts} +159 -26
  93. package/src/managers/mcpManager.ts +1 -1
  94. package/src/managers/messageManager.ts +36 -6
  95. package/src/managers/skillManager.ts +1 -1
  96. package/src/managers/slashCommandManager.ts +5 -1
  97. package/src/managers/subagentManager.ts +46 -53
  98. package/src/managers/toolManager.ts +1 -1
  99. package/src/services/aiService.ts +9 -2
  100. package/src/services/hook.ts +360 -0
  101. package/src/services/session.ts +6 -7
  102. package/src/tools/taskTool.ts +13 -5
  103. package/src/types/commands.ts +26 -0
  104. package/src/types/config.ts +14 -0
  105. package/src/types/core.ts +49 -0
  106. package/src/{hooks/types.ts → types/hooks.ts} +1 -0
  107. package/src/types/index.ts +23 -0
  108. package/src/types/mcp.ts +31 -0
  109. package/src/types/messaging.ts +103 -0
  110. package/src/types/processes.ts +18 -0
  111. package/src/types/skills.ts +91 -0
  112. package/src/utils/configResolver.ts +1 -1
  113. package/src/utils/configValidator.ts +5 -1
  114. package/src/utils/convertMessagesForAPI.ts +1 -1
  115. package/src/utils/customCommands.ts +1 -1
  116. package/src/utils/markdownParser.ts +1 -1
  117. package/src/utils/mcpUtils.ts +1 -1
  118. package/src/utils/messageOperations.ts +20 -1
  119. package/src/utils/skillParser.ts +1 -1
  120. package/dist/hooks/executor.d.ts +0 -56
  121. package/dist/hooks/executor.d.ts.map +0 -1
  122. package/dist/hooks/executor.js +0 -312
  123. package/dist/hooks/index.d.ts +0 -17
  124. package/dist/hooks/index.d.ts.map +0 -1
  125. package/dist/hooks/index.js +0 -14
  126. package/dist/hooks/manager.d.ts.map +0 -1
  127. package/dist/hooks/matcher.d.ts.map +0 -1
  128. package/dist/hooks/settings.d.ts +0 -46
  129. package/dist/hooks/settings.d.ts.map +0 -1
  130. package/dist/hooks/settings.js +0 -100
  131. package/dist/hooks/types.d.ts.map +0 -1
  132. package/dist/types.d.ts +0 -288
  133. package/dist/types.d.ts.map +0 -1
  134. package/src/hooks/executor.ts +0 -440
  135. package/src/hooks/index.ts +0 -52
  136. package/src/hooks/settings.ts +0 -129
  137. /package/dist/{hooks/types.js → types/hooks.js} +0 -0
  138. /package/dist/{hooks/matcher.js → utils/hookMatcher.js} +0 -0
  139. /package/src/{types.ts → types/index.ts.backup} +0 -0
  140. /package/src/{hooks/matcher.ts → utils/hookMatcher.ts} +0 -0
@@ -0,0 +1,360 @@
1
+ /**
2
+ * Hook Services
3
+ *
4
+ * Consolidated hook services providing both execution and configuration functionality.
5
+ * Combines hook command execution and settings management into a single module.
6
+ */
7
+
8
+ import { spawn, type ChildProcess } from "child_process";
9
+ import { existsSync, readFileSync } from "fs";
10
+ import { join } from "path";
11
+ import { homedir } from "os";
12
+ import {
13
+ type HookExecutionContext,
14
+ type HookExecutionResult,
15
+ type HookExecutionOptions,
16
+ type ExtendedHookExecutionContext,
17
+ type HookJsonInput,
18
+ type HookConfiguration,
19
+ type PartialHookConfiguration,
20
+ getSessionFilePath,
21
+ isValidHookEvent,
22
+ } from "../types/hooks.js";
23
+
24
+ // =============================================================================
25
+ // Hook Execution Functions
26
+ // =============================================================================
27
+
28
+ /**
29
+ * Build JSON input data for hook stdin
30
+ */
31
+ function buildHookJsonInput(
32
+ context: ExtendedHookExecutionContext,
33
+ ): HookJsonInput {
34
+ const jsonInput: HookJsonInput = {
35
+ session_id: context.sessionId || "unknown",
36
+ transcript_path:
37
+ context.transcriptPath ||
38
+ (context.sessionId ? getSessionFilePath(context.sessionId) : ""),
39
+ cwd: context.cwd || context.projectDir,
40
+ hook_event_name: context.event,
41
+ };
42
+
43
+ // Add optional fields based on event type
44
+ if (context.event === "PreToolUse" || context.event === "PostToolUse") {
45
+ if (context.toolName) {
46
+ jsonInput.tool_name = context.toolName;
47
+ }
48
+ if (context.toolInput !== undefined) {
49
+ jsonInput.tool_input = context.toolInput;
50
+ }
51
+ }
52
+
53
+ if (context.event === "PostToolUse" && context.toolResponse !== undefined) {
54
+ jsonInput.tool_response = context.toolResponse;
55
+ }
56
+
57
+ if (
58
+ context.event === "UserPromptSubmit" &&
59
+ context.userPrompt !== undefined
60
+ ) {
61
+ jsonInput.user_prompt = context.userPrompt;
62
+ }
63
+
64
+ return jsonInput;
65
+ }
66
+
67
+ /**
68
+ * Execute a single hook command
69
+ */
70
+ export async function executeCommand(
71
+ command: string,
72
+ context: HookExecutionContext | ExtendedHookExecutionContext,
73
+ options?: HookExecutionOptions,
74
+ ): Promise<HookExecutionResult> {
75
+ const defaultTimeout = 10000; // 10 seconds
76
+ const maxTimeout = 300000; // 5 minutes
77
+ const skipExecution =
78
+ process.env.NODE_ENV === "test" &&
79
+ process.env.TEST_HOOK_EXECUTION !== "true";
80
+
81
+ const startTime = Date.now();
82
+ const timeout = Math.min(options?.timeout ?? defaultTimeout, maxTimeout);
83
+
84
+ // Return mock result if execution is skipped
85
+ if (skipExecution) {
86
+ return {
87
+ success: true,
88
+ exitCode: 0,
89
+ stdout: "",
90
+ stderr: "",
91
+ duration: 0,
92
+ timedOut: false,
93
+ };
94
+ }
95
+
96
+ return new Promise((resolve) => {
97
+ let stdout = "";
98
+ let stderr = "";
99
+ let timedOut = false;
100
+
101
+ // Parse command for shell execution
102
+ const isWindows = process.platform === "win32";
103
+ const shell = isWindows ? "cmd.exe" : "/bin/sh";
104
+ const shellFlag = isWindows ? "/c" : "-c";
105
+
106
+ const childProcess: ChildProcess = spawn(shell, [shellFlag, command], {
107
+ stdio: ["pipe", "pipe", "pipe"],
108
+ cwd: context.projectDir,
109
+ env: {
110
+ ...process.env,
111
+ HOOK_EVENT: context.event,
112
+ HOOK_TOOL_NAME: context.toolName || "",
113
+ HOOK_PROJECT_DIR: context.projectDir,
114
+ },
115
+ });
116
+
117
+ // Set up timeout
118
+ const timeoutHandle = setTimeout(() => {
119
+ timedOut = true;
120
+ childProcess.kill("SIGTERM");
121
+
122
+ // Force kill after additional delay
123
+ setTimeout(() => {
124
+ if (!childProcess.killed) {
125
+ childProcess.kill("SIGKILL");
126
+ }
127
+ }, 2000);
128
+ }, timeout);
129
+
130
+ // Handle stdout
131
+ if (childProcess.stdout) {
132
+ childProcess.stdout.on("data", (data: Buffer) => {
133
+ stdout += data.toString();
134
+ });
135
+ }
136
+
137
+ // Handle stderr
138
+ if (childProcess.stderr) {
139
+ childProcess.stderr.on("data", (data: Buffer) => {
140
+ stderr += data.toString();
141
+ });
142
+ }
143
+
144
+ // Send JSON input to stdin if we have extended context
145
+ if (childProcess.stdin && "sessionId" in context) {
146
+ try {
147
+ const jsonInput = buildHookJsonInput(context);
148
+ childProcess.stdin.write(JSON.stringify(jsonInput, null, 2));
149
+ childProcess.stdin.end();
150
+ } catch {
151
+ // Continue execution even if JSON input fails
152
+ }
153
+ } else if (childProcess.stdin) {
154
+ childProcess.stdin.end();
155
+ }
156
+
157
+ // Handle process completion
158
+ childProcess.on("close", (code: number | null) => {
159
+ clearTimeout(timeoutHandle);
160
+ const duration = Date.now() - startTime;
161
+
162
+ resolve({
163
+ success: !timedOut && (code === 0 || code === null),
164
+ exitCode: code || 0,
165
+ stdout: stdout.trim(),
166
+ stderr: stderr.trim(),
167
+ duration,
168
+ timedOut,
169
+ });
170
+ });
171
+
172
+ // Handle process errors
173
+ childProcess.on("error", (error: Error) => {
174
+ clearTimeout(timeoutHandle);
175
+ const duration = Date.now() - startTime;
176
+
177
+ resolve({
178
+ success: false,
179
+ exitCode: 1,
180
+ stdout: stdout.trim(),
181
+ stderr: error.message,
182
+ duration,
183
+ timedOut,
184
+ });
185
+ });
186
+ });
187
+ }
188
+
189
+ /**
190
+ * Execute multiple commands in sequence
191
+ */
192
+ export async function executeCommands(
193
+ commands: string[],
194
+ context: HookExecutionContext | ExtendedHookExecutionContext,
195
+ options?: HookExecutionOptions,
196
+ ): Promise<HookExecutionResult[]> {
197
+ const results: HookExecutionResult[] = [];
198
+
199
+ for (const command of commands) {
200
+ const result = await executeCommand(command, context, options);
201
+ results.push(result);
202
+
203
+ // Stop on first failure unless continueOnFailure is set
204
+ if (!result.success && !options?.continueOnFailure) {
205
+ break;
206
+ }
207
+ }
208
+
209
+ return results;
210
+ }
211
+
212
+ /**
213
+ * Validate command safety (basic checks)
214
+ */
215
+ export function isCommandSafe(command: string): boolean {
216
+ const trimmed = command.trim();
217
+
218
+ // Empty commands are safe (no-op)
219
+ if (!trimmed) {
220
+ return true;
221
+ }
222
+
223
+ // Check for obviously dangerous patterns
224
+ const dangerousPatterns = [
225
+ /rm\s+-rf\s+\//, // rm -rf /
226
+ /sudo\s+rm/, // sudo rm
227
+ />\s*\/dev\/sd[a-z]/, // writing to disk devices
228
+ /dd\s+if=.*of=\/dev/, // dd to devices
229
+ /mkfs/, // filesystem creation
230
+ /fdisk/, // disk partitioning
231
+ /format\s+[a-z]:/, // Windows format command
232
+ ];
233
+
234
+ return !dangerousPatterns.some((pattern) =>
235
+ pattern.test(trimmed.toLowerCase()),
236
+ );
237
+ }
238
+
239
+ // =============================================================================
240
+ // Hook Settings Functions
241
+ // =============================================================================
242
+
243
+ /**
244
+ * Get the user-specific hooks configuration file path
245
+ */
246
+ export function getUserHooksConfigPath(): string {
247
+ return join(homedir(), ".wave", "settings.json");
248
+ }
249
+
250
+ /**
251
+ * Get the project-specific hooks configuration file path
252
+ */
253
+ export function getProjectHooksConfigPath(workdir: string): string {
254
+ return join(workdir, ".wave", "settings.json");
255
+ }
256
+
257
+ /**
258
+ * Load hooks configuration from a JSON file
259
+ */
260
+ export function loadHooksConfigFromFile(
261
+ filePath: string,
262
+ ): PartialHookConfiguration | null {
263
+ if (!existsSync(filePath)) {
264
+ return null;
265
+ }
266
+
267
+ const content = readFileSync(filePath, "utf-8");
268
+ const config = JSON.parse(content) as HookConfiguration;
269
+
270
+ // Validate basic structure
271
+ if (!config || typeof config !== "object" || !config.hooks) {
272
+ throw new Error(`Invalid hooks configuration structure in ${filePath}`);
273
+ }
274
+
275
+ return config.hooks;
276
+ }
277
+
278
+ /**
279
+ * Load user-specific hooks configuration
280
+ */
281
+ export function loadUserHooksConfig(): PartialHookConfiguration | null {
282
+ return loadHooksConfigFromFile(getUserHooksConfigPath());
283
+ }
284
+
285
+ /**
286
+ * Load project-specific hooks configuration
287
+ */
288
+ export function loadProjectHooksConfig(
289
+ workdir: string,
290
+ ): PartialHookConfiguration | null {
291
+ return loadHooksConfigFromFile(getProjectHooksConfigPath(workdir));
292
+ }
293
+
294
+ /**
295
+ * Load and merge hooks configuration from both user and project sources
296
+ */
297
+ export function loadMergedHooksConfig(
298
+ workdir: string,
299
+ ): PartialHookConfiguration | null {
300
+ const userConfig = loadUserHooksConfig();
301
+ const projectConfig = loadProjectHooksConfig(workdir);
302
+
303
+ // No configuration found
304
+ if (!userConfig && !projectConfig) {
305
+ return null;
306
+ }
307
+
308
+ // Only one configuration found
309
+ if (!userConfig) return projectConfig;
310
+ if (!projectConfig) return userConfig;
311
+
312
+ // Merge configurations (project overrides user)
313
+ const merged: PartialHookConfiguration = {};
314
+
315
+ // Combine all hook events
316
+ const allEvents = new Set([
317
+ ...Object.keys(userConfig),
318
+ ...Object.keys(projectConfig),
319
+ ]);
320
+
321
+ for (const event of allEvents) {
322
+ if (!isValidHookEvent(event)) continue;
323
+
324
+ const userEventConfigs = userConfig[event] || [];
325
+ const projectEventConfigs = projectConfig[event] || [];
326
+
327
+ // Project configurations take precedence
328
+ merged[event] = [...userEventConfigs, ...projectEventConfigs];
329
+ }
330
+
331
+ return merged;
332
+ }
333
+
334
+ /**
335
+ * Check if hooks configuration exists (user or project)
336
+ */
337
+ export function hasHooksConfiguration(workdir: string): boolean {
338
+ return (
339
+ existsSync(getUserHooksConfigPath()) ||
340
+ existsSync(getProjectHooksConfigPath(workdir))
341
+ );
342
+ }
343
+
344
+ /**
345
+ * Get hooks configuration information for debugging
346
+ */
347
+ export function getHooksConfigurationInfo(workdir: string): {
348
+ hasUser: boolean;
349
+ hasProject: boolean;
350
+ paths: string[];
351
+ } {
352
+ const userPath = getUserHooksConfigPath();
353
+ const projectPath = getProjectHooksConfigPath(workdir);
354
+
355
+ return {
356
+ hasUser: existsSync(userPath),
357
+ hasProject: existsSync(projectPath),
358
+ paths: [userPath, projectPath],
359
+ };
360
+ }
@@ -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;
@@ -235,8 +235,8 @@ export async function listSessions(
235
235
  latestTotalTokens: sessionData.metadata.latestTotalTokens,
236
236
  });
237
237
  } catch {
238
- // Ignore corrupted session files
239
- console.warn(`Skipping corrupted session file: ${file}`);
238
+ // Skip corrupted session files and continue processing others
239
+ continue;
240
240
  }
241
241
  }
242
242
 
@@ -304,10 +304,9 @@ export async function cleanupExpiredSessions(
304
304
  try {
305
305
  await deleteSession(session.id, sessionDir);
306
306
  deletedCount++;
307
- } catch (error) {
308
- console.warn(
309
- `Failed to delete expired session ${session.id}: ${error}`,
310
- );
307
+ } catch {
308
+ // Skip failed deletions and continue processing other sessions
309
+ continue;
311
310
  }
312
311
  }
313
312
  }
@@ -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,
@@ -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";
@@ -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
+ }