wave-agent-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/README.md +32 -0
  2. package/dist/agent.d.ts +96 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +286 -0
  5. package/dist/hooks/executor.d.ts +56 -0
  6. package/dist/hooks/executor.d.ts.map +1 -0
  7. package/dist/hooks/executor.js +312 -0
  8. package/dist/hooks/index.d.ts +17 -0
  9. package/dist/hooks/index.d.ts.map +1 -0
  10. package/dist/hooks/index.js +14 -0
  11. package/dist/hooks/manager.d.ts +90 -0
  12. package/dist/hooks/manager.d.ts.map +1 -0
  13. package/dist/hooks/manager.js +395 -0
  14. package/dist/hooks/matcher.d.ts +49 -0
  15. package/dist/hooks/matcher.d.ts.map +1 -0
  16. package/dist/hooks/matcher.js +147 -0
  17. package/dist/hooks/settings.d.ts +46 -0
  18. package/dist/hooks/settings.d.ts.map +1 -0
  19. package/dist/hooks/settings.js +100 -0
  20. package/dist/hooks/types.d.ts +80 -0
  21. package/dist/hooks/types.d.ts.map +1 -0
  22. package/dist/hooks/types.js +59 -0
  23. package/dist/index.d.ts +16 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +20 -0
  26. package/dist/managers/aiManager.d.ts +61 -0
  27. package/dist/managers/aiManager.d.ts.map +1 -0
  28. package/dist/managers/aiManager.js +415 -0
  29. package/dist/managers/backgroundBashManager.d.ts +27 -0
  30. package/dist/managers/backgroundBashManager.d.ts.map +1 -0
  31. package/dist/managers/backgroundBashManager.js +166 -0
  32. package/dist/managers/bashManager.d.ts +20 -0
  33. package/dist/managers/bashManager.d.ts.map +1 -0
  34. package/dist/managers/bashManager.js +66 -0
  35. package/dist/managers/mcpManager.d.ts +63 -0
  36. package/dist/managers/mcpManager.d.ts.map +1 -0
  37. package/dist/managers/mcpManager.js +378 -0
  38. package/dist/managers/messageManager.d.ts +85 -0
  39. package/dist/managers/messageManager.d.ts.map +1 -0
  40. package/dist/managers/messageManager.js +265 -0
  41. package/dist/managers/skillManager.d.ts +59 -0
  42. package/dist/managers/skillManager.d.ts.map +1 -0
  43. package/dist/managers/skillManager.js +317 -0
  44. package/dist/managers/slashCommandManager.d.ts +77 -0
  45. package/dist/managers/slashCommandManager.d.ts.map +1 -0
  46. package/dist/managers/slashCommandManager.js +208 -0
  47. package/dist/managers/toolManager.d.ts +23 -0
  48. package/dist/managers/toolManager.d.ts.map +1 -0
  49. package/dist/managers/toolManager.js +79 -0
  50. package/dist/services/aiService.d.ts +28 -0
  51. package/dist/services/aiService.d.ts.map +1 -0
  52. package/dist/services/aiService.js +180 -0
  53. package/dist/services/memory.d.ts +8 -0
  54. package/dist/services/memory.d.ts.map +1 -0
  55. package/dist/services/memory.js +128 -0
  56. package/dist/services/session.d.ts +54 -0
  57. package/dist/services/session.d.ts.map +1 -0
  58. package/dist/services/session.js +196 -0
  59. package/dist/tools/bashTool.d.ts +14 -0
  60. package/dist/tools/bashTool.d.ts.map +1 -0
  61. package/dist/tools/bashTool.js +351 -0
  62. package/dist/tools/deleteFileTool.d.ts +6 -0
  63. package/dist/tools/deleteFileTool.d.ts.map +1 -0
  64. package/dist/tools/deleteFileTool.js +67 -0
  65. package/dist/tools/editTool.d.ts +6 -0
  66. package/dist/tools/editTool.d.ts.map +1 -0
  67. package/dist/tools/editTool.js +168 -0
  68. package/dist/tools/globTool.d.ts +6 -0
  69. package/dist/tools/globTool.d.ts.map +1 -0
  70. package/dist/tools/globTool.js +113 -0
  71. package/dist/tools/grepTool.d.ts +6 -0
  72. package/dist/tools/grepTool.d.ts.map +1 -0
  73. package/dist/tools/grepTool.js +268 -0
  74. package/dist/tools/lsTool.d.ts +6 -0
  75. package/dist/tools/lsTool.d.ts.map +1 -0
  76. package/dist/tools/lsTool.js +160 -0
  77. package/dist/tools/multiEditTool.d.ts +6 -0
  78. package/dist/tools/multiEditTool.d.ts.map +1 -0
  79. package/dist/tools/multiEditTool.js +222 -0
  80. package/dist/tools/readTool.d.ts +6 -0
  81. package/dist/tools/readTool.d.ts.map +1 -0
  82. package/dist/tools/readTool.js +136 -0
  83. package/dist/tools/types.d.ts +35 -0
  84. package/dist/tools/types.d.ts.map +1 -0
  85. package/dist/tools/types.js +4 -0
  86. package/dist/tools/writeTool.d.ts +6 -0
  87. package/dist/tools/writeTool.d.ts.map +1 -0
  88. package/dist/tools/writeTool.js +138 -0
  89. package/dist/types.d.ts +212 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +13 -0
  92. package/dist/utils/bashHistory.d.ts +46 -0
  93. package/dist/utils/bashHistory.d.ts.map +1 -0
  94. package/dist/utils/bashHistory.js +236 -0
  95. package/dist/utils/commandArgumentParser.d.ts +34 -0
  96. package/dist/utils/commandArgumentParser.d.ts.map +1 -0
  97. package/dist/utils/commandArgumentParser.js +123 -0
  98. package/dist/utils/constants.d.ts +27 -0
  99. package/dist/utils/constants.d.ts.map +1 -0
  100. package/dist/utils/constants.js +28 -0
  101. package/dist/utils/convertMessagesForAPI.d.ts +9 -0
  102. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -0
  103. package/dist/utils/convertMessagesForAPI.js +189 -0
  104. package/dist/utils/customCommands.d.ts +14 -0
  105. package/dist/utils/customCommands.d.ts.map +1 -0
  106. package/dist/utils/customCommands.js +71 -0
  107. package/dist/utils/fileFilter.d.ts +26 -0
  108. package/dist/utils/fileFilter.d.ts.map +1 -0
  109. package/dist/utils/fileFilter.js +177 -0
  110. package/dist/utils/markdownParser.d.ts +27 -0
  111. package/dist/utils/markdownParser.d.ts.map +1 -0
  112. package/dist/utils/markdownParser.js +109 -0
  113. package/dist/utils/mcpUtils.d.ts +24 -0
  114. package/dist/utils/mcpUtils.d.ts.map +1 -0
  115. package/dist/utils/mcpUtils.js +51 -0
  116. package/dist/utils/messageOperations.d.ts +118 -0
  117. package/dist/utils/messageOperations.d.ts.map +1 -0
  118. package/dist/utils/messageOperations.js +334 -0
  119. package/dist/utils/path.d.ts +25 -0
  120. package/dist/utils/path.d.ts.map +1 -0
  121. package/dist/utils/path.js +109 -0
  122. package/dist/utils/skillParser.d.ts +18 -0
  123. package/dist/utils/skillParser.d.ts.map +1 -0
  124. package/dist/utils/skillParser.js +147 -0
  125. package/dist/utils/stringUtils.d.ts +13 -0
  126. package/dist/utils/stringUtils.d.ts.map +1 -0
  127. package/dist/utils/stringUtils.js +44 -0
  128. package/package.json +51 -0
  129. package/src/agent.ts +405 -0
  130. package/src/hooks/executor.ts +440 -0
  131. package/src/hooks/index.ts +52 -0
  132. package/src/hooks/manager.ts +618 -0
  133. package/src/hooks/matcher.ts +187 -0
  134. package/src/hooks/settings.ts +129 -0
  135. package/src/hooks/types.ts +169 -0
  136. package/src/index.ts +24 -0
  137. package/src/managers/aiManager.ts +573 -0
  138. package/src/managers/backgroundBashManager.ts +203 -0
  139. package/src/managers/bashManager.ts +97 -0
  140. package/src/managers/mcpManager.ts +493 -0
  141. package/src/managers/messageManager.ts +415 -0
  142. package/src/managers/skillManager.ts +404 -0
  143. package/src/managers/slashCommandManager.ts +293 -0
  144. package/src/managers/toolManager.ts +106 -0
  145. package/src/services/aiService.ts +252 -0
  146. package/src/services/memory.ts +149 -0
  147. package/src/services/session.ts +265 -0
  148. package/src/tools/bashTool.ts +402 -0
  149. package/src/tools/deleteFileTool.ts +81 -0
  150. package/src/tools/editTool.ts +192 -0
  151. package/src/tools/globTool.ts +135 -0
  152. package/src/tools/grepTool.ts +326 -0
  153. package/src/tools/lsTool.ts +187 -0
  154. package/src/tools/multiEditTool.ts +268 -0
  155. package/src/tools/readTool.ts +165 -0
  156. package/src/tools/types.ts +47 -0
  157. package/src/tools/writeTool.ts +163 -0
  158. package/src/types.ts +260 -0
  159. package/src/utils/bashHistory.ts +303 -0
  160. package/src/utils/commandArgumentParser.ts +153 -0
  161. package/src/utils/constants.ts +37 -0
  162. package/src/utils/convertMessagesForAPI.ts +236 -0
  163. package/src/utils/customCommands.ts +85 -0
  164. package/src/utils/fileFilter.ts +202 -0
  165. package/src/utils/markdownParser.ts +156 -0
  166. package/src/utils/mcpUtils.ts +81 -0
  167. package/src/utils/messageOperations.ts +506 -0
  168. package/src/utils/path.ts +118 -0
  169. package/src/utils/skillParser.ts +188 -0
  170. package/src/utils/stringUtils.ts +50 -0
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Hook Pattern Matcher
3
+ *
4
+ * Provides pattern matching functionality for hook tool name matching.
5
+ * Supports exact matching, wildcard patterns, and pipe-separated alternatives.
6
+ */
7
+
8
+ import { minimatch } from "minimatch";
9
+
10
+ export interface IHookMatcher {
11
+ // Test if pattern matches tool name
12
+ matches(pattern: string, toolName: string): boolean;
13
+
14
+ // Validate pattern syntax
15
+ isValidPattern(pattern: string): boolean;
16
+
17
+ // Get pattern type for optimization
18
+ getPatternType(pattern: string): "exact" | "glob" | "regex" | "alternatives";
19
+ }
20
+
21
+ export class HookMatcher implements IHookMatcher {
22
+ /**
23
+ * Test if pattern matches tool name
24
+ * Supports multiple matching strategies:
25
+ * - Exact matching: "Edit" matches "Edit"
26
+ * - Pipe alternatives: "Edit|Write" matches "Edit" or "Write"
27
+ * - Glob patterns: "Edit*" matches "EditFile", "EditText", etc.
28
+ * - Case insensitive matching
29
+ */
30
+ matches(pattern: string, toolName: string): boolean {
31
+ if (!pattern || !toolName) return false;
32
+
33
+ // Handle pipe-separated alternatives (e.g., "Edit|Write|Delete")
34
+ if (pattern.includes("|")) {
35
+ const alternatives = pattern.split("|").map((alt) => alt.trim());
36
+ return alternatives.some((alt) => this.matchesSingle(alt, toolName));
37
+ }
38
+
39
+ return this.matchesSingle(pattern, toolName);
40
+ }
41
+
42
+ /**
43
+ * Match a single pattern against tool name
44
+ */
45
+ private matchesSingle(pattern: string, toolName: string): boolean {
46
+ // Exact match (case insensitive)
47
+ if (pattern.toLowerCase() === toolName.toLowerCase()) {
48
+ return true;
49
+ }
50
+
51
+ // Glob pattern matching using minimatch
52
+ try {
53
+ return minimatch(toolName, pattern, {
54
+ nocase: true, // Case insensitive
55
+ noglobstar: false, // Allow ** patterns
56
+ nonegate: true, // Disable negation for security
57
+ });
58
+ } catch {
59
+ // Invalid pattern, fall back to exact match
60
+ return false;
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Validate pattern syntax
66
+ */
67
+ isValidPattern(pattern: string): boolean {
68
+ if (!pattern || typeof pattern !== "string") return false;
69
+
70
+ // Empty pattern is invalid
71
+ if (pattern.trim().length === 0) return false;
72
+
73
+ // Handle pipe-separated alternatives
74
+ if (pattern.includes("|")) {
75
+ const alternatives = pattern.split("|").map((alt) => alt.trim());
76
+ return (
77
+ alternatives.length > 0 &&
78
+ alternatives.every(
79
+ (alt) => alt.length > 0 && this.isValidSinglePattern(alt),
80
+ )
81
+ );
82
+ }
83
+
84
+ return this.isValidSinglePattern(pattern);
85
+ }
86
+
87
+ /**
88
+ * Validate single pattern syntax
89
+ */
90
+ private isValidSinglePattern(pattern: string): boolean {
91
+ // Basic validation - non-empty string
92
+ if (!pattern || pattern.trim().length === 0) return false;
93
+
94
+ // Check for dangerous characters that could be used for command injection
95
+ // Note: [ ] are allowed for glob patterns
96
+ const dangerousChars = /[;&|`$(){}><]/;
97
+ if (dangerousChars.test(pattern)) return false;
98
+
99
+ // Validate glob pattern syntax using minimatch
100
+ try {
101
+ // Test with a dummy string to validate pattern
102
+ minimatch("test", pattern, { nocase: true });
103
+ return true;
104
+ } catch {
105
+ return false;
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Get pattern type for optimization
111
+ */
112
+ getPatternType(pattern: string): "exact" | "glob" | "regex" | "alternatives" {
113
+ if (!pattern) return "exact";
114
+
115
+ // Check for pipe alternatives first
116
+ if (pattern.includes("|")) {
117
+ return "alternatives";
118
+ }
119
+
120
+ // Check for regex patterns first (before glob check)
121
+ if (
122
+ pattern.startsWith("/") &&
123
+ pattern.endsWith("/") &&
124
+ pattern.length > 2
125
+ ) {
126
+ return "regex";
127
+ }
128
+
129
+ // Check for glob patterns
130
+ if (
131
+ pattern.includes("*") ||
132
+ pattern.includes("?") ||
133
+ pattern.includes("[")
134
+ ) {
135
+ return "glob";
136
+ }
137
+
138
+ return "exact";
139
+ }
140
+
141
+ /**
142
+ * Get all tool names that would match this pattern from a given list
143
+ * Useful for testing and validation
144
+ */
145
+ getMatches(pattern: string, toolNames: string[]): string[] {
146
+ return toolNames.filter((toolName) => this.matches(pattern, toolName));
147
+ }
148
+
149
+ /**
150
+ * Optimize pattern for repeated matching
151
+ * Returns a compiled matcher function for performance
152
+ */
153
+ compile(pattern: string): (toolName: string) => boolean {
154
+ if (!this.isValidPattern(pattern)) {
155
+ return () => false;
156
+ }
157
+
158
+ const patternType = this.getPatternType(pattern);
159
+
160
+ switch (patternType) {
161
+ case "exact": {
162
+ const lowerPattern = pattern.toLowerCase();
163
+ return (toolName: string) => toolName.toLowerCase() === lowerPattern;
164
+ }
165
+
166
+ case "alternatives": {
167
+ const alternatives = pattern
168
+ .split("|")
169
+ .map((alt) => alt.trim().toLowerCase());
170
+ return (toolName: string) => {
171
+ const lowerTool = toolName.toLowerCase();
172
+ return alternatives.some(
173
+ (alt) =>
174
+ lowerTool === alt || minimatch(toolName, alt, { nocase: true }),
175
+ );
176
+ };
177
+ }
178
+
179
+ case "glob":
180
+ return (toolName: string) =>
181
+ minimatch(toolName, pattern, { nocase: true });
182
+
183
+ default:
184
+ return (toolName: string) => this.matches(pattern, toolName);
185
+ }
186
+ }
187
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Hook Settings Management
3
+ *
4
+ * Handles loading and merging of hook configurations from:
5
+ * - User settings: ~/.wave/hooks.json
6
+ * - Project settings: ./.wave/hooks.json
7
+ */
8
+
9
+ import { existsSync, readFileSync } from "fs";
10
+ import { join } from "path";
11
+ import { homedir } from "os";
12
+ import type { HookConfiguration, PartialHookConfiguration } from "./types.js";
13
+ import { isValidHookEvent } from "./types.js";
14
+
15
+ /**
16
+ * Get the user-specific hooks configuration file path
17
+ */
18
+ export function getUserHooksConfigPath(): string {
19
+ return join(homedir(), ".wave", "hooks.json");
20
+ }
21
+
22
+ /**
23
+ * Get the project-specific hooks configuration file path
24
+ */
25
+ export function getProjectHooksConfigPath(workdir: string): string {
26
+ return join(workdir, ".wave", "hooks.json");
27
+ }
28
+
29
+ /**
30
+ * Load hooks configuration from a JSON file
31
+ */
32
+ export function loadHooksConfigFromFile(
33
+ filePath: string,
34
+ ): PartialHookConfiguration | null {
35
+ try {
36
+ if (!existsSync(filePath)) {
37
+ return null;
38
+ }
39
+
40
+ const content = readFileSync(filePath, "utf-8");
41
+ const config = JSON.parse(content) as HookConfiguration;
42
+
43
+ // Validate basic structure
44
+ if (!config || typeof config !== "object" || !config.hooks) {
45
+ console.warn(`Invalid hooks configuration structure in ${filePath}`);
46
+ return null;
47
+ }
48
+
49
+ return config.hooks;
50
+ } catch (error) {
51
+ console.warn(`Failed to load hooks configuration from ${filePath}:`, error);
52
+ return null;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Load user hooks configuration
58
+ */
59
+ export function loadUserHooksConfig(): PartialHookConfiguration | null {
60
+ return loadHooksConfigFromFile(getUserHooksConfigPath());
61
+ }
62
+
63
+ /**
64
+ * Load project hooks configuration
65
+ */
66
+ export function loadProjectHooksConfig(
67
+ workdir: string,
68
+ ): PartialHookConfiguration | null {
69
+ return loadHooksConfigFromFile(getProjectHooksConfigPath(workdir));
70
+ }
71
+
72
+ /**
73
+ * Load and merge hooks configuration with project settings taking precedence
74
+ */
75
+ export function loadMergedHooksConfig(
76
+ workdir: string,
77
+ ): PartialHookConfiguration {
78
+ const userConfig = loadUserHooksConfig();
79
+ const projectConfig = loadProjectHooksConfig(workdir);
80
+
81
+ const merged: PartialHookConfiguration = {};
82
+
83
+ // Start with user configuration
84
+ if (userConfig) {
85
+ Object.entries(userConfig).forEach(([event, configs]) => {
86
+ if (isValidHookEvent(event)) {
87
+ merged[event] = [...configs];
88
+ }
89
+ });
90
+ }
91
+
92
+ // Override with project configuration (project takes precedence)
93
+ if (projectConfig) {
94
+ Object.entries(projectConfig).forEach(([event, configs]) => {
95
+ if (isValidHookEvent(event)) {
96
+ merged[event] = [...configs];
97
+ }
98
+ });
99
+ }
100
+
101
+ return merged;
102
+ }
103
+
104
+ /**
105
+ * Check if any hooks configuration files exist
106
+ */
107
+ export function hasHooksConfiguration(workdir: string): boolean {
108
+ return (
109
+ existsSync(getUserHooksConfigPath()) ||
110
+ existsSync(getProjectHooksConfigPath(workdir))
111
+ );
112
+ }
113
+
114
+ /**
115
+ * Get information about available hooks configuration files
116
+ */
117
+ export function getHooksConfigurationInfo(workdir: string): {
118
+ userConfigExists: boolean;
119
+ projectConfigExists: boolean;
120
+ userConfigPath: string;
121
+ projectConfigPath: string;
122
+ } {
123
+ return {
124
+ userConfigExists: existsSync(getUserHooksConfigPath()),
125
+ projectConfigExists: existsSync(getProjectHooksConfigPath(workdir)),
126
+ userConfigPath: getUserHooksConfigPath(),
127
+ projectConfigPath: getProjectHooksConfigPath(workdir),
128
+ };
129
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Hooks System Type Definitions
3
+ *
4
+ * Provides comprehensive TypeScript types for the Wave Code hooks system,
5
+ * enabling automated actions at specific workflow points.
6
+ */
7
+
8
+ import { join } from "path";
9
+ import { homedir } from "os";
10
+
11
+ // Session path utility (from session.ts)
12
+ export function getSessionFilePath(sessionId: string): string {
13
+ const shortId = sessionId.split("_")[2] || sessionId.slice(-8);
14
+ return join(homedir(), ".wave", "sessions", `session_${shortId}.json`);
15
+ }
16
+
17
+ // Hook event types - trigger points in the AI workflow
18
+ export type HookEvent =
19
+ | "PreToolUse"
20
+ | "PostToolUse"
21
+ | "UserPromptSubmit"
22
+ | "Stop";
23
+
24
+ // Individual hook command configuration
25
+ export interface HookCommand {
26
+ type: "command";
27
+ command: string;
28
+ }
29
+
30
+ // Hook event configuration with optional pattern matching
31
+ export interface HookEventConfig {
32
+ matcher?: string; // Required for PreToolUse/PostToolUse, omitted for others
33
+ hooks: HookCommand[];
34
+ }
35
+
36
+ // Root configuration structure for all hook definitions
37
+ export interface HookConfiguration {
38
+ hooks: Partial<Record<HookEvent, HookEventConfig[]>>;
39
+ }
40
+
41
+ // Partial hook configuration for loading/merging scenarios
42
+ export type PartialHookConfiguration = Partial<
43
+ Record<HookEvent, HookEventConfig[]>
44
+ >;
45
+
46
+ // Direct hook configuration record (for test convenience)
47
+ export type HookConfigurationRecord = Record<HookEvent, HookEventConfig[]>;
48
+
49
+ // Context passed to hook during execution
50
+ export interface HookExecutionContext {
51
+ event: HookEvent;
52
+ toolName?: string; // Present for PreToolUse/PostToolUse events
53
+ projectDir: string; // Absolute path for $WAVE_PROJECT_DIR
54
+ timestamp: Date;
55
+ }
56
+
57
+ // Result of hook execution
58
+ export interface HookExecutionResult {
59
+ success: boolean;
60
+ exitCode?: number;
61
+ stdout?: string;
62
+ stderr?: string;
63
+ duration: number; // milliseconds
64
+ timedOut: boolean;
65
+ }
66
+
67
+ // Hook execution options
68
+ export interface HookExecutionOptions {
69
+ timeout?: number; // milliseconds, default 10000
70
+ cwd?: string; // working directory, defaults to projectDir
71
+ }
72
+
73
+ // Validation result for hook configuration
74
+ export interface ValidationResult {
75
+ valid: boolean;
76
+ errors: string[];
77
+ }
78
+
79
+ // Hook execution errors (non-blocking)
80
+ export class HookExecutionError extends Error {
81
+ constructor(
82
+ public readonly hookCommand: string,
83
+ public readonly originalError: Error,
84
+ public readonly context: HookExecutionContext,
85
+ ) {
86
+ super(`Hook execution failed: ${hookCommand} - ${originalError.message}`);
87
+ this.name = "HookExecutionError";
88
+ }
89
+ }
90
+
91
+ // Configuration validation errors (blocking)
92
+ export class HookConfigurationError extends Error {
93
+ constructor(
94
+ public readonly configPath: string,
95
+ public readonly validationErrors: string[],
96
+ ) {
97
+ super(
98
+ `Hook configuration error in ${configPath}: ${validationErrors.join(", ")}`,
99
+ );
100
+ this.name = "HookConfigurationError";
101
+ }
102
+ }
103
+
104
+ // Type guards for runtime validation
105
+ export function isValidHookEvent(event: string): event is HookEvent {
106
+ return ["PreToolUse", "PostToolUse", "UserPromptSubmit", "Stop"].includes(
107
+ event,
108
+ );
109
+ }
110
+
111
+ export function isValidHookCommand(cmd: unknown): cmd is HookCommand {
112
+ return (
113
+ typeof cmd === "object" &&
114
+ cmd !== null &&
115
+ "type" in cmd &&
116
+ cmd.type === "command" &&
117
+ "command" in cmd &&
118
+ typeof cmd.command === "string" &&
119
+ cmd.command.length > 0
120
+ );
121
+ }
122
+
123
+ export function isValidHookEventConfig(
124
+ config: unknown,
125
+ ): config is HookEventConfig {
126
+ if (typeof config !== "object" || config === null) return false;
127
+
128
+ const cfg = config as Record<string, unknown>;
129
+
130
+ // Validate hooks array
131
+ if (!Array.isArray(cfg.hooks) || cfg.hooks.length === 0) return false;
132
+ if (!cfg.hooks.every(isValidHookCommand)) return false;
133
+
134
+ // Validate optional matcher
135
+ if ("matcher" in cfg && typeof cfg.matcher !== "string") return false;
136
+
137
+ return true;
138
+ }
139
+
140
+ // JSON structure passed to hooks via stdin
141
+ export interface HookJsonInput {
142
+ // Required fields for all events
143
+ session_id: string; // Format: "wave_session_{uuid}_{shortId}"
144
+ transcript_path: string; // Format: "~/.wave/sessions/session_{shortId}.json"
145
+ cwd: string; // Absolute path to current working directory
146
+ hook_event_name: HookEvent; // "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop"
147
+
148
+ // Optional fields based on event type
149
+ tool_name?: string; // Present for PreToolUse, PostToolUse
150
+ tool_input?: unknown; // Present for PreToolUse, PostToolUse
151
+ tool_response?: unknown; // Present for PostToolUse only
152
+ user_prompt?: string; // Present for UserPromptSubmit only
153
+ }
154
+
155
+ // Extended context interface for passing additional data to hook executor
156
+ export interface ExtendedHookExecutionContext extends HookExecutionContext {
157
+ sessionId?: string; // Session identifier for JSON construction
158
+ transcriptPath?: string; // Path to session transcript file
159
+ cwd?: string; // Current working directory
160
+ toolInput?: unknown; // Tool input parameters (PreToolUse/PostToolUse)
161
+ toolResponse?: unknown; // Tool execution result (PostToolUse only)
162
+ userPrompt?: string; // User prompt text (UserPromptSubmit only)
163
+ }
164
+
165
+ // Environment variables injected into hook processes
166
+ export interface HookEnvironment {
167
+ WAVE_PROJECT_DIR: string; // Absolute path to project root
168
+ [key: string]: string; // Inherit all parent process environment variables
169
+ }
package/src/index.ts ADDED
@@ -0,0 +1,24 @@
1
+ // Export all services
2
+ export * from "./services/aiService.js";
3
+ export * from "./services/memory.js";
4
+ export * from "./services/session.js";
5
+
6
+ // Export main agent
7
+ export * from "./agent.js";
8
+
9
+ // Export all utilities
10
+ export * from "./utils/bashHistory.js";
11
+ export * from "./utils/convertMessagesForAPI.js";
12
+ export * from "./utils/fileFilter.js";
13
+ export * from "./utils/mcpUtils.js";
14
+ export * from "./utils/messageOperations.js";
15
+ export * from "./utils/path.js";
16
+ export * from "./utils/stringUtils.js";
17
+ export * from "./utils/markdownParser.js";
18
+ export * from "./utils/customCommands.js";
19
+
20
+ // Export hooks system
21
+ export * from "./hooks/index.js";
22
+
23
+ // Export types
24
+ export * from "./types.js";