wave-agent-sdk 0.0.7 → 0.0.10

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 (240) hide show
  1. package/dist/agent.d.ts +105 -24
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +438 -53
  4. package/dist/index.d.ts +4 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +4 -0
  7. package/dist/managers/aiManager.d.ts +18 -7
  8. package/dist/managers/aiManager.d.ts.map +1 -1
  9. package/dist/managers/aiManager.js +254 -142
  10. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  11. package/dist/managers/backgroundBashManager.js +11 -9
  12. package/dist/managers/hookManager.d.ts +6 -6
  13. package/dist/managers/hookManager.d.ts.map +1 -1
  14. package/dist/managers/hookManager.js +81 -39
  15. package/dist/managers/liveConfigManager.d.ts +95 -0
  16. package/dist/managers/liveConfigManager.d.ts.map +1 -0
  17. package/dist/managers/liveConfigManager.js +442 -0
  18. package/dist/managers/lspManager.d.ts +43 -0
  19. package/dist/managers/lspManager.d.ts.map +1 -0
  20. package/dist/managers/lspManager.js +326 -0
  21. package/dist/managers/messageManager.d.ts +41 -24
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +184 -73
  24. package/dist/managers/permissionManager.d.ts +66 -0
  25. package/dist/managers/permissionManager.d.ts.map +1 -0
  26. package/dist/managers/permissionManager.js +208 -0
  27. package/dist/managers/skillManager.d.ts +1 -0
  28. package/dist/managers/skillManager.d.ts.map +1 -1
  29. package/dist/managers/skillManager.js +2 -1
  30. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  31. package/dist/managers/slashCommandManager.js +4 -2
  32. package/dist/managers/subagentManager.d.ts +42 -6
  33. package/dist/managers/subagentManager.d.ts.map +1 -1
  34. package/dist/managers/subagentManager.js +213 -62
  35. package/dist/managers/toolManager.d.ts +38 -1
  36. package/dist/managers/toolManager.d.ts.map +1 -1
  37. package/dist/managers/toolManager.js +66 -2
  38. package/dist/services/aiService.d.ts +15 -5
  39. package/dist/services/aiService.d.ts.map +1 -1
  40. package/dist/services/aiService.js +446 -77
  41. package/dist/services/configurationService.d.ts +116 -0
  42. package/dist/services/configurationService.d.ts.map +1 -0
  43. package/dist/services/configurationService.js +585 -0
  44. package/dist/services/fileWatcher.d.ts +69 -0
  45. package/dist/services/fileWatcher.d.ts.map +1 -0
  46. package/dist/services/fileWatcher.js +212 -0
  47. package/dist/services/hook.d.ts +5 -40
  48. package/dist/services/hook.d.ts.map +1 -1
  49. package/dist/services/hook.js +47 -109
  50. package/dist/services/jsonlHandler.d.ts +71 -0
  51. package/dist/services/jsonlHandler.d.ts.map +1 -0
  52. package/dist/services/jsonlHandler.js +236 -0
  53. package/dist/services/memory.d.ts.map +1 -1
  54. package/dist/services/memory.js +33 -11
  55. package/dist/services/session.d.ts +116 -52
  56. package/dist/services/session.d.ts.map +1 -1
  57. package/dist/services/session.js +415 -143
  58. package/dist/tools/bashTool.d.ts.map +1 -1
  59. package/dist/tools/bashTool.js +77 -17
  60. package/dist/tools/deleteFileTool.d.ts.map +1 -1
  61. package/dist/tools/deleteFileTool.js +27 -1
  62. package/dist/tools/editTool.d.ts.map +1 -1
  63. package/dist/tools/editTool.js +33 -8
  64. package/dist/tools/lspTool.d.ts +6 -0
  65. package/dist/tools/lspTool.d.ts.map +1 -0
  66. package/dist/tools/lspTool.js +589 -0
  67. package/dist/tools/multiEditTool.d.ts.map +1 -1
  68. package/dist/tools/multiEditTool.js +30 -10
  69. package/dist/tools/readTool.d.ts.map +1 -1
  70. package/dist/tools/readTool.js +113 -3
  71. package/dist/tools/skillTool.js +2 -2
  72. package/dist/tools/todoWriteTool.d.ts.map +1 -1
  73. package/dist/tools/todoWriteTool.js +23 -0
  74. package/dist/tools/types.d.ts +11 -8
  75. package/dist/tools/types.d.ts.map +1 -1
  76. package/dist/tools/writeTool.d.ts.map +1 -1
  77. package/dist/tools/writeTool.js +30 -15
  78. package/dist/types/commands.d.ts +4 -1
  79. package/dist/types/commands.d.ts.map +1 -1
  80. package/dist/types/config.d.ts +4 -0
  81. package/dist/types/config.d.ts.map +1 -1
  82. package/dist/types/configuration.d.ts +69 -0
  83. package/dist/types/configuration.d.ts.map +1 -0
  84. package/dist/types/configuration.js +8 -0
  85. package/dist/types/core.d.ts +45 -0
  86. package/dist/types/core.d.ts.map +1 -1
  87. package/dist/types/environment.d.ts +83 -0
  88. package/dist/types/environment.d.ts.map +1 -0
  89. package/dist/types/environment.js +21 -0
  90. package/dist/types/fileSearch.d.ts +5 -0
  91. package/dist/types/fileSearch.d.ts.map +1 -0
  92. package/dist/types/fileSearch.js +1 -0
  93. package/dist/types/hooks.d.ts +18 -3
  94. package/dist/types/hooks.d.ts.map +1 -1
  95. package/dist/types/hooks.js +8 -8
  96. package/dist/types/index.d.ts +7 -0
  97. package/dist/types/index.d.ts.map +1 -1
  98. package/dist/types/index.js +7 -0
  99. package/dist/types/lsp.d.ts +90 -0
  100. package/dist/types/lsp.d.ts.map +1 -0
  101. package/dist/types/lsp.js +4 -0
  102. package/dist/types/messaging.d.ts +19 -12
  103. package/dist/types/messaging.d.ts.map +1 -1
  104. package/dist/types/permissions.d.ts +35 -0
  105. package/dist/types/permissions.d.ts.map +1 -0
  106. package/dist/types/permissions.js +12 -0
  107. package/dist/types/session.d.ts +15 -0
  108. package/dist/types/session.d.ts.map +1 -0
  109. package/dist/types/session.js +7 -0
  110. package/dist/types/skills.d.ts +1 -0
  111. package/dist/types/skills.d.ts.map +1 -1
  112. package/dist/types/tools.d.ts +35 -0
  113. package/dist/types/tools.d.ts.map +1 -0
  114. package/dist/types/tools.js +4 -0
  115. package/dist/utils/abortUtils.d.ts +34 -0
  116. package/dist/utils/abortUtils.d.ts.map +1 -0
  117. package/dist/utils/abortUtils.js +92 -0
  118. package/dist/utils/bashHistory.d.ts +4 -0
  119. package/dist/utils/bashHistory.d.ts.map +1 -1
  120. package/dist/utils/bashHistory.js +48 -30
  121. package/dist/utils/builtinSubagents.d.ts +7 -0
  122. package/dist/utils/builtinSubagents.d.ts.map +1 -0
  123. package/dist/utils/builtinSubagents.js +65 -0
  124. package/dist/utils/cacheControlUtils.d.ts +96 -0
  125. package/dist/utils/cacheControlUtils.d.ts.map +1 -0
  126. package/dist/utils/cacheControlUtils.js +324 -0
  127. package/dist/utils/commandPathResolver.d.ts +52 -0
  128. package/dist/utils/commandPathResolver.d.ts.map +1 -0
  129. package/dist/utils/commandPathResolver.js +145 -0
  130. package/dist/utils/configPaths.d.ts +85 -0
  131. package/dist/utils/configPaths.d.ts.map +1 -0
  132. package/dist/utils/configPaths.js +121 -0
  133. package/dist/utils/constants.d.ts +1 -13
  134. package/dist/utils/constants.d.ts.map +1 -1
  135. package/dist/utils/constants.js +2 -14
  136. package/dist/utils/convertMessagesForAPI.d.ts +2 -1
  137. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  138. package/dist/utils/convertMessagesForAPI.js +39 -18
  139. package/dist/utils/customCommands.d.ts.map +1 -1
  140. package/dist/utils/customCommands.js +66 -21
  141. package/dist/utils/fileSearch.d.ts +14 -0
  142. package/dist/utils/fileSearch.d.ts.map +1 -0
  143. package/dist/utils/fileSearch.js +88 -0
  144. package/dist/utils/fileUtils.d.ts +27 -0
  145. package/dist/utils/fileUtils.d.ts.map +1 -0
  146. package/dist/utils/fileUtils.js +145 -0
  147. package/dist/utils/globalLogger.d.ts +88 -0
  148. package/dist/utils/globalLogger.d.ts.map +1 -0
  149. package/dist/utils/globalLogger.js +120 -0
  150. package/dist/utils/largeOutputHandler.d.ts +15 -0
  151. package/dist/utils/largeOutputHandler.d.ts.map +1 -0
  152. package/dist/utils/largeOutputHandler.js +40 -0
  153. package/dist/utils/markdownParser.d.ts.map +1 -1
  154. package/dist/utils/markdownParser.js +1 -17
  155. package/dist/utils/mcpUtils.d.ts.map +1 -1
  156. package/dist/utils/mcpUtils.js +25 -3
  157. package/dist/utils/messageOperations.d.ts +20 -18
  158. package/dist/utils/messageOperations.d.ts.map +1 -1
  159. package/dist/utils/messageOperations.js +30 -38
  160. package/dist/utils/pathEncoder.d.ts +108 -0
  161. package/dist/utils/pathEncoder.d.ts.map +1 -0
  162. package/dist/utils/pathEncoder.js +279 -0
  163. package/dist/utils/subagentParser.d.ts +2 -2
  164. package/dist/utils/subagentParser.d.ts.map +1 -1
  165. package/dist/utils/subagentParser.js +12 -8
  166. package/dist/utils/tokenCalculation.d.ts +26 -0
  167. package/dist/utils/tokenCalculation.d.ts.map +1 -0
  168. package/dist/utils/tokenCalculation.js +36 -0
  169. package/dist/utils/tokenEstimator.d.ts +39 -0
  170. package/dist/utils/tokenEstimator.d.ts.map +1 -0
  171. package/dist/utils/tokenEstimator.js +55 -0
  172. package/package.json +6 -6
  173. package/src/agent.ts +586 -78
  174. package/src/index.ts +4 -0
  175. package/src/managers/aiManager.ts +341 -192
  176. package/src/managers/backgroundBashManager.ts +11 -9
  177. package/src/managers/hookManager.ts +102 -54
  178. package/src/managers/liveConfigManager.ts +634 -0
  179. package/src/managers/lspManager.ts +434 -0
  180. package/src/managers/messageManager.ts +258 -121
  181. package/src/managers/permissionManager.ts +276 -0
  182. package/src/managers/skillManager.ts +3 -1
  183. package/src/managers/slashCommandManager.ts +5 -3
  184. package/src/managers/subagentManager.ts +295 -76
  185. package/src/managers/toolManager.ts +95 -3
  186. package/src/services/aiService.ts +656 -84
  187. package/src/services/configurationService.ts +762 -0
  188. package/src/services/fileWatcher.ts +300 -0
  189. package/src/services/hook.ts +54 -144
  190. package/src/services/jsonlHandler.ts +303 -0
  191. package/src/services/memory.ts +34 -11
  192. package/src/services/session.ts +522 -173
  193. package/src/tools/bashTool.ts +94 -20
  194. package/src/tools/deleteFileTool.ts +38 -1
  195. package/src/tools/editTool.ts +44 -9
  196. package/src/tools/lspTool.ts +760 -0
  197. package/src/tools/multiEditTool.ts +41 -11
  198. package/src/tools/readTool.ts +127 -3
  199. package/src/tools/skillTool.ts +2 -2
  200. package/src/tools/todoWriteTool.ts +33 -1
  201. package/src/tools/types.ts +15 -9
  202. package/src/tools/writeTool.ts +43 -16
  203. package/src/types/commands.ts +6 -1
  204. package/src/types/config.ts +5 -0
  205. package/src/types/configuration.ts +73 -0
  206. package/src/types/core.ts +55 -0
  207. package/src/types/environment.ts +104 -0
  208. package/src/types/fileSearch.ts +4 -0
  209. package/src/types/hooks.ts +32 -16
  210. package/src/types/index.ts +7 -0
  211. package/src/types/lsp.ts +96 -0
  212. package/src/types/messaging.ts +21 -14
  213. package/src/types/permissions.ts +48 -0
  214. package/src/types/session.ts +20 -0
  215. package/src/types/skills.ts +1 -0
  216. package/src/types/tools.ts +38 -0
  217. package/src/utils/abortUtils.ts +118 -0
  218. package/src/utils/bashHistory.ts +55 -31
  219. package/src/utils/builtinSubagents.ts +71 -0
  220. package/src/utils/cacheControlUtils.ts +475 -0
  221. package/src/utils/commandPathResolver.ts +189 -0
  222. package/src/utils/configPaths.ts +163 -0
  223. package/src/utils/constants.ts +2 -17
  224. package/src/utils/convertMessagesForAPI.ts +44 -18
  225. package/src/utils/customCommands.ts +90 -22
  226. package/src/utils/fileSearch.ts +107 -0
  227. package/src/utils/fileUtils.ts +160 -0
  228. package/src/utils/globalLogger.ts +128 -0
  229. package/src/utils/largeOutputHandler.ts +55 -0
  230. package/src/utils/markdownParser.ts +1 -19
  231. package/src/utils/mcpUtils.ts +34 -3
  232. package/src/utils/messageOperations.ts +47 -53
  233. package/src/utils/pathEncoder.ts +394 -0
  234. package/src/utils/subagentParser.ts +13 -9
  235. package/src/utils/tokenCalculation.ts +43 -0
  236. package/src/utils/tokenEstimator.ts +68 -0
  237. package/dist/utils/configResolver.d.ts +0 -38
  238. package/dist/utils/configResolver.d.ts.map +0 -1
  239. package/dist/utils/configResolver.js +0 -106
  240. package/src/utils/configResolver.ts +0 -142
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Command path resolver utilities for nested command discovery
3
+ * Handles conversion between file paths and command IDs with colon syntax
4
+ */
5
+ export interface CommandIdParts {
6
+ namespace?: string;
7
+ commandName: string;
8
+ isNested: boolean;
9
+ depth: number;
10
+ segments: string[];
11
+ }
12
+ /**
13
+ * Generate command ID from file path
14
+ * @param filePath - Absolute path to markdown file
15
+ * @param rootDir - Root commands directory path
16
+ * @returns Command identifier string (e.g., "openspec:apply")
17
+ * @throws Error on invalid path structure
18
+ */
19
+ export declare function generateCommandId(filePath: string, rootDir: string): string;
20
+ /**
21
+ * Parse command ID into components
22
+ * @param commandId - Command identifier (e.g., "openspec:apply")
23
+ * @returns Object with namespace and command name
24
+ * @throws Error on malformed command ID
25
+ */
26
+ export declare function parseCommandId(commandId: string): CommandIdParts;
27
+ /**
28
+ * Validate command ID format
29
+ * @param commandId - Command identifier to validate
30
+ * @returns Boolean indicating validity
31
+ */
32
+ export declare function validateCommandId(commandId: string): boolean;
33
+ /**
34
+ * Convert file path to command segments array
35
+ * @param filePath - Absolute path to markdown file
36
+ * @param rootDir - Root commands directory path
37
+ * @returns Array of path segments
38
+ */
39
+ export declare function getCommandSegments(filePath: string, rootDir: string): string[];
40
+ /**
41
+ * Get namespace from command segments
42
+ * @param segments - Command path segments
43
+ * @returns Namespace string or undefined for flat commands
44
+ */
45
+ export declare function getNamespace(segments: string[]): string | undefined;
46
+ /**
47
+ * Get command depth from segments
48
+ * @param segments - Command path segments
49
+ * @returns Depth number (0 for root, 1 for nested)
50
+ */
51
+ export declare function getDepth(segments: string[]): number;
52
+ //# sourceMappingURL=commandPathResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandPathResolver.d.ts","sourceRoot":"","sources":["../../src/utils/commandPathResolver.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAmD3E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAyChE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAU5D;AAaD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CASV;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,145 @@
1
+ import { relative, basename } from "path";
2
+ /**
3
+ * Generate command ID from file path
4
+ * @param filePath - Absolute path to markdown file
5
+ * @param rootDir - Root commands directory path
6
+ * @returns Command identifier string (e.g., "openspec:apply")
7
+ * @throws Error on invalid path structure
8
+ */
9
+ export function generateCommandId(filePath, rootDir) {
10
+ // Handle null/undefined inputs
11
+ if (filePath == null || rootDir == null) {
12
+ throw new Error("File path and root directory must be provided");
13
+ }
14
+ // Handle empty root directory (for root level commands)
15
+ const relativePath = rootDir === "" ? filePath : relative(rootDir, filePath);
16
+ // Handle edge cases
17
+ if (!relativePath || relativePath === ".") {
18
+ throw new Error("Command filename cannot be empty");
19
+ }
20
+ const segments = relativePath.split("/").filter((segment) => segment !== "");
21
+ // Remove .md extension from the last segment
22
+ const lastSegment = segments[segments.length - 1];
23
+ if (!lastSegment.endsWith(".md")) {
24
+ throw new Error(`Command files must have .md extension`);
25
+ }
26
+ segments[segments.length - 1] = basename(lastSegment, ".md");
27
+ // Handle empty filename after removing extension
28
+ if (segments[segments.length - 1] === "") {
29
+ throw new Error("Command filename cannot be empty");
30
+ }
31
+ // Validate depth (max 1 level of nesting)
32
+ if (segments.length > 2) {
33
+ throw new Error(`Command nesting too deep: ${relativePath}. Maximum depth is 1 level.`);
34
+ }
35
+ // Validate segments
36
+ for (const segment of segments) {
37
+ if (!validateSegment(segment)) {
38
+ throw new Error(`Invalid command path segment: "${segment}" in ${relativePath}. Must match pattern /^[a-zA-Z][a-zA-Z0-9_.-]*$/`);
39
+ }
40
+ }
41
+ // Generate command ID
42
+ if (segments.length === 1) {
43
+ return segments[0]; // Flat command
44
+ }
45
+ else {
46
+ return segments.join(":"); // Nested command with colon syntax
47
+ }
48
+ }
49
+ /**
50
+ * Parse command ID into components
51
+ * @param commandId - Command identifier (e.g., "openspec:apply")
52
+ * @returns Object with namespace and command name
53
+ * @throws Error on malformed command ID
54
+ */
55
+ export function parseCommandId(commandId) {
56
+ // Handle null/undefined inputs
57
+ if (commandId == null) {
58
+ throw new Error("Command ID cannot be null or undefined");
59
+ }
60
+ if (commandId === "") {
61
+ throw new Error("Command ID cannot be empty");
62
+ }
63
+ if (!validateCommandId(commandId)) {
64
+ throw new Error(`Invalid command ID format: "${commandId}". Must match pattern /^[a-zA-Z0-9_-]+(?::[a-zA-Z0-9_-]+)?$/`);
65
+ }
66
+ const parts = commandId.split(":");
67
+ if (parts.length === 1) {
68
+ // Flat command
69
+ return {
70
+ namespace: undefined,
71
+ commandName: parts[0],
72
+ isNested: false,
73
+ depth: 0,
74
+ segments: [parts[0]],
75
+ };
76
+ }
77
+ else if (parts.length === 2) {
78
+ // Nested command
79
+ return {
80
+ namespace: parts[0],
81
+ commandName: parts[1],
82
+ isNested: true,
83
+ depth: 1,
84
+ segments: [parts[0], parts[1]],
85
+ };
86
+ }
87
+ else {
88
+ throw new Error(`Invalid command ID format: "${commandId}". Too many colon separators.`);
89
+ }
90
+ }
91
+ /**
92
+ * Validate command ID format
93
+ * @param commandId - Command identifier to validate
94
+ * @returns Boolean indicating validity
95
+ */
96
+ export function validateCommandId(commandId) {
97
+ // Handle null/undefined inputs
98
+ if (commandId == null) {
99
+ return false;
100
+ }
101
+ // Command ID can have multiple colons (though generateCommandId enforces max 1 level)
102
+ // This validates the format but doesn't enforce depth limits
103
+ const pattern = /^[a-zA-Z][a-zA-Z0-9_-]*(?::[a-zA-Z][a-zA-Z0-9_-]*)*$/;
104
+ return pattern.test(commandId);
105
+ }
106
+ /**
107
+ * Validate individual path segment
108
+ * @param segment - Path segment to validate
109
+ * @returns Boolean indicating validity
110
+ */
111
+ function validateSegment(segment) {
112
+ // Segments should start with letters and can contain letters, numbers, dashes, underscores, dots
113
+ const pattern = /^[a-zA-Z][a-zA-Z0-9_.-]*$/;
114
+ return pattern.test(segment);
115
+ }
116
+ /**
117
+ * Convert file path to command segments array
118
+ * @param filePath - Absolute path to markdown file
119
+ * @param rootDir - Root commands directory path
120
+ * @returns Array of path segments
121
+ */
122
+ export function getCommandSegments(filePath, rootDir) {
123
+ const relativePath = relative(rootDir, filePath);
124
+ const segments = relativePath.split("/").filter((segment) => segment !== "");
125
+ // Remove .md extension from the last segment
126
+ const lastSegment = segments[segments.length - 1];
127
+ segments[segments.length - 1] = basename(lastSegment, ".md");
128
+ return segments;
129
+ }
130
+ /**
131
+ * Get namespace from command segments
132
+ * @param segments - Command path segments
133
+ * @returns Namespace string or undefined for flat commands
134
+ */
135
+ export function getNamespace(segments) {
136
+ return segments.length > 1 ? segments[0] : undefined;
137
+ }
138
+ /**
139
+ * Get command depth from segments
140
+ * @param segments - Command path segments
141
+ * @returns Depth number (0 for root, 1 for nested)
142
+ */
143
+ export function getDepth(segments) {
144
+ return Math.max(0, segments.length - 1);
145
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Configuration Path Utilities
3
+ *
4
+ * Centralized utilities for resolving Wave configuration file paths.
5
+ * Supports both regular settings.json and settings.local.json with proper priority.
6
+ *
7
+ * Priority system:
8
+ * - User configs: ~/.wave/settings.local.json > ~/.wave/settings.json
9
+ * - Project configs: {workdir}/.wave/settings.local.json > {workdir}/.wave/settings.json
10
+ * - Project configs override user configs (existing behavior)
11
+ */
12
+ /**
13
+ * Get the user-specific configuration file path (legacy function)
14
+ * @deprecated Use getUserConfigPaths() for better priority support
15
+ */
16
+ export declare function getUserConfigPath(): string;
17
+ /**
18
+ * Get the project-specific configuration file path (legacy function)
19
+ * @deprecated Use getProjectConfigPaths() for better priority support
20
+ */
21
+ export declare function getProjectConfigPath(workdir: string): string;
22
+ /**
23
+ * Get the user-specific configuration file paths in priority order
24
+ * Returns array with .local.json first, then .json
25
+ */
26
+ export declare function getUserConfigPaths(): string[];
27
+ /**
28
+ * Get the project-specific configuration file paths in priority order
29
+ * Returns array with .local.json first, then .json
30
+ */
31
+ export declare function getProjectConfigPaths(workdir: string): string[];
32
+ /**
33
+ * Get all configuration file paths (user and project) in priority order
34
+ * Useful for comprehensive configuration detection
35
+ */
36
+ export declare function getAllConfigPaths(workdir: string): {
37
+ userPaths: string[];
38
+ projectPaths: string[];
39
+ allPaths: string[];
40
+ };
41
+ /**
42
+ * Get existing configuration file paths
43
+ * Returns only the paths that actually exist on the filesystem
44
+ */
45
+ export declare function getExistingConfigPaths(workdir: string): {
46
+ userPaths: string[];
47
+ projectPaths: string[];
48
+ existingPaths: string[];
49
+ };
50
+ /**
51
+ * Get the first existing configuration file path with the specified priority
52
+ * @param paths Array of paths in priority order
53
+ * @returns The first path that exists, or undefined if none exist
54
+ */
55
+ export declare function getFirstExistingPath(paths: string[]): string | undefined;
56
+ /**
57
+ * Get effective configuration paths (the ones that would actually be used)
58
+ * Returns the highest priority existing path for each category
59
+ */
60
+ export declare function getEffectiveConfigPaths(workdir: string): {
61
+ userPath?: string;
62
+ projectPath?: string;
63
+ effectivePath?: string;
64
+ };
65
+ /**
66
+ * Check if any configuration files exist
67
+ */
68
+ export declare function hasAnyConfig(workdir: string): boolean;
69
+ /**
70
+ * Get configuration information for debugging and monitoring
71
+ */
72
+ export declare function getConfigurationInfo(workdir: string): {
73
+ hasUser: boolean;
74
+ hasProject: boolean;
75
+ paths: string[];
76
+ userPaths: string[];
77
+ projectPaths: string[];
78
+ existingPaths: string[];
79
+ effectivePaths: {
80
+ userPath?: string;
81
+ projectPath?: string;
82
+ effectivePath?: string;
83
+ };
84
+ };
85
+ //# sourceMappingURL=configPaths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configPaths.d.ts","sourceRoot":"","sources":["../../src/utils/configPaths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAG7C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAG/D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAClD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CASA;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG;IACvD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAYA;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAExE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAeA;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,CAcA"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Configuration Path Utilities
3
+ *
4
+ * Centralized utilities for resolving Wave configuration file paths.
5
+ * Supports both regular settings.json and settings.local.json with proper priority.
6
+ *
7
+ * Priority system:
8
+ * - User configs: ~/.wave/settings.local.json > ~/.wave/settings.json
9
+ * - Project configs: {workdir}/.wave/settings.local.json > {workdir}/.wave/settings.json
10
+ * - Project configs override user configs (existing behavior)
11
+ */
12
+ import { join } from "path";
13
+ import { homedir } from "os";
14
+ import { existsSync } from "fs";
15
+ /**
16
+ * Get the user-specific configuration file path (legacy function)
17
+ * @deprecated Use getUserConfigPaths() for better priority support
18
+ */
19
+ export function getUserConfigPath() {
20
+ return join(homedir(), ".wave", "settings.json");
21
+ }
22
+ /**
23
+ * Get the project-specific configuration file path (legacy function)
24
+ * @deprecated Use getProjectConfigPaths() for better priority support
25
+ */
26
+ export function getProjectConfigPath(workdir) {
27
+ return join(workdir, ".wave", "settings.json");
28
+ }
29
+ /**
30
+ * Get the user-specific configuration file paths in priority order
31
+ * Returns array with .local.json first, then .json
32
+ */
33
+ export function getUserConfigPaths() {
34
+ const baseDir = join(homedir(), ".wave");
35
+ return [join(baseDir, "settings.local.json"), join(baseDir, "settings.json")];
36
+ }
37
+ /**
38
+ * Get the project-specific configuration file paths in priority order
39
+ * Returns array with .local.json first, then .json
40
+ */
41
+ export function getProjectConfigPaths(workdir) {
42
+ const baseDir = join(workdir, ".wave");
43
+ return [join(baseDir, "settings.local.json"), join(baseDir, "settings.json")];
44
+ }
45
+ /**
46
+ * Get all configuration file paths (user and project) in priority order
47
+ * Useful for comprehensive configuration detection
48
+ */
49
+ export function getAllConfigPaths(workdir) {
50
+ const userPaths = getUserConfigPaths();
51
+ const projectPaths = getProjectConfigPaths(workdir);
52
+ return {
53
+ userPaths,
54
+ projectPaths,
55
+ allPaths: [...userPaths, ...projectPaths],
56
+ };
57
+ }
58
+ /**
59
+ * Get existing configuration file paths
60
+ * Returns only the paths that actually exist on the filesystem
61
+ */
62
+ export function getExistingConfigPaths(workdir) {
63
+ const allPaths = getAllConfigPaths(workdir);
64
+ const existingUserPaths = allPaths.userPaths.filter(existsSync);
65
+ const existingProjectPaths = allPaths.projectPaths.filter(existsSync);
66
+ const allExistingPaths = allPaths.allPaths.filter(existsSync);
67
+ return {
68
+ userPaths: existingUserPaths,
69
+ projectPaths: existingProjectPaths,
70
+ existingPaths: allExistingPaths,
71
+ };
72
+ }
73
+ /**
74
+ * Get the first existing configuration file path with the specified priority
75
+ * @param paths Array of paths in priority order
76
+ * @returns The first path that exists, or undefined if none exist
77
+ */
78
+ export function getFirstExistingPath(paths) {
79
+ return paths.find((path) => existsSync(path));
80
+ }
81
+ /**
82
+ * Get effective configuration paths (the ones that would actually be used)
83
+ * Returns the highest priority existing path for each category
84
+ */
85
+ export function getEffectiveConfigPaths(workdir) {
86
+ const userPaths = getUserConfigPaths();
87
+ const projectPaths = getProjectConfigPaths(workdir);
88
+ const userPath = getFirstExistingPath(userPaths);
89
+ const projectPath = getFirstExistingPath(projectPaths);
90
+ // Project path takes precedence over user path if both exist
91
+ const effectivePath = projectPath || userPath;
92
+ return {
93
+ userPath,
94
+ projectPath,
95
+ effectivePath,
96
+ };
97
+ }
98
+ /**
99
+ * Check if any configuration files exist
100
+ */
101
+ export function hasAnyConfig(workdir) {
102
+ const { existingPaths } = getExistingConfigPaths(workdir);
103
+ return existingPaths.length > 0;
104
+ }
105
+ /**
106
+ * Get configuration information for debugging and monitoring
107
+ */
108
+ export function getConfigurationInfo(workdir) {
109
+ const allPaths = getAllConfigPaths(workdir);
110
+ const existingPaths = getExistingConfigPaths(workdir);
111
+ const effectivePaths = getEffectiveConfigPaths(workdir);
112
+ return {
113
+ hasUser: existingPaths.userPaths.length > 0,
114
+ hasProject: existingPaths.projectPaths.length > 0,
115
+ paths: allPaths.allPaths,
116
+ userPaths: allPaths.userPaths,
117
+ projectPaths: allPaths.projectPaths,
118
+ existingPaths: existingPaths.existingPaths,
119
+ effectivePaths,
120
+ };
121
+ }
@@ -21,17 +21,5 @@ export declare const USER_MEMORY_FILE: string;
21
21
  /**
22
22
  * AI related constants
23
23
  */
24
- export declare const DEFAULT_TOKEN_LIMIT = 64000;
25
- /**
26
- * @deprecated These constants are now legacy. Use ModelConfig through Agent constructor instead.
27
- * They are maintained for backward compatibility with existing code that might still reference them,
28
- * but the actual AI services now use configuration injection.
29
- */
30
- export declare const FAST_MODEL_ID: string;
31
- /**
32
- * @deprecated These constants are now legacy. Use ModelConfig through Agent constructor instead.
33
- * They are maintained for backward compatibility with existing code that might still reference them,
34
- * but the actual AI services now use configuration injection.
35
- */
36
- export declare const AGENT_MODEL_ID: string;
24
+ export declare const DEFAULT_TOKEN_LIMIT = 96000;
37
25
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAmC,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAA0C,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAA8C,CAAC;AAE5E;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAoD,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAC2B,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAmC,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAA0C,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC"}
@@ -19,20 +19,8 @@ export const ERROR_LOG_DIRECTORY = path.join(DATA_DIRECTORY, "error-logs");
19
19
  /**
20
20
  * User-level memory file path
21
21
  */
22
- export const USER_MEMORY_FILE = path.join(DATA_DIRECTORY, "user-memory.md");
22
+ export const USER_MEMORY_FILE = path.join(DATA_DIRECTORY, "AGENTS.md");
23
23
  /**
24
24
  * AI related constants
25
25
  */
26
- export const DEFAULT_TOKEN_LIMIT = 64000; // Default token limit
27
- /**
28
- * @deprecated These constants are now legacy. Use ModelConfig through Agent constructor instead.
29
- * They are maintained for backward compatibility with existing code that might still reference them,
30
- * but the actual AI services now use configuration injection.
31
- */
32
- export const FAST_MODEL_ID = process.env.AIGW_FAST_MODEL || "gemini-2.5-flash";
33
- /**
34
- * @deprecated These constants are now legacy. Use ModelConfig through Agent constructor instead.
35
- * They are maintained for backward compatibility with existing code that might still reference them,
36
- * but the actual AI services now use configuration injection.
37
- */
38
- export const AGENT_MODEL_ID = process.env.AIGW_MODEL || "claude-sonnet-4-20250514";
26
+ export const DEFAULT_TOKEN_LIMIT = 96000; // Default token limit
@@ -1,7 +1,8 @@
1
1
  import type { Message } from "../types/index.js";
2
2
  import { ChatCompletionMessageParam } from "openai/resources.js";
3
3
  /**
4
- * Convert message format to API call format, stopping when a compressed message is encountered
4
+ * Convert message format to API call format, stopping when a compressed message is encountered.
5
+ * Messages with no meaningful content or tool calls are filtered out.
5
6
  * @param messages Message list
6
7
  * @returns Converted API message format list
7
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"convertMessagesForAPI.d.ts","sourceRoot":"","sources":["../../src/utils/convertMessagesForAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAEL,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAuB7B;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EAAE,GAClB,0BAA0B,EAAE,CA8L9B"}
1
+ {"version":3,"file":"convertMessagesForAPI.d.ts","sourceRoot":"","sources":["../../src/utils/convertMessagesForAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAEL,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAwB7B;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EAAE,GAClB,0BAA0B,EAAE,CAsN9B"}
@@ -1,5 +1,6 @@
1
1
  import { convertImageToBase64 } from "./messageOperations.js";
2
2
  import { stripAnsiColors } from "./stringUtils.js";
3
+ import { logger } from "./globalLogger.js";
3
4
  /**
4
5
  * Safely handle tool call parameters, ensuring a legal JSON string is returned
5
6
  * @param args Tool call parameters
@@ -14,14 +15,15 @@ function safeToolArguments(args) {
14
15
  JSON.parse(args);
15
16
  return args;
16
17
  }
17
- catch {
18
- // logger.error(`Invalid tool arguments: ${args}`);
18
+ catch (error) {
19
+ logger.error(`Invalid tool arguments: ${args}`, error);
19
20
  // If not valid JSON, return a fallback empty object
20
21
  return "{}";
21
22
  }
22
23
  }
23
24
  /**
24
- * Convert message format to API call format, stopping when a compressed message is encountered
25
+ * Convert message format to API call format, stopping when a compressed message is encountered.
26
+ * Messages with no meaningful content or tool calls are filtered out.
25
27
  * @param messages Message list
26
28
  * @returns Converted API message format list
27
29
  */
@@ -43,7 +45,7 @@ export function convertMessagesForAPI(messages) {
43
45
  }
44
46
  break;
45
47
  }
46
- // Skip empty assistant messages
48
+ // Skip empty assistant messages (no blocks or all blocks are empty)
47
49
  if (message.role === "assistant" && message.blocks.length === 0) {
48
50
  continue;
49
51
  }
@@ -54,8 +56,8 @@ export function convertMessagesForAPI(messages) {
54
56
  const completedToolIds = new Set(); // Record completed tool IDs
55
57
  if (toolBlocks.length > 0) {
56
58
  toolBlocks.forEach((toolBlock) => {
57
- // Only add completed tool blocks (i.e., not running)
58
- if (toolBlock.id && !toolBlock.isRunning) {
59
+ // Only add completed tool blocks (i.e., stage is 'end')
60
+ if (toolBlock.id && toolBlock.stage === "end") {
59
61
  completedToolIds.add(toolBlock.id);
60
62
  // Check for image data
61
63
  if (toolBlock.images && toolBlock.images.length > 0) {
@@ -100,10 +102,14 @@ export function convertMessagesForAPI(messages) {
100
102
  // Construct the content of the assistant message
101
103
  let content = "";
102
104
  let tool_calls = undefined;
103
- // Construct content from text blocks
104
- const textBlocks = message.blocks.filter((block) => block.type === "text");
105
+ // Construct content from text blocks - filter out empty content
106
+ const textBlocks = message.blocks.filter((block) => block.type === "text" &&
107
+ block.content &&
108
+ block.content.trim().length > 0);
105
109
  if (textBlocks.length > 0) {
106
- content = textBlocks.map((block) => block.content || "").join("\n");
110
+ content = textBlocks
111
+ .map((block) => (block.type === "text" ? block.content : ""))
112
+ .join("\n");
107
113
  }
108
114
  // Construct tool calls from tool blocks
109
115
  if (toolBlocks.length > 0) {
@@ -121,12 +127,15 @@ export function convertMessagesForAPI(messages) {
121
127
  tool_calls = undefined;
122
128
  }
123
129
  }
124
- // Construct assistant message - only add if there is content or tool calls
125
- if (content || tool_calls) {
130
+ // Construct assistant message - only add if there is meaningful content or tool calls
131
+ const hasContent = content && content.trim().length > 0;
132
+ const hasToolCalls = tool_calls && tool_calls.length > 0;
133
+ if (hasContent || hasToolCalls) {
126
134
  const assistantMessage = {
127
135
  role: "assistant",
128
- content,
136
+ content: hasContent ? content : undefined,
129
137
  tool_calls,
138
+ ...(message.additionalFields ? { ...message.additionalFields } : {}),
130
139
  };
131
140
  recentMessages.unshift(assistantMessage);
132
141
  }
@@ -135,8 +144,10 @@ export function convertMessagesForAPI(messages) {
135
144
  // User messages converted to standard format
136
145
  const contentParts = [];
137
146
  message.blocks.forEach((block) => {
138
- // Add text content
139
- if (block.type === "text" && block.content) {
147
+ // Add text content - only if it has meaningful content
148
+ if (block.type === "text" &&
149
+ block.content &&
150
+ block.content.trim().length > 0) {
140
151
  contentParts.push({
141
152
  type: "text",
142
153
  text: block.customCommandContent || block.content,
@@ -155,7 +166,7 @@ export function convertMessagesForAPI(messages) {
155
166
  finalImageUrl = convertImageToBase64(imageUrl);
156
167
  }
157
168
  catch (error) {
158
- console.error("Failed to convert image path to base64:", imageUrl, error);
169
+ logger.error("Failed to convert image path to base64:", imageUrl, error);
159
170
  // Skip this image, do not add to content
160
171
  return;
161
172
  }
@@ -170,11 +181,21 @@ export function convertMessagesForAPI(messages) {
170
181
  });
171
182
  }
172
183
  });
184
+ // Only add user message if there is meaningful content
173
185
  if (contentParts.length > 0) {
174
- recentMessages.unshift({
175
- role: "user",
176
- content: contentParts,
186
+ // Filter out empty text parts
187
+ const meaningfulParts = contentParts.filter((part) => {
188
+ if (part.type === "text") {
189
+ return part.text && part.text.trim().length > 0;
190
+ }
191
+ return true; // Keep image parts
177
192
  });
193
+ if (meaningfulParts.length > 0) {
194
+ recentMessages.unshift({
195
+ role: "user",
196
+ content: meaningfulParts,
197
+ });
198
+ }
178
199
  }
179
200
  }
180
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"customCommands.d.ts","sourceRoot":"","sources":["../../src/utils/customCommands.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AA6CD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAkB7E"}
1
+ {"version":3,"file":"customCommands.d.ts","sourceRoot":"","sources":["../../src/utils/customCommands.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAU5D;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AA0GD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAkB7E"}