wave-agent-sdk 0.7.1 → 0.8.0

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 (168) hide show
  1. package/dist/agent.d.ts +9 -79
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +85 -302
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -1
  7. package/dist/managers/aiManager.d.ts.map +1 -1
  8. package/dist/managers/aiManager.js +20 -13
  9. package/dist/managers/backgroundTaskManager.d.ts +1 -1
  10. package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
  11. package/dist/managers/backgroundTaskManager.js +1 -1
  12. package/dist/managers/{bashManager.d.ts → bangManager.d.ts} +4 -4
  13. package/dist/managers/{bashManager.d.ts.map → bangManager.d.ts.map} +1 -1
  14. package/dist/managers/{bashManager.js → bangManager.js} +5 -6
  15. package/dist/managers/hookManager.d.ts.map +1 -1
  16. package/dist/managers/hookManager.js +12 -3
  17. package/dist/managers/messageManager.d.ts +18 -6
  18. package/dist/managers/messageManager.d.ts.map +1 -1
  19. package/dist/managers/messageManager.js +42 -20
  20. package/dist/managers/permissionManager.d.ts +22 -1
  21. package/dist/managers/permissionManager.d.ts.map +1 -1
  22. package/dist/managers/permissionManager.js +106 -85
  23. package/dist/managers/planManager.d.ts +6 -0
  24. package/dist/managers/planManager.d.ts.map +1 -1
  25. package/dist/managers/planManager.js +21 -0
  26. package/dist/managers/skillManager.d.ts +7 -2
  27. package/dist/managers/skillManager.d.ts.map +1 -1
  28. package/dist/managers/skillManager.js +30 -10
  29. package/dist/managers/slashCommandManager.d.ts +7 -0
  30. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  31. package/dist/managers/slashCommandManager.js +57 -45
  32. package/dist/managers/subagentManager.d.ts +4 -0
  33. package/dist/managers/subagentManager.d.ts.map +1 -1
  34. package/dist/managers/subagentManager.js +47 -13
  35. package/dist/managers/toolManager.d.ts +7 -1
  36. package/dist/managers/toolManager.d.ts.map +1 -1
  37. package/dist/managers/toolManager.js +15 -2
  38. package/dist/prompts/index.d.ts +0 -4
  39. package/dist/prompts/index.d.ts.map +1 -1
  40. package/dist/prompts/index.js +0 -9
  41. package/dist/services/aiService.d.ts.map +1 -1
  42. package/dist/services/aiService.js +6 -6
  43. package/dist/services/configurationService.d.ts +2 -2
  44. package/dist/services/configurationService.d.ts.map +1 -1
  45. package/dist/services/configurationService.js +4 -4
  46. package/dist/services/hook.d.ts.map +1 -1
  47. package/dist/services/hook.js +6 -0
  48. package/dist/services/initializationService.d.ts +44 -0
  49. package/dist/services/initializationService.d.ts.map +1 -0
  50. package/dist/services/initializationService.js +170 -0
  51. package/dist/services/interactionService.d.ts +29 -0
  52. package/dist/services/interactionService.d.ts.map +1 -0
  53. package/dist/services/interactionService.js +97 -0
  54. package/dist/services/session.js +1 -1
  55. package/dist/services/taskManager.d.ts +5 -0
  56. package/dist/services/taskManager.d.ts.map +1 -1
  57. package/dist/services/taskManager.js +16 -2
  58. package/dist/tools/bashTool.d.ts.map +1 -1
  59. package/dist/tools/bashTool.js +7 -18
  60. package/dist/tools/editTool.js +1 -1
  61. package/dist/tools/exitPlanMode.js +1 -1
  62. package/dist/tools/lspTool.d.ts +2 -0
  63. package/dist/tools/lspTool.d.ts.map +1 -1
  64. package/dist/tools/lspTool.js +144 -52
  65. package/dist/tools/skillTool.d.ts.map +1 -1
  66. package/dist/tools/skillTool.js +97 -2
  67. package/dist/tools/taskManagementTools.d.ts.map +1 -1
  68. package/dist/tools/taskManagementTools.js +23 -2
  69. package/dist/tools/taskTool.d.ts.map +1 -1
  70. package/dist/tools/taskTool.js +9 -15
  71. package/dist/tools/types.d.ts +1 -2
  72. package/dist/tools/types.d.ts.map +1 -1
  73. package/dist/tools/writeTool.js +1 -1
  74. package/dist/types/agent.d.ts +64 -0
  75. package/dist/types/agent.d.ts.map +1 -0
  76. package/dist/types/agent.js +1 -0
  77. package/dist/types/commands.d.ts +0 -4
  78. package/dist/types/commands.d.ts.map +1 -1
  79. package/dist/types/config.d.ts +1 -1
  80. package/dist/types/config.d.ts.map +1 -1
  81. package/dist/types/hooks.d.ts +3 -1
  82. package/dist/types/hooks.d.ts.map +1 -1
  83. package/dist/types/hooks.js +1 -0
  84. package/dist/types/index.d.ts +1 -0
  85. package/dist/types/index.d.ts.map +1 -1
  86. package/dist/types/index.js +1 -0
  87. package/dist/types/messaging.d.ts +3 -3
  88. package/dist/types/messaging.d.ts.map +1 -1
  89. package/dist/types/skills.d.ts +13 -0
  90. package/dist/types/skills.d.ts.map +1 -1
  91. package/dist/utils/commandPathResolver.d.ts +3 -36
  92. package/dist/utils/commandPathResolver.d.ts.map +1 -1
  93. package/dist/utils/commandPathResolver.js +16 -93
  94. package/dist/utils/configValidator.d.ts +2 -2
  95. package/dist/utils/configValidator.d.ts.map +1 -1
  96. package/dist/utils/configValidator.js +4 -6
  97. package/dist/utils/containerSetup.d.ts +3 -4
  98. package/dist/utils/containerSetup.d.ts.map +1 -1
  99. package/dist/utils/containerSetup.js +14 -9
  100. package/dist/utils/customCommands.d.ts +2 -3
  101. package/dist/utils/customCommands.d.ts.map +1 -1
  102. package/dist/utils/customCommands.js +20 -60
  103. package/dist/utils/gitUtils.d.ts +25 -0
  104. package/dist/utils/gitUtils.d.ts.map +1 -1
  105. package/dist/utils/gitUtils.js +75 -0
  106. package/dist/utils/markdownParser.d.ts +4 -0
  107. package/dist/utils/markdownParser.d.ts.map +1 -1
  108. package/dist/utils/markdownParser.js +33 -0
  109. package/dist/utils/messageOperations.d.ts +16 -7
  110. package/dist/utils/messageOperations.d.ts.map +1 -1
  111. package/dist/utils/messageOperations.js +45 -20
  112. package/dist/utils/nameGenerator.d.ts +1 -1
  113. package/dist/utils/nameGenerator.d.ts.map +1 -1
  114. package/dist/utils/nameGenerator.js +10 -6
  115. package/dist/utils/skillParser.d.ts.map +1 -1
  116. package/dist/utils/skillParser.js +48 -0
  117. package/package.json +1 -1
  118. package/src/agent.ts +103 -458
  119. package/src/index.ts +2 -2
  120. package/src/managers/aiManager.ts +23 -17
  121. package/src/managers/backgroundTaskManager.ts +2 -2
  122. package/src/managers/{bashManager.ts → bangManager.ts} +11 -8
  123. package/src/managers/hookManager.ts +13 -3
  124. package/src/managers/messageManager.ts +55 -26
  125. package/src/managers/permissionManager.ts +121 -98
  126. package/src/managers/planManager.ts +26 -0
  127. package/src/managers/skillManager.ts +51 -14
  128. package/src/managers/slashCommandManager.ts +75 -55
  129. package/src/managers/subagentManager.ts +57 -13
  130. package/src/managers/toolManager.ts +22 -2
  131. package/src/prompts/index.ts +0 -15
  132. package/src/services/aiService.ts +9 -12
  133. package/src/services/configurationService.ts +4 -4
  134. package/src/services/hook.ts +7 -0
  135. package/src/services/initializationService.ts +291 -0
  136. package/src/services/interactionService.ts +171 -0
  137. package/src/services/session.ts +1 -1
  138. package/src/services/taskManager.ts +18 -2
  139. package/src/tools/bashTool.ts +8 -18
  140. package/src/tools/editTool.ts +1 -1
  141. package/src/tools/exitPlanMode.ts +1 -1
  142. package/src/tools/lsTool.ts +1 -1
  143. package/src/tools/lspTool.ts +184 -52
  144. package/src/tools/skillTool.ts +127 -2
  145. package/src/tools/taskManagementTools.ts +32 -2
  146. package/src/tools/taskTool.ts +13 -15
  147. package/src/tools/types.ts +1 -2
  148. package/src/tools/writeTool.ts +1 -1
  149. package/src/types/agent.ts +83 -0
  150. package/src/types/commands.ts +0 -6
  151. package/src/types/config.ts +1 -1
  152. package/src/types/hooks.ts +5 -1
  153. package/src/types/index.ts +1 -0
  154. package/src/types/messaging.ts +3 -3
  155. package/src/types/skills.ts +13 -0
  156. package/src/utils/commandPathResolver.ts +14 -117
  157. package/src/utils/configValidator.ts +5 -9
  158. package/src/utils/containerSetup.ts +17 -14
  159. package/src/utils/customCommands.ts +20 -83
  160. package/src/utils/gitUtils.ts +75 -0
  161. package/src/utils/markdownParser.ts +47 -0
  162. package/src/utils/messageOperations.ts +58 -28
  163. package/src/utils/nameGenerator.ts +10 -6
  164. package/src/utils/skillParser.ts +52 -0
  165. package/dist/managers/backgroundBashManager.d.ts +0 -27
  166. package/dist/managers/backgroundBashManager.d.ts.map +0 -1
  167. package/dist/managers/backgroundBashManager.js +0 -169
  168. package/src/managers/backgroundBashManager.ts +0 -206
@@ -2,6 +2,8 @@ import { relative } from "path";
2
2
  import { logger } from "../utils/globalLogger.js";
3
3
  import { getDisplayPath } from "../utils/path.js";
4
4
  import { LSP_TOOL_NAME } from "../constants/tools.js";
5
+ export const MAX_RESULTS = 1000;
6
+ export const MAX_FILES = 100;
5
7
  /**
6
8
  * Formats an LSP URI into a readable file path
7
9
  */
@@ -94,10 +96,15 @@ function formatGoToDefinitionResult(result, workdir) {
94
96
  if (validLocations.length === 1) {
95
97
  return `Defined in ${formatLocation(validLocations[0], workdir)}`;
96
98
  }
97
- const formatted = validLocations
99
+ const shownLocations = validLocations.slice(0, MAX_RESULTS);
100
+ const formatted = shownLocations
98
101
  .map((loc) => ` ${formatLocation(loc, workdir)}`)
99
102
  .join("\n");
100
- return `Found ${validLocations.length} definitions:\n${formatted}`;
103
+ let header = `Found ${validLocations.length} definitions:`;
104
+ if (validLocations.length > MAX_RESULTS) {
105
+ header += ` (showing first ${MAX_RESULTS})`;
106
+ }
107
+ return `${header}\n${formatted}`;
101
108
  }
102
109
  const loc = isLocationLink(result) ? locationLinkToLocation(result) : result;
103
110
  return `Defined in ${formatLocation(loc, workdir)}`;
@@ -117,17 +124,34 @@ function formatFindReferencesResult(result, workdir) {
117
124
  return `Found 1 reference:\n ${formatLocation(validLocations[0], workdir)}`;
118
125
  }
119
126
  const grouped = groupItemsByUri(validLocations, workdir);
120
- const lines = [
121
- `Found ${validLocations.length} references across ${grouped.size} files:`,
122
- ];
127
+ const totalResults = validLocations.length;
128
+ const totalFiles = grouped.size;
129
+ let resultsShown = 0;
130
+ let filesShown = 0;
131
+ const lines = [];
123
132
  for (const [path, locs] of grouped) {
133
+ if (resultsShown >= MAX_RESULTS || filesShown >= MAX_FILES)
134
+ break;
135
+ filesShown++;
136
+ const remainingResults = MAX_RESULTS - resultsShown;
137
+ const locsToShow = locs.slice(0, remainingResults);
138
+ const isTruncated = locsToShow.length < locs.length;
124
139
  lines.push(`\n${path}:`);
125
- for (const loc of locs) {
140
+ for (const loc of locsToShow) {
126
141
  const line = loc.range.start.line + 1;
127
142
  const character = loc.range.start.character + 1;
128
143
  lines.push(` Line ${line}:${character}`);
129
144
  }
145
+ if (isTruncated) {
146
+ lines.push(` ... and ${locs.length - locsToShow.length} more in this file`);
147
+ }
148
+ resultsShown += locsToShow.length;
130
149
  }
150
+ let header = `Found ${totalResults} references across ${totalFiles} files:`;
151
+ if (totalResults > resultsShown || totalFiles > filesShown) {
152
+ header += ` (showing first ${resultsShown} results and ${filesShown} files)`;
153
+ }
154
+ lines.unshift(header);
131
155
  return lines.join("\n");
132
156
  }
133
157
  /**
@@ -196,20 +220,24 @@ function getSymbolKindName(kind) {
196
220
  /**
197
221
  * Formats a single document symbol recursively
198
222
  */
199
- function formatDocumentSymbol(symbol, depth = 0) {
223
+ function formatDocumentSymbol(symbol, state, depth = 0) {
224
+ state.total++;
200
225
  const results = [];
201
- const indent = " ".repeat(depth);
202
- const kindName = getSymbolKindName(symbol.kind);
203
- let line = `${indent}${symbol.name} (${kindName})`;
204
- if (symbol.detail) {
205
- line += ` ${symbol.detail}`;
206
- }
207
- const startLine = symbol.range.start.line + 1;
208
- line += ` - Line ${startLine}`;
209
- results.push(line);
226
+ if (state.count < MAX_RESULTS) {
227
+ const indent = " ".repeat(depth);
228
+ const kindName = getSymbolKindName(symbol.kind);
229
+ let line = `${indent}${symbol.name} (${kindName})`;
230
+ if (symbol.detail) {
231
+ line += ` ${symbol.detail}`;
232
+ }
233
+ const startLine = symbol.range.start.line + 1;
234
+ line += ` - Line ${startLine}`;
235
+ results.push(line);
236
+ state.count++;
237
+ }
210
238
  if (symbol.children && symbol.children.length > 0) {
211
239
  for (const child of symbol.children) {
212
- results.push(...formatDocumentSymbol(child, depth + 1));
240
+ results.push(...formatDocumentSymbol(child, state, depth + 1));
213
241
  }
214
242
  }
215
243
  return results;
@@ -225,10 +253,16 @@ function formatDocumentSymbolResult(result, workdir) {
225
253
  if (first && "location" in first) {
226
254
  return formatWorkspaceSymbolResult(result, workdir);
227
255
  }
228
- const lines = ["Document symbols:"];
256
+ const state = { count: 0, total: 0 };
257
+ const lines = [];
229
258
  for (const symbol of result) {
230
- lines.push(...formatDocumentSymbol(symbol));
259
+ lines.push(...formatDocumentSymbol(symbol, state));
260
+ }
261
+ let header = "Document symbols:";
262
+ if (state.total > MAX_RESULTS) {
263
+ header += ` (showing first ${MAX_RESULTS} of ${state.total})`;
231
264
  }
265
+ lines.unshift(header);
232
266
  return lines.join("\n");
233
267
  }
234
268
  /**
@@ -242,13 +276,21 @@ function formatWorkspaceSymbolResult(result, workdir) {
242
276
  if (validSymbols.length === 0) {
243
277
  return "No symbols found in workspace. This may occur if the workspace is empty, or if the LSP server has not finished indexing the project.";
244
278
  }
245
- const lines = [
246
- `Found ${validSymbols.length} symbol${validSymbols.length === 1 ? "" : "s"} in workspace:`,
247
- ];
248
279
  const grouped = groupItemsByUri(validSymbols, workdir);
280
+ const totalResults = validSymbols.length;
281
+ const totalFiles = grouped.size;
282
+ let resultsShown = 0;
283
+ let filesShown = 0;
284
+ const lines = [];
249
285
  for (const [path, symbols] of grouped) {
286
+ if (resultsShown >= MAX_RESULTS || filesShown >= MAX_FILES)
287
+ break;
288
+ filesShown++;
289
+ const remainingResults = MAX_RESULTS - resultsShown;
290
+ const symbolsToShow = symbols.slice(0, remainingResults);
291
+ const isTruncated = symbolsToShow.length < symbols.length;
250
292
  lines.push(`\n${path}:`);
251
- for (const s of symbols) {
293
+ for (const s of symbolsToShow) {
252
294
  const kindName = getSymbolKindName(s.kind);
253
295
  const startLine = s.location.range.start.line + 1;
254
296
  let line = ` ${s.name} (${kindName}) - Line ${startLine}`;
@@ -257,7 +299,16 @@ function formatWorkspaceSymbolResult(result, workdir) {
257
299
  }
258
300
  lines.push(line);
259
301
  }
302
+ if (isTruncated) {
303
+ lines.push(` ... and ${symbols.length - symbolsToShow.length} more in this file`);
304
+ }
305
+ resultsShown += symbolsToShow.length;
260
306
  }
307
+ let header = `Found ${totalResults} symbol${totalResults === 1 ? "" : "s"} in workspace:`;
308
+ if (totalResults > resultsShown || totalFiles > filesShown) {
309
+ header += ` (showing first ${resultsShown} results and ${filesShown} files)`;
310
+ }
311
+ lines.unshift(header);
261
312
  return lines.join("\n");
262
313
  }
263
314
  /**
@@ -287,10 +338,16 @@ function formatPrepareCallHierarchyResult(result, workdir) {
287
338
  if (result.length === 1) {
288
339
  return `Call hierarchy item: ${formatCallHierarchyItem(result[0], workdir)}`;
289
340
  }
290
- const lines = [`Found ${result.length} call hierarchy items:`];
291
- for (const item of result) {
341
+ const shownItems = result.slice(0, MAX_RESULTS);
342
+ const lines = [];
343
+ for (const item of shownItems) {
292
344
  lines.push(` ${formatCallHierarchyItem(item, workdir)}`);
293
345
  }
346
+ let header = `Found ${result.length} call hierarchy items:`;
347
+ if (result.length > MAX_RESULTS) {
348
+ header += ` (showing first ${MAX_RESULTS})`;
349
+ }
350
+ lines.unshift(header);
294
351
  return lines.join("\n");
295
352
  }
296
353
  /**
@@ -300,10 +357,8 @@ function formatIncomingCallsResult(result, workdir) {
300
357
  if (!result || result.length === 0) {
301
358
  return "No incoming calls found (nothing calls this function)";
302
359
  }
303
- const lines = [
304
- `Found ${result.length} incoming call${result.length === 1 ? "" : "s"}:`,
305
- ];
306
360
  const grouped = new Map();
361
+ const totalResults = result.length;
307
362
  for (const call of result) {
308
363
  if (!call.from) {
309
364
  logger.warn("formatIncomingCallsResult: CallHierarchyIncomingCall has undefined from field");
@@ -318,9 +373,19 @@ function formatIncomingCallsResult(result, workdir) {
318
373
  grouped.set(path, [call]);
319
374
  }
320
375
  }
376
+ const totalFiles = grouped.size;
377
+ let resultsShown = 0;
378
+ let filesShown = 0;
379
+ const lines = [];
321
380
  for (const [path, calls] of grouped) {
381
+ if (resultsShown >= MAX_RESULTS || filesShown >= MAX_FILES)
382
+ break;
383
+ filesShown++;
384
+ const remainingResults = MAX_RESULTS - resultsShown;
385
+ const callsToShow = calls.slice(0, remainingResults);
386
+ const isTruncated = callsToShow.length < calls.length;
322
387
  lines.push(`\n${path}:`);
323
- for (const call of calls) {
388
+ for (const call of callsToShow) {
324
389
  if (!call.from)
325
390
  continue;
326
391
  const kindName = getSymbolKindName(call.from.kind);
@@ -334,7 +399,16 @@ function formatIncomingCallsResult(result, workdir) {
334
399
  }
335
400
  lines.push(line);
336
401
  }
402
+ if (isTruncated) {
403
+ lines.push(` ... and ${calls.length - callsToShow.length} more in this file`);
404
+ }
405
+ resultsShown += callsToShow.length;
337
406
  }
407
+ let header = `Found ${totalResults} incoming call${totalResults === 1 ? "" : "s"}:`;
408
+ if (totalResults > resultsShown || totalFiles > filesShown) {
409
+ header += ` (showing first ${resultsShown} results and ${filesShown} files)`;
410
+ }
411
+ lines.unshift(header);
338
412
  return lines.join("\n");
339
413
  }
340
414
  /**
@@ -344,10 +418,8 @@ function formatOutgoingCallsResult(result, workdir) {
344
418
  if (!result || result.length === 0) {
345
419
  return "No outgoing calls found (this function calls nothing)";
346
420
  }
347
- const lines = [
348
- `Found ${result.length} outgoing call${result.length === 1 ? "" : "s"}:`,
349
- ];
350
421
  const grouped = new Map();
422
+ const totalResults = result.length;
351
423
  for (const call of result) {
352
424
  if (!call.to) {
353
425
  logger.warn("formatOutgoingCallsResult: CallHierarchyOutgoingCall has undefined to field");
@@ -362,9 +434,19 @@ function formatOutgoingCallsResult(result, workdir) {
362
434
  grouped.set(path, [call]);
363
435
  }
364
436
  }
437
+ const totalFiles = grouped.size;
438
+ let resultsShown = 0;
439
+ let filesShown = 0;
440
+ const lines = [];
365
441
  for (const [path, calls] of grouped) {
442
+ if (resultsShown >= MAX_RESULTS || filesShown >= MAX_FILES)
443
+ break;
444
+ filesShown++;
445
+ const remainingResults = MAX_RESULTS - resultsShown;
446
+ const callsToShow = calls.slice(0, remainingResults);
447
+ const isTruncated = callsToShow.length < calls.length;
366
448
  lines.push(`\n${path}:`);
367
- for (const call of calls) {
449
+ for (const call of callsToShow) {
368
450
  if (!call.to)
369
451
  continue;
370
452
  const kindName = getSymbolKindName(call.to.kind);
@@ -378,7 +460,16 @@ function formatOutgoingCallsResult(result, workdir) {
378
460
  }
379
461
  lines.push(line);
380
462
  }
463
+ if (isTruncated) {
464
+ lines.push(` ... and ${calls.length - callsToShow.length} more in this file`);
465
+ }
466
+ resultsShown += callsToShow.length;
467
+ }
468
+ let header = `Found ${totalResults} outgoing call${totalResults === 1 ? "" : "s"}:`;
469
+ if (totalResults > resultsShown || totalFiles > filesShown) {
470
+ header += ` (showing first ${resultsShown} results and ${filesShown} files)`;
381
471
  }
472
+ lines.unshift(header);
382
473
  return lines.join("\n");
383
474
  }
384
475
  /**
@@ -390,25 +481,7 @@ export const lspTool = {
390
481
  type: "function",
391
482
  function: {
392
483
  name: LSP_TOOL_NAME,
393
- description: `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
394
-
395
- Supported operations:
396
- - goToDefinition: Find where a symbol is defined
397
- - findReferences: Find all references to a symbol
398
- - hover: Get hover information (documentation, type info) for a symbol
399
- - documentSymbol: Get all symbols (functions, classes, variables) in a document
400
- - workspaceSymbol: Search for symbols across the entire workspace
401
- - goToImplementation: Find implementations of an interface or abstract method
402
- - prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)
403
- - incomingCalls: Find all functions/methods that call the function at a position
404
- - outgoingCalls: Find all functions/methods called by the function at a position
405
-
406
- All operations require:
407
- - filePath: The file to operate on
408
- - line: The line number (1-based, as shown in editors)
409
- - character: The character offset (1-based, as shown in editors)
410
-
411
- Note: LSP servers must be configured for the file type. If no server is available, an error will be returned.`,
484
+ description: `Interact with Language Server Protocol (LSP) servers to get code intelligence features.`,
412
485
  parameters: {
413
486
  type: "object",
414
487
  properties: {
@@ -444,6 +517,25 @@ Note: LSP servers must be configured for the file type. If no server is availabl
444
517
  },
445
518
  },
446
519
  },
520
+ prompt: () => `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
521
+
522
+ Supported operations:
523
+ - goToDefinition: Find where a symbol is defined
524
+ - findReferences: Find all references to a symbol
525
+ - hover: Get hover information (documentation, type info) for a symbol
526
+ - documentSymbol: Get all symbols (functions, classes, variables) in a document
527
+ - workspaceSymbol: Search for symbols across the entire workspace
528
+ - goToImplementation: Find implementations of an interface or abstract method
529
+ - prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)
530
+ - incomingCalls: Find all functions/methods that call the function at a position
531
+ - outgoingCalls: Find all functions/methods called by the function at a position
532
+
533
+ All operations require:
534
+ - filePath: The file to operate on
535
+ - line: The line number (1-based, as shown in editors)
536
+ - character: The character offset (1-based, as shown in editors)
537
+
538
+ Note: LSP servers must be configured for the file type. If no server is available, an error will be returned.`,
447
539
  execute: async (args, context) => {
448
540
  const { operation, filePath, line, character } = args;
449
541
  if (!context.lspManager) {
@@ -1 +1 @@
1
- {"version":3,"file":"skillTool.d.ts","sourceRoot":"","sources":["../../src/tools/skillTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAItE;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,UAmFvB,CAAC"}
1
+ {"version":3,"file":"skillTool.d.ts","sourceRoot":"","sources":["../../src/tools/skillTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAUtE;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,UA0MvB,CAAC"}
@@ -1,4 +1,7 @@
1
1
  import { SKILL_TOOL_NAME } from "../constants/tools.js";
2
+ import { GENERAL_PURPOSE_SUBAGENT_TYPE } from "../constants/subagents.js";
3
+ import { logger } from "../utils/globalLogger.js";
4
+ import { countToolBlocks, formatToolTokenSummary, } from "../utils/messageOperations.js";
2
5
  /**
3
6
  * Skill tool plugin for invoking Wave skills
4
7
  */
@@ -16,13 +19,17 @@ export const skillTool = {
16
19
  type: "string",
17
20
  description: "Name of the skill to invoke",
18
21
  },
22
+ args: {
23
+ type: "string",
24
+ description: "Optional arguments to pass to the skill",
25
+ },
19
26
  },
20
27
  required: ["skill_name"],
21
28
  },
22
29
  },
23
30
  },
24
31
  prompt: (args) => {
25
- const availableSkills = args?.availableSkills;
32
+ const availableSkills = args?.availableSkills?.filter((skill) => !skill.disableModelInvocation);
26
33
  if (!availableSkills || availableSkills.length === 0) {
27
34
  return "Invoke a Wave skill by name. Skills are user-defined automation templates that can be personal or project-specific. No skills are currently available.";
28
35
  }
@@ -43,6 +50,7 @@ export const skillTool = {
43
50
  }
44
51
  // Validate arguments
45
52
  const skillName = args.skill_name;
53
+ const skillArgs = args.args;
46
54
  if (!skillName || typeof skillName !== "string") {
47
55
  return {
48
56
  success: false,
@@ -50,10 +58,97 @@ export const skillTool = {
50
58
  error: "skill_name parameter is required and must be a string",
51
59
  };
52
60
  }
53
- // Execute the skill
61
+ const skillMetadata = skillManager.getSkillMetadata(skillName);
62
+ if (skillMetadata?.disableModelInvocation) {
63
+ return {
64
+ success: false,
65
+ content: "",
66
+ error: `Skill "${skillName}" is not available for model invocation.`,
67
+ };
68
+ }
69
+ // Handle fork context
70
+ if (skillMetadata?.context === "fork") {
71
+ const subagentManager = context.subagentManager;
72
+ if (!subagentManager) {
73
+ return {
74
+ success: false,
75
+ content: "",
76
+ error: "Subagent manager not available in tool context",
77
+ };
78
+ }
79
+ const agentType = skillMetadata.agent || GENERAL_PURPOSE_SUBAGENT_TYPE;
80
+ const configuration = await subagentManager.findSubagent(agentType);
81
+ if (!configuration) {
82
+ return {
83
+ success: false,
84
+ content: "",
85
+ error: `No subagent found matching "${agentType}" for skill "${skillName}"`,
86
+ };
87
+ }
88
+ // Execute the skill to get the content
89
+ const skillResult = await skillManager.executeSkill({
90
+ skill_name: skillName,
91
+ args: skillArgs,
92
+ });
93
+ logger.debug(`Skill ${skillName} executed, allowedTools:`, {
94
+ allowedTools: skillResult.allowedTools,
95
+ });
96
+ // Create subagent instance
97
+ const instance = await subagentManager.createInstance(configuration, {
98
+ description: `Skill: ${skillName}`,
99
+ prompt: skillResult.content,
100
+ subagent_type: agentType,
101
+ allowedTools: skillResult.allowedTools,
102
+ model: skillMetadata.model,
103
+ }, false, // run_in_background
104
+ () => {
105
+ // Update shortResult
106
+ const messages = instance.messageManager.getMessages();
107
+ const tokens = instance.messageManager.getlatestTotalTokens();
108
+ const lastTools = instance.lastTools;
109
+ const toolCount = countToolBlocks(messages);
110
+ const summary = formatToolTokenSummary(toolCount, tokens);
111
+ let shortResult = "";
112
+ if (toolCount > 2) {
113
+ shortResult += "... ";
114
+ }
115
+ if (lastTools.length > 0) {
116
+ shortResult += `${lastTools.join(", ")} `;
117
+ }
118
+ shortResult += summary;
119
+ context.onShortResultUpdate?.(shortResult);
120
+ });
121
+ try {
122
+ const result = await subagentManager.executeTask(instance, skillResult.content, context.abortSignal, false);
123
+ // Cleanup subagent instance after task completion
124
+ subagentManager.cleanupInstance(instance.subagentId);
125
+ const messages = instance.messageManager.getMessages();
126
+ const tokens = instance.messageManager.getlatestTotalTokens();
127
+ const toolCount = countToolBlocks(messages);
128
+ const summary = formatToolTokenSummary(toolCount, tokens);
129
+ return {
130
+ success: true,
131
+ content: result,
132
+ shortResult: `Invoked skill: ${skillName}${summary ? ` ${summary}` : ""}`,
133
+ };
134
+ }
135
+ catch (error) {
136
+ return {
137
+ success: false,
138
+ content: "",
139
+ error: `Skill fork failed: ${error instanceof Error ? error.message : String(error)}`,
140
+ };
141
+ }
142
+ }
143
+ // Standard execution
54
144
  const result = await skillManager.executeSkill({
55
145
  skill_name: skillName,
146
+ args: skillArgs,
56
147
  });
148
+ // Add temporary rules if allowedTools are present
149
+ if (result.allowedTools && result.allowedTools.length > 0) {
150
+ context.permissionManager?.addTemporaryRules(result.allowedTools);
151
+ }
57
152
  return {
58
153
  success: true,
59
154
  content: result.content,
@@ -1 +1 @@
1
- {"version":3,"file":"taskManagementTools.d.ts","sourceRoot":"","sources":["../../src/tools/taskManagementTools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AASjE,eAAO,MAAM,cAAc,EAAE,UA0H5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAyDzB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,UA+P5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,UAkE1B,CAAC"}
1
+ {"version":3,"file":"taskManagementTools.d.ts","sourceRoot":"","sources":["../../src/tools/taskManagementTools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AASjE,eAAO,MAAM,cAAc,EAAE,UA2H5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAyDzB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,UA4R5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,UAkE1B,CAAC"}
@@ -104,7 +104,8 @@ NOTE that you should not use this tool if there is only one trivial task to do.
104
104
  const taskId = await taskManager.createTask(task);
105
105
  if (context.reversionManager && context.messageId) {
106
106
  const taskPath = taskManager.getTaskPath(taskId);
107
- await context.reversionManager.recordSnapshot(context.messageId, taskPath, "create");
107
+ const snapshotId = await context.reversionManager.recordSnapshot(context.messageId, taskPath, "create");
108
+ await context.reversionManager.commitSnapshot(snapshotId);
108
109
  }
109
110
  return {
110
111
  success: true,
@@ -308,9 +309,10 @@ Set up task dependencies:
308
309
  content: `Task with ID ${taskId} not found.`,
309
310
  };
310
311
  }
312
+ let snapshotId;
311
313
  if (context.reversionManager && context.messageId) {
312
314
  const taskPath = taskManager.getTaskPath(taskId);
313
- await context.reversionManager.recordSnapshot(context.messageId, taskPath, "modify");
315
+ snapshotId = await context.reversionManager.recordSnapshot(context.messageId, taskPath, "modify");
314
316
  }
315
317
  const updatedFields = [];
316
318
  const updatedTask = {
@@ -360,10 +362,18 @@ Set up task dependencies:
360
362
  for (const targetId of blocksToAdd) {
361
363
  const targetTask = await taskManager.getTask(targetId);
362
364
  if (targetTask && !targetTask.blockedBy.includes(taskId)) {
365
+ let targetSnapshotId;
366
+ if (context.reversionManager && context.messageId) {
367
+ const targetPath = taskManager.getTaskPath(targetId);
368
+ targetSnapshotId = await context.reversionManager.recordSnapshot(context.messageId, targetPath, "modify");
369
+ }
363
370
  await taskManager.updateTask({
364
371
  ...targetTask,
365
372
  blockedBy: [...targetTask.blockedBy, taskId],
366
373
  });
374
+ if (context.reversionManager && targetSnapshotId) {
375
+ await context.reversionManager.commitSnapshot(targetSnapshotId);
376
+ }
367
377
  }
368
378
  }
369
379
  }
@@ -377,15 +387,26 @@ Set up task dependencies:
377
387
  for (const targetId of blockedByToAdd) {
378
388
  const targetTask = await taskManager.getTask(targetId);
379
389
  if (targetTask && !targetTask.blocks.includes(taskId)) {
390
+ let targetSnapshotId;
391
+ if (context.reversionManager && context.messageId) {
392
+ const targetPath = taskManager.getTaskPath(targetId);
393
+ targetSnapshotId = await context.reversionManager.recordSnapshot(context.messageId, targetPath, "modify");
394
+ }
380
395
  await taskManager.updateTask({
381
396
  ...targetTask,
382
397
  blocks: [...targetTask.blocks, taskId],
383
398
  });
399
+ if (context.reversionManager && targetSnapshotId) {
400
+ await context.reversionManager.commitSnapshot(targetSnapshotId);
401
+ }
384
402
  }
385
403
  }
386
404
  }
387
405
  }
388
406
  await taskManager.updateTask(updatedTask);
407
+ if (context.reversionManager && snapshotId) {
408
+ await context.reversionManager.commitSnapshot(snapshotId);
409
+ }
389
410
  let content = `Updated task #${taskId} ${updatedFields.join(", ")}`;
390
411
  if (updatedTask.status === "completed") {
391
412
  content += `\n\nTask completed. Call TaskList now to find your next available task or see if your work unblocked others.`;
@@ -1 +1 @@
1
- {"version":3,"file":"taskTool.d.ts","sourceRoot":"","sources":["../../src/tools/taskTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAKtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA2OtB,CAAC"}
1
+ {"version":3,"file":"taskTool.d.ts","sourceRoot":"","sources":["../../src/tools/taskTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAStE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAqOtB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { EXPLORE_SUBAGENT_TYPE } from "../constants/subagents.js";
2
2
  import { TASK_TOOL_NAME } from "../constants/tools.js";
3
+ import { countToolBlocks, formatToolTokenSummary, } from "../utils/messageOperations.js";
3
4
  /**
4
5
  * Task tool plugin for delegating tasks to specialized subagents
5
6
  */
@@ -116,15 +117,8 @@ ${subagentList || "No subagents configured"}
116
117
  const messages = instance.messageManager.getMessages();
117
118
  const tokens = instance.messageManager.getlatestTotalTokens();
118
119
  const lastTools = instance.lastTools;
119
- // Count tool blocks in messages
120
- let toolCount = 0;
121
- messages.forEach((msg) => {
122
- msg.blocks.forEach((block) => {
123
- if (block.type === "tool") {
124
- toolCount++;
125
- }
126
- });
127
- });
120
+ const toolCount = countToolBlocks(messages);
121
+ const summary = formatToolTokenSummary(toolCount, tokens);
128
122
  let shortResult = "";
129
123
  if (toolCount > 2) {
130
124
  shortResult += "... ";
@@ -132,11 +126,7 @@ ${subagentList || "No subagents configured"}
132
126
  if (lastTools.length > 0) {
133
127
  shortResult += `${lastTools.join(", ")} `;
134
128
  }
135
- shortResult += `(${toolCount} tools`;
136
- if (tokens > 0) {
137
- shortResult += ` | ${tokens.toLocaleString()} tokens`;
138
- }
139
- shortResult += ")";
129
+ shortResult += summary;
140
130
  context.onShortResultUpdate?.(shortResult);
141
131
  });
142
132
  // Register for backgrounding if not already in background
@@ -174,10 +164,14 @@ ${subagentList || "No subagents configured"}
174
164
  }
175
165
  // Cleanup subagent instance after task completion
176
166
  subagentManager.cleanupInstance(instance.subagentId);
167
+ const messages = instance.messageManager.getMessages();
168
+ const tokens = instance.messageManager.getlatestTotalTokens();
169
+ const toolCount = countToolBlocks(messages);
170
+ const summary = formatToolTokenSummary(toolCount, tokens);
177
171
  return {
178
172
  success: true,
179
173
  content: result,
180
- shortResult: `Task completed by ${configuration.name}`,
174
+ shortResult: `Task completed${summary ? ` ${summary}` : ""}`,
181
175
  };
182
176
  }
183
177
  finally {
@@ -11,7 +11,7 @@ export interface ToolPlugin {
11
11
  execute: (args: Record<string, unknown>, context: ToolContext) => Promise<ToolResult>;
12
12
  formatCompactParams?: (params: Record<string, unknown>, context: ToolContext) => string;
13
13
  /**
14
- * Optional function to provide a prompt to be added to the system prompt
14
+ * Function to provide a prompt to be added to the tool description
15
15
  */
16
16
  prompt?: (args?: {
17
17
  availableSubagents?: SubagentConfiguration[];
@@ -34,7 +34,6 @@ export interface ToolResult {
34
34
  }
35
35
  export interface ToolContext {
36
36
  abortSignal?: AbortSignal;
37
- backgroundBashManager?: import("../managers/backgroundBashManager.js").BackgroundBashManager;
38
37
  backgroundTaskManager?: import("../managers/backgroundTaskManager.js").BackgroundTaskManager;
39
38
  workdir: string;
40
39
  /** Permission mode for this tool execution */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,0BAA0B,CAAC;IACnC,OAAO,EAAE,CACP,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,WAAW,KACjB,OAAO,CAAC,UAAU,CAAC,CAAC;IACzB,mBAAmB,CAAC,EAAE,CACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,WAAW,KACjB,MAAM,CAAC;IACZ;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;QACf,kBAAkB,CAAC,EAAE,qBAAqB,EAAE,CAAC;QAC7C,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,KAAK,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IAEH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,sCAAsC,EAAE,qBAAqB,CAAC;IAC7F,qBAAqB,CAAC,EAAE,OAAO,sCAAsC,EAAE,qBAAqB,CAAC;IAC7F,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iCAAiC;IACjC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,kCAAkC,EAAE,iBAAiB,CAAC;IACjF,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,2BAA2B,EAAE,UAAU,CAAC;IAC5D,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,iBAAiB,EAAE,WAAW,CAAC;IACnD,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,OAAO,iCAAiC,EAAE,gBAAgB,CAAC;IAC9E,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,qBAAqB,CAAC,EAAE,OAAO,uBAAuB,EAAE,sBAAsB,CAAC;IAC/E,gDAAgD;IAChD,WAAW,EAAE,OAAO,4BAA4B,EAAE,WAAW,CAAC;IAC9D,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,gCAAgC,EAAE,eAAe,CAAC;IAC3E,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,6BAA6B,EAAE,YAAY,CAAC;IAClE,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,0BAA0B,CAAC;IACnC,OAAO,EAAE,CACP,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,WAAW,KACjB,OAAO,CAAC,UAAU,CAAC,CAAC;IACzB,mBAAmB,CAAC,EAAE,CACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,WAAW,KACjB,MAAM,CAAC;IACZ;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;QACf,kBAAkB,CAAC,EAAE,qBAAqB,EAAE,CAAC;QAC7C,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,KAAK,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IAEH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,sCAAsC,EAAE,qBAAqB,CAAC;IAC7F,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iCAAiC;IACjC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,kCAAkC,EAAE,iBAAiB,CAAC;IACjF,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,2BAA2B,EAAE,UAAU,CAAC;IAC5D,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,iBAAiB,EAAE,WAAW,CAAC;IACnD,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,OAAO,iCAAiC,EAAE,gBAAgB,CAAC;IAC9E,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,qBAAqB,CAAC,EAAE,OAAO,uBAAuB,EAAE,sBAAsB,CAAC;IAC/E,gDAAgD;IAChD,WAAW,EAAE,OAAO,4BAA4B,EAAE,WAAW,CAAC;IAC9D,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,gCAAgC,EAAE,eAAe,CAAC;IAC3E,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,6BAA6B,EAAE,YAAY,CAAC;IAClE,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD"}
@@ -100,7 +100,7 @@ Usage:
100
100
  return {
101
101
  success: false,
102
102
  content: "",
103
- error: `Write operation denied, reason: ${permissionResult.message || "No reason provided"}`,
103
+ error: `Write operation denied by user, reason: ${permissionResult.message || "No reason provided"}`,
104
104
  };
105
105
  }
106
106
  }