wave-agent-sdk 0.0.7 → 0.0.8

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 (172) hide show
  1. package/dist/agent.d.ts +32 -20
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +202 -20
  4. package/dist/constants/events.d.ts +28 -0
  5. package/dist/constants/events.d.ts.map +1 -0
  6. package/dist/constants/events.js +27 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -0
  10. package/dist/managers/aiManager.d.ts +34 -1
  11. package/dist/managers/aiManager.d.ts.map +1 -1
  12. package/dist/managers/aiManager.js +243 -128
  13. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  14. package/dist/managers/backgroundBashManager.js +7 -6
  15. package/dist/managers/hookManager.d.ts +9 -4
  16. package/dist/managers/hookManager.d.ts.map +1 -1
  17. package/dist/managers/hookManager.js +62 -30
  18. package/dist/managers/liveConfigManager.d.ts +58 -0
  19. package/dist/managers/liveConfigManager.d.ts.map +1 -0
  20. package/dist/managers/liveConfigManager.js +160 -0
  21. package/dist/managers/messageManager.d.ts +38 -13
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +163 -30
  24. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  25. package/dist/managers/slashCommandManager.js +4 -1
  26. package/dist/managers/subagentManager.d.ts +51 -0
  27. package/dist/managers/subagentManager.d.ts.map +1 -1
  28. package/dist/managers/subagentManager.js +189 -18
  29. package/dist/services/aiService.d.ts +13 -5
  30. package/dist/services/aiService.d.ts.map +1 -1
  31. package/dist/services/aiService.js +350 -74
  32. package/dist/services/configurationWatcher.d.ts +120 -0
  33. package/dist/services/configurationWatcher.d.ts.map +1 -0
  34. package/dist/services/configurationWatcher.js +439 -0
  35. package/dist/services/fileWatcher.d.ts +69 -0
  36. package/dist/services/fileWatcher.d.ts.map +1 -0
  37. package/dist/services/fileWatcher.js +213 -0
  38. package/dist/services/hook.d.ts +91 -9
  39. package/dist/services/hook.d.ts.map +1 -1
  40. package/dist/services/hook.js +393 -43
  41. package/dist/services/jsonlHandler.d.ts +62 -0
  42. package/dist/services/jsonlHandler.d.ts.map +1 -0
  43. package/dist/services/jsonlHandler.js +257 -0
  44. package/dist/services/memory.d.ts +9 -0
  45. package/dist/services/memory.d.ts.map +1 -1
  46. package/dist/services/memory.js +81 -12
  47. package/dist/services/memoryStore.d.ts +81 -0
  48. package/dist/services/memoryStore.d.ts.map +1 -0
  49. package/dist/services/memoryStore.js +200 -0
  50. package/dist/services/session.d.ts +64 -49
  51. package/dist/services/session.d.ts.map +1 -1
  52. package/dist/services/session.js +310 -132
  53. package/dist/tools/bashTool.d.ts.map +1 -1
  54. package/dist/tools/bashTool.js +5 -4
  55. package/dist/tools/deleteFileTool.d.ts.map +1 -1
  56. package/dist/tools/deleteFileTool.js +2 -1
  57. package/dist/tools/editTool.d.ts.map +1 -1
  58. package/dist/tools/editTool.js +3 -2
  59. package/dist/tools/multiEditTool.d.ts.map +1 -1
  60. package/dist/tools/multiEditTool.js +4 -3
  61. package/dist/tools/readTool.d.ts.map +1 -1
  62. package/dist/tools/readTool.js +2 -1
  63. package/dist/tools/writeTool.d.ts.map +1 -1
  64. package/dist/tools/writeTool.js +5 -6
  65. package/dist/types/commands.d.ts +4 -0
  66. package/dist/types/commands.d.ts.map +1 -1
  67. package/dist/types/core.d.ts +35 -0
  68. package/dist/types/core.d.ts.map +1 -1
  69. package/dist/types/environment.d.ts +42 -0
  70. package/dist/types/environment.d.ts.map +1 -0
  71. package/dist/types/environment.js +21 -0
  72. package/dist/types/hooks.d.ts +8 -2
  73. package/dist/types/hooks.d.ts.map +1 -1
  74. package/dist/types/hooks.js +8 -2
  75. package/dist/types/index.d.ts +2 -0
  76. package/dist/types/index.d.ts.map +1 -1
  77. package/dist/types/index.js +2 -0
  78. package/dist/types/memoryStore.d.ts +82 -0
  79. package/dist/types/memoryStore.d.ts.map +1 -0
  80. package/dist/types/memoryStore.js +7 -0
  81. package/dist/types/messaging.d.ts +14 -2
  82. package/dist/types/messaging.d.ts.map +1 -1
  83. package/dist/types/session.d.ts +20 -0
  84. package/dist/types/session.d.ts.map +1 -0
  85. package/dist/types/session.js +7 -0
  86. package/dist/utils/bashHistory.d.ts.map +1 -1
  87. package/dist/utils/bashHistory.js +27 -26
  88. package/dist/utils/cacheControlUtils.d.ts +121 -0
  89. package/dist/utils/cacheControlUtils.d.ts.map +1 -0
  90. package/dist/utils/cacheControlUtils.js +367 -0
  91. package/dist/utils/commandPathResolver.d.ts +52 -0
  92. package/dist/utils/commandPathResolver.d.ts.map +1 -0
  93. package/dist/utils/commandPathResolver.js +145 -0
  94. package/dist/utils/configPaths.d.ts +85 -0
  95. package/dist/utils/configPaths.d.ts.map +1 -0
  96. package/dist/utils/configPaths.js +121 -0
  97. package/dist/utils/configResolver.d.ts +37 -10
  98. package/dist/utils/configResolver.d.ts.map +1 -1
  99. package/dist/utils/configResolver.js +127 -23
  100. package/dist/utils/constants.d.ts +1 -1
  101. package/dist/utils/constants.js +1 -1
  102. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  103. package/dist/utils/convertMessagesForAPI.js +7 -5
  104. package/dist/utils/customCommands.d.ts.map +1 -1
  105. package/dist/utils/customCommands.js +66 -21
  106. package/dist/utils/fileUtils.d.ts +15 -0
  107. package/dist/utils/fileUtils.d.ts.map +1 -0
  108. package/dist/utils/fileUtils.js +61 -0
  109. package/dist/utils/globalLogger.d.ts +102 -0
  110. package/dist/utils/globalLogger.d.ts.map +1 -0
  111. package/dist/utils/globalLogger.js +136 -0
  112. package/dist/utils/mcpUtils.d.ts.map +1 -1
  113. package/dist/utils/mcpUtils.js +25 -3
  114. package/dist/utils/messageOperations.d.ts +20 -8
  115. package/dist/utils/messageOperations.d.ts.map +1 -1
  116. package/dist/utils/messageOperations.js +25 -16
  117. package/dist/utils/pathEncoder.d.ts +104 -0
  118. package/dist/utils/pathEncoder.d.ts.map +1 -0
  119. package/dist/utils/pathEncoder.js +272 -0
  120. package/dist/utils/subagentParser.d.ts.map +1 -1
  121. package/dist/utils/subagentParser.js +2 -1
  122. package/dist/utils/tokenCalculation.d.ts +26 -0
  123. package/dist/utils/tokenCalculation.d.ts.map +1 -0
  124. package/dist/utils/tokenCalculation.js +36 -0
  125. package/package.json +6 -3
  126. package/src/agent.ts +298 -34
  127. package/src/constants/events.ts +38 -0
  128. package/src/index.ts +2 -0
  129. package/src/managers/aiManager.ts +323 -170
  130. package/src/managers/backgroundBashManager.ts +7 -6
  131. package/src/managers/hookManager.ts +83 -40
  132. package/src/managers/liveConfigManager.ts +248 -0
  133. package/src/managers/messageManager.ts +230 -63
  134. package/src/managers/slashCommandManager.ts +4 -1
  135. package/src/managers/subagentManager.ts +283 -21
  136. package/src/services/aiService.ts +474 -83
  137. package/src/services/configurationWatcher.ts +622 -0
  138. package/src/services/fileWatcher.ts +301 -0
  139. package/src/services/hook.ts +538 -47
  140. package/src/services/jsonlHandler.ts +319 -0
  141. package/src/services/memory.ts +92 -12
  142. package/src/services/memoryStore.ts +279 -0
  143. package/src/services/session.ts +381 -157
  144. package/src/tools/bashTool.ts +5 -4
  145. package/src/tools/deleteFileTool.ts +2 -1
  146. package/src/tools/editTool.ts +3 -2
  147. package/src/tools/multiEditTool.ts +4 -3
  148. package/src/tools/readTool.ts +2 -1
  149. package/src/tools/writeTool.ts +7 -6
  150. package/src/types/commands.ts +6 -0
  151. package/src/types/core.ts +44 -0
  152. package/src/types/environment.ts +60 -0
  153. package/src/types/hooks.ts +21 -8
  154. package/src/types/index.ts +2 -0
  155. package/src/types/memoryStore.ts +94 -0
  156. package/src/types/messaging.ts +14 -2
  157. package/src/types/session.ts +25 -0
  158. package/src/utils/bashHistory.ts +27 -27
  159. package/src/utils/cacheControlUtils.ts +540 -0
  160. package/src/utils/commandPathResolver.ts +189 -0
  161. package/src/utils/configPaths.ts +163 -0
  162. package/src/utils/configResolver.ts +182 -22
  163. package/src/utils/constants.ts +1 -1
  164. package/src/utils/convertMessagesForAPI.ts +7 -5
  165. package/src/utils/customCommands.ts +90 -22
  166. package/src/utils/fileUtils.ts +65 -0
  167. package/src/utils/globalLogger.ts +145 -0
  168. package/src/utils/mcpUtils.ts +34 -3
  169. package/src/utils/messageOperations.ts +42 -20
  170. package/src/utils/pathEncoder.ts +379 -0
  171. package/src/utils/subagentParser.ts +2 -1
  172. package/src/utils/tokenCalculation.ts +43 -0
@@ -1,4 +1,5 @@
1
1
  import { spawn, ChildProcess } from "child_process";
2
+ import { logger } from "../utils/globalLogger.js";
2
3
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
3
4
 
4
5
  /**
@@ -133,8 +134,8 @@ export const bashTool: ToolPlugin = {
133
134
  if (child.pid && !child.killed) {
134
135
  try {
135
136
  process.kill(-child.pid, "SIGKILL");
136
- } catch {
137
- // logger.error("Failed to force kill process:", killError);
137
+ } catch (killError) {
138
+ logger.error("Failed to force kill process:", killError);
138
139
  }
139
140
  }
140
141
  }, 1000);
@@ -147,8 +148,8 @@ export const bashTool: ToolPlugin = {
147
148
  child.kill("SIGKILL");
148
149
  }
149
150
  }, 1000);
150
- } catch {
151
- // logger.error("Failed to kill child process:", directKillError);
151
+ } catch (directKillError) {
152
+ logger.error("Failed to kill child process:", directKillError);
152
153
  }
153
154
  }
154
155
  }
@@ -1,4 +1,5 @@
1
1
  import { unlink } from "fs/promises";
2
+ import { logger } from "../utils/globalLogger.js";
2
3
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
3
4
  import { resolvePath, getDisplayPath } from "../utils/path.js";
4
5
 
@@ -48,7 +49,7 @@ export const deleteFileTool: ToolPlugin = {
48
49
  // Delete file
49
50
  await unlink(filePath);
50
51
 
51
- // logger.debug(`Successfully deleted file: ${filePath}`);
52
+ logger.debug(`Successfully deleted file: ${filePath}`);
52
53
 
53
54
  return {
54
55
  success: true,
@@ -1,4 +1,5 @@
1
1
  import { readFile, writeFile } from "fs/promises";
2
+ import { logger } from "../utils/globalLogger.js";
2
3
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
3
4
  import { resolvePath, getDisplayPath } from "../utils/path.js";
4
5
  import { diffLines } from "diff";
@@ -160,7 +161,7 @@ export const editTool: ToolPlugin = {
160
161
  ? `Replaced ${replacementCount} instances`
161
162
  : "Text replaced successfully";
162
163
 
163
- // logger.debug(`Edit tool: ${shortResult}`);
164
+ logger.debug(`Edit tool: ${shortResult}`);
164
165
 
165
166
  return {
166
167
  success: true,
@@ -174,7 +175,7 @@ export const editTool: ToolPlugin = {
174
175
  } catch (error) {
175
176
  const errorMessage =
176
177
  error instanceof Error ? error.message : String(error);
177
- // logger.error(`Edit tool error: ${errorMessage}`);
178
+ logger.error(`Edit tool error: ${errorMessage}`);
178
179
  return {
179
180
  success: false,
180
181
  content: "",
@@ -1,4 +1,5 @@
1
1
  import { readFile, writeFile } from "fs/promises";
2
+ import { logger } from "../utils/globalLogger.js";
2
3
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
3
4
  import { resolvePath, getDisplayPath } from "../utils/path.js";
4
5
  import { diffLines } from "diff";
@@ -149,7 +150,7 @@ export const multiEditTool: ToolPlugin = {
149
150
  if (edits[0] && edits[0].old_string === "") {
150
151
  originalContent = "";
151
152
  isNewFile = true;
152
- // logger.debug(`Creating new file: ${resolvedPath}`);
153
+ logger.debug(`Creating new file: ${resolvedPath}`);
153
154
  } else {
154
155
  return {
155
156
  success: false,
@@ -236,7 +237,7 @@ export const multiEditTool: ToolPlugin = {
236
237
 
237
238
  const detailedContent = `${shortResult}\n\nOperations performed:\n${appliedEdits.map((edit, i) => `${i + 1}. ${edit}`).join("\n")}`;
238
239
 
239
- // logger.debug(`MultiEdit tool: ${shortResult}`);
240
+ logger.debug(`MultiEdit tool: ${shortResult}`);
240
241
 
241
242
  return {
242
243
  success: true,
@@ -250,7 +251,7 @@ export const multiEditTool: ToolPlugin = {
250
251
  } catch (error) {
251
252
  const errorMessage =
252
253
  error instanceof Error ? error.message : String(error);
253
- // logger.error(`MultiEdit tool error: ${errorMessage}`);
254
+ logger.error(`MultiEdit tool error: ${errorMessage}`);
254
255
  return {
255
256
  success: false,
256
257
  content: "",
@@ -1,4 +1,5 @@
1
1
  import { readFile } from "fs/promises";
2
+ import { logger } from "../utils/globalLogger.js";
2
3
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
3
4
  import { resolvePath, getDisplayPath } from "../utils/path.js";
4
5
  import {
@@ -75,7 +76,7 @@ export const readTool: ToolPlugin = {
75
76
 
76
77
  // Check if file is empty
77
78
  if (fileContent.length === 0) {
78
- // logger.warn(`File ${filePath} exists but has empty contents`);
79
+ logger.warn(`File ${filePath} exists but has empty contents`);
79
80
  return {
80
81
  success: true,
81
82
  content:
@@ -1,5 +1,6 @@
1
1
  import { readFile, writeFile, mkdir } from "fs/promises";
2
2
  import { dirname } from "path";
3
+ import { logger } from "../utils/globalLogger.js";
3
4
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
4
5
  import { resolvePath, getDisplayPath } from "../utils/path.js";
5
6
  import { diffLines } from "diff";
@@ -14,7 +15,7 @@ export const writeTool: ToolPlugin = {
14
15
  function: {
15
16
  name: "Write",
16
17
  description:
17
- "Writes a file to the local filesystem.\n\nUsage:\n- This tool will overwrite the existing file if there is one at the provided path.\n- If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.\n- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.\n- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.\n- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.",
18
+ "Writes a file to the local filesystem.\n\nUsage:\n- This tool will overwrite the existing file if there is one at the provided path.\n- If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.\n- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.\n- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.\n- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.\n- IMPORTANT: Always provide file_path parameter before content parameter when calling this tool.",
18
19
  parameters: {
19
20
  type: "object",
20
21
  properties: {
@@ -95,9 +96,9 @@ export const writeTool: ToolPlugin = {
95
96
  mkdirError instanceof Error &&
96
97
  !mkdirError.message.includes("EEXIST")
97
98
  ) {
98
- // logger.warn(
99
- // `Failed to create directory ${fileDir}: ${mkdirError.message}`,
100
- // );
99
+ logger.warn(
100
+ `Failed to create directory ${fileDir}: ${mkdirError.message}`,
101
+ );
101
102
  }
102
103
  }
103
104
 
@@ -121,7 +122,7 @@ export const writeTool: ToolPlugin = {
121
122
  const chars = content.length;
122
123
  const detailedContent = `${shortResult} (${lines} lines, ${chars} characters)`;
123
124
 
124
- // logger.debug(`Write tool: ${shortResult}`);
125
+ logger.debug(`Write tool: ${shortResult}`);
125
126
 
126
127
  return {
127
128
  success: true,
@@ -135,7 +136,7 @@ export const writeTool: ToolPlugin = {
135
136
  } catch (error) {
136
137
  const errorMessage =
137
138
  error instanceof Error ? error.message : String(error);
138
- // logger.error(`Write tool error: ${errorMessage}`);
139
+ logger.error(`Write tool error: ${errorMessage}`);
139
140
  return {
140
141
  success: false,
141
142
  content: "",
@@ -23,4 +23,10 @@ export interface CustomSlashCommand {
23
23
  filePath: string;
24
24
  content: string;
25
25
  config?: CustomSlashCommandConfig;
26
+
27
+ // Nested command support
28
+ namespace?: string; // Parent directory for nested commands (e.g., "openspec")
29
+ isNested: boolean; // Whether command is in a subdirectory
30
+ depth: number; // 0 = root, 1 = nested
31
+ segments: string[]; // Path components for ID generation (e.g., ["openspec", "apply"])
26
32
  }
package/src/types/core.ts CHANGED
@@ -3,6 +3,8 @@
3
3
  * Dependencies: None (foundation layer)
4
4
  */
5
5
 
6
+ import type { CompletionUsage } from "openai/resources";
7
+
6
8
  /**
7
9
  * Logger interface definition
8
10
  * Compatible with OpenAI package Logger interface
@@ -24,6 +26,48 @@ export interface Usage {
24
26
  total_tokens: number; // Sum of prompt + completion tokens
25
27
  model?: string; // Model used for the operation (e.g., "gpt-4", "gpt-3.5-turbo")
26
28
  operation_type?: "agent" | "compress"; // Type of operation that generated usage
29
+
30
+ // Cache-related tokens (Claude models only)
31
+ cache_read_input_tokens?: number; // Tokens read from cache
32
+ cache_creation_input_tokens?: number; // Tokens used to create cache entries
33
+ cache_creation?: {
34
+ ephemeral_5m_input_tokens: number; // Tokens cached for 5 minutes
35
+ ephemeral_1h_input_tokens: number; // Tokens cached for 1 hour
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Enhanced usage metrics including Claude cache information
41
+ * Backward compatible with standard OpenAI CompletionUsage
42
+ */
43
+ export interface ClaudeUsage extends CompletionUsage {
44
+ // Standard OpenAI usage fields (inherited)
45
+ prompt_tokens: number;
46
+ completion_tokens: number;
47
+ total_tokens: number;
48
+
49
+ // Claude-specific cache extensions
50
+ /**
51
+ * Number of tokens read from existing cache
52
+ * Indicates cost savings from cache hits
53
+ */
54
+ cache_read_input_tokens?: number;
55
+
56
+ /**
57
+ * Number of tokens used to create new cache entries
58
+ * Investment in future cache hits
59
+ */
60
+ cache_creation_input_tokens?: number;
61
+
62
+ /**
63
+ * Detailed breakdown of cache creation by duration
64
+ */
65
+ cache_creation?: {
66
+ /** Tokens cached for 5 minute duration */
67
+ ephemeral_5m_input_tokens: number;
68
+ /** Tokens cached for 1 hour duration */
69
+ ephemeral_1h_input_tokens: number;
70
+ };
27
71
  }
28
72
 
29
73
  export class ConfigurationError extends Error {
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Environment Variable System Types
3
+ *
4
+ * Provides comprehensive TypeScript types for environment variable validation,
5
+ * merging, and conflict resolution in the Wave Agent SDK.
6
+ */
7
+
8
+ /**
9
+ * Result of environment variable validation
10
+ */
11
+ export interface EnvironmentValidationResult {
12
+ isValid: boolean;
13
+ errors: string[];
14
+ warnings: string[];
15
+ }
16
+
17
+ /**
18
+ * Context containing merged environment variables and conflict information
19
+ */
20
+ export interface MergedEnvironmentContext {
21
+ userVars: Record<string, string>;
22
+ projectVars: Record<string, string>;
23
+ mergedVars: Record<string, string>;
24
+ conflicts: Array<{
25
+ key: string;
26
+ userValue: string;
27
+ projectValue: string;
28
+ resolvedValue: string;
29
+ }>;
30
+ }
31
+
32
+ /**
33
+ * Type guard to check if a value is a valid environment variables object
34
+ */
35
+ export function isValidEnvironmentVars(
36
+ env: unknown,
37
+ ): env is Record<string, string> {
38
+ if (typeof env !== "object" || env === null) {
39
+ return false;
40
+ }
41
+
42
+ // Check if all keys and values are strings
43
+ for (const [key, value] of Object.entries(env)) {
44
+ if (typeof key !== "string" || typeof value !== "string") {
45
+ return false;
46
+ }
47
+ }
48
+
49
+ return true;
50
+ }
51
+
52
+ /**
53
+ * Configuration options for environment merging
54
+ */
55
+ export interface EnvironmentMergeOptions {
56
+ /** Whether to include warnings for conflicting variables */
57
+ includeConflictWarnings?: boolean;
58
+ /** Whether to validate variable names for common patterns */
59
+ validateVariableNames?: boolean;
60
+ }
@@ -8,7 +8,7 @@
8
8
  import { join } from "path";
9
9
  import { homedir } from "os";
10
10
 
11
- // Session path utility (from session.ts)
11
+ // Session path utility (simplified version for hooks)
12
12
  export function getSessionFilePath(sessionId: string): string {
13
13
  const shortId = sessionId.split("_")[2] || sessionId.slice(-8);
14
14
  return join(homedir(), ".wave", "sessions", `session_${shortId}.json`);
@@ -19,7 +19,8 @@ export type HookEvent =
19
19
  | "PreToolUse"
20
20
  | "PostToolUse"
21
21
  | "UserPromptSubmit"
22
- | "Stop";
22
+ | "Stop"
23
+ | "SubagentStop";
23
24
 
24
25
  // Individual hook command configuration
25
26
  export interface HookCommand {
@@ -33,8 +34,14 @@ export interface HookEventConfig {
33
34
  hooks: HookCommand[];
34
35
  }
35
36
 
36
- // Root configuration structure for all hook definitions
37
- export interface HookConfiguration {
37
+ // Root configuration structure for all Wave Agent settings including hooks and environment variables
38
+ export interface WaveConfiguration {
39
+ hooks?: Partial<Record<HookEvent, HookEventConfig[]>>;
40
+ env?: Record<string, string>; // Environment variables key-value pairs
41
+ }
42
+
43
+ // Legacy alias for backward compatibility - will be deprecated
44
+ export interface HookConfiguration extends WaveConfiguration {
38
45
  hooks: Partial<Record<HookEvent, HookEventConfig[]>>;
39
46
  }
40
47
 
@@ -104,9 +111,13 @@ export class HookConfigurationError extends Error {
104
111
 
105
112
  // Type guards for runtime validation
106
113
  export function isValidHookEvent(event: string): event is HookEvent {
107
- return ["PreToolUse", "PostToolUse", "UserPromptSubmit", "Stop"].includes(
108
- event,
109
- );
114
+ return [
115
+ "PreToolUse",
116
+ "PostToolUse",
117
+ "UserPromptSubmit",
118
+ "Stop",
119
+ "SubagentStop",
120
+ ].includes(event);
110
121
  }
111
122
 
112
123
  export function isValidHookCommand(cmd: unknown): cmd is HookCommand {
@@ -144,13 +155,14 @@ export interface HookJsonInput {
144
155
  session_id: string; // Format: "wave_session_{uuid}_{shortId}"
145
156
  transcript_path: string; // Format: "~/.wave/sessions/session_{shortId}.json"
146
157
  cwd: string; // Absolute path to current working directory
147
- hook_event_name: HookEvent; // "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop"
158
+ hook_event_name: HookEvent; // "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop" | "SubagentStop"
148
159
 
149
160
  // Optional fields based on event type
150
161
  tool_name?: string; // Present for PreToolUse, PostToolUse
151
162
  tool_input?: unknown; // Present for PreToolUse, PostToolUse
152
163
  tool_response?: unknown; // Present for PostToolUse only
153
164
  user_prompt?: string; // Present for UserPromptSubmit only
165
+ subagent_type?: string; // Present when hook is executed by a subagent
154
166
  }
155
167
 
156
168
  // Extended context interface for passing additional data to hook executor
@@ -161,6 +173,7 @@ export interface ExtendedHookExecutionContext extends HookExecutionContext {
161
173
  toolInput?: unknown; // Tool input parameters (PreToolUse/PostToolUse)
162
174
  toolResponse?: unknown; // Tool execution result (PostToolUse only)
163
175
  userPrompt?: string; // User prompt text (UserPromptSubmit only)
176
+ subagentType?: string; // Subagent type when hook is executed by a subagent
164
177
  }
165
178
 
166
179
  // Environment variables injected into hook processes
@@ -21,3 +21,5 @@ export * from "./processes.js";
21
21
  export * from "./commands.js";
22
22
  export * from "./skills.js";
23
23
  export * from "./config.js";
24
+ export * from "./session.js";
25
+ export * from "./environment.js";
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Memory Store Type Definitions
3
+ *
4
+ * Provides TypeScript types for in-memory file storage system,
5
+ * enabling optimized access to frequently read files like AGENTS.md.
6
+ */
7
+
8
+ export interface MemoryStore {
9
+ content: string; // Current file content in memory
10
+ lastModified: number; // File modification timestamp
11
+ path: string; // Absolute file path
12
+ isLoaded: boolean; // Whether content has been loaded
13
+ }
14
+
15
+ export interface MemoryStoreEntry {
16
+ content: string;
17
+ path: string;
18
+ lastModified: number;
19
+ isLoaded: boolean;
20
+ }
21
+
22
+ export interface MemoryStoreStats {
23
+ contentSize: number;
24
+ lastUpdated: number;
25
+ updateCount: number;
26
+ isLoaded: boolean;
27
+ }
28
+
29
+ export interface MemoryUpdateEvent {
30
+ path: string;
31
+ reason: "file_change" | "initial_load" | "manual_reload";
32
+ timestamp: number;
33
+ previousSize?: number;
34
+ newSize: number;
35
+ }
36
+
37
+ /**
38
+ * Memory Store Service Interface
39
+ * Maps to FR-006, FR-007: Memory storage and updates
40
+ */
41
+ export interface MemoryStoreService {
42
+ /**
43
+ * Get content from memory store (loads from file if not loaded)
44
+ * Maps to FR-006: Keep AGENTS.md content in memory to avoid repeated reads
45
+ */
46
+ getContent(path: string): Promise<string>;
47
+
48
+ /**
49
+ * Update memory content from file
50
+ * Maps to FR-007: Update memory content when file changes
51
+ */
52
+ updateContent(path: string): Promise<void>;
53
+
54
+ /**
55
+ * Get memory store statistics
56
+ * For monitoring and debugging
57
+ */
58
+ getStats(path?: string): MemoryStoreStats;
59
+
60
+ /**
61
+ * Check if content is loaded in memory
62
+ * For status checking
63
+ */
64
+ isLoaded(path: string): boolean;
65
+
66
+ /**
67
+ * Manually reload content from file
68
+ * For force refresh scenarios
69
+ */
70
+ reloadContent(path: string): Promise<void>;
71
+
72
+ /**
73
+ * Remove content from memory store
74
+ * For cleanup when file is deleted
75
+ */
76
+ removeContent(path: string): boolean;
77
+
78
+ /**
79
+ * Clear all content from memory store
80
+ * For cleanup and testing
81
+ */
82
+ clear(): void;
83
+
84
+ /**
85
+ * Get all stored paths
86
+ * For monitoring and debugging
87
+ */
88
+ getStoredPaths(): string[];
89
+
90
+ /**
91
+ * Check if file exists and is accessible
92
+ */
93
+ fileExists(path: string): Promise<boolean>;
94
+ }
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { Usage } from "./core.js";
7
+ import type { SubagentConfiguration } from "../utils/subagentParser.js";
7
8
 
8
9
  export enum MessageSource {
9
10
  USER = "user",
@@ -14,6 +15,7 @@ export interface Message {
14
15
  role: "user" | "assistant";
15
16
  blocks: MessageBlock[];
16
17
  usage?: Usage; // Usage data for this message's AI operation (assistant messages only)
18
+ metadata?: Record<string, unknown>; // Additional metadata from AI responses
17
19
  }
18
20
 
19
21
  export type MessageBlock =
@@ -51,10 +53,18 @@ export interface ToolBlock {
51
53
  }>;
52
54
  id?: string;
53
55
  name?: string;
54
- isRunning?: boolean; // Mark if tool is actually executing
56
+ /**
57
+ * Tool execution stage:
58
+ * - 'start': Tool call initiated (from AI service streaming)
59
+ * - 'streaming': Tool parameters being streamed (from AI service)
60
+ * - 'running': Tool execution in progress (from AI manager)
61
+ * - 'end': Tool execution completed (from AI manager)
62
+ */
63
+ stage: "start" | "streaming" | "running" | "end";
55
64
  success?: boolean;
56
65
  error?: string | Error;
57
66
  compactParams?: string; // Compact parameter display
67
+ parametersChunk?: string; // Incremental parameter updates for streaming
58
68
  }
59
69
 
60
70
  export interface ImageBlock {
@@ -83,6 +93,7 @@ export interface CommandOutputBlock {
83
93
  export interface CompressBlock {
84
94
  type: "compress";
85
95
  content: string;
96
+ sessionId: string;
86
97
  }
87
98
 
88
99
  export interface MemoryBlock {
@@ -98,5 +109,6 @@ export interface SubagentBlock {
98
109
  subagentId: string;
99
110
  subagentName: string;
100
111
  status: "active" | "completed" | "error" | "aborted";
101
- messages: Message[];
112
+ sessionId: string;
113
+ configuration: SubagentConfiguration;
102
114
  }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Session management types for project-based organization with JSONL format
3
+ * Dependencies: Core messaging types
4
+ *
5
+ * SIMPLIFIED: Removed unused interfaces to focus on core functionality
6
+ */
7
+
8
+ import type { Message } from "./messaging.js";
9
+
10
+ // Enhanced message interface for JSONL storage (extends existing Message)
11
+ export interface SessionMessage extends Message {
12
+ timestamp: string; // ISO 8601 - added for JSONL format
13
+ // Inherits: role: "user" | "assistant", blocks: MessageBlock[], usage?, metadata?
14
+ }
15
+
16
+ // Metadata line that appears as the first line in JSONL session files
17
+ export interface SessionMetadataLine {
18
+ __meta__: true;
19
+ sessionId: string;
20
+ sessionType: "main" | "subagent";
21
+ parentSessionId?: string;
22
+ subagentType?: string;
23
+ workdir: string;
24
+ startedAt: string;
25
+ }