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.
- package/dist/agent.d.ts +9 -79
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +85 -302
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +20 -13
- package/dist/managers/backgroundTaskManager.d.ts +1 -1
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +1 -1
- package/dist/managers/{bashManager.d.ts → bangManager.d.ts} +4 -4
- package/dist/managers/{bashManager.d.ts.map → bangManager.d.ts.map} +1 -1
- package/dist/managers/{bashManager.js → bangManager.js} +5 -6
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +12 -3
- package/dist/managers/messageManager.d.ts +18 -6
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +42 -20
- package/dist/managers/permissionManager.d.ts +22 -1
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +106 -85
- package/dist/managers/planManager.d.ts +6 -0
- package/dist/managers/planManager.d.ts.map +1 -1
- package/dist/managers/planManager.js +21 -0
- package/dist/managers/skillManager.d.ts +7 -2
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +30 -10
- package/dist/managers/slashCommandManager.d.ts +7 -0
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +57 -45
- package/dist/managers/subagentManager.d.ts +4 -0
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +47 -13
- package/dist/managers/toolManager.d.ts +7 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +15 -2
- package/dist/prompts/index.d.ts +0 -4
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +0 -9
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +6 -6
- package/dist/services/configurationService.d.ts +2 -2
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +4 -4
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +6 -0
- package/dist/services/initializationService.d.ts +44 -0
- package/dist/services/initializationService.d.ts.map +1 -0
- package/dist/services/initializationService.js +170 -0
- package/dist/services/interactionService.d.ts +29 -0
- package/dist/services/interactionService.d.ts.map +1 -0
- package/dist/services/interactionService.js +97 -0
- package/dist/services/session.js +1 -1
- package/dist/services/taskManager.d.ts +5 -0
- package/dist/services/taskManager.d.ts.map +1 -1
- package/dist/services/taskManager.js +16 -2
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +7 -18
- package/dist/tools/editTool.js +1 -1
- package/dist/tools/exitPlanMode.js +1 -1
- package/dist/tools/lspTool.d.ts +2 -0
- package/dist/tools/lspTool.d.ts.map +1 -1
- package/dist/tools/lspTool.js +144 -52
- package/dist/tools/skillTool.d.ts.map +1 -1
- package/dist/tools/skillTool.js +97 -2
- package/dist/tools/taskManagementTools.d.ts.map +1 -1
- package/dist/tools/taskManagementTools.js +23 -2
- package/dist/tools/taskTool.d.ts.map +1 -1
- package/dist/tools/taskTool.js +9 -15
- package/dist/tools/types.d.ts +1 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.js +1 -1
- package/dist/types/agent.d.ts +64 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +1 -0
- package/dist/types/commands.d.ts +0 -4
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/config.d.ts +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +3 -1
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/messaging.d.ts +3 -3
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/skills.d.ts +13 -0
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/utils/commandPathResolver.d.ts +3 -36
- package/dist/utils/commandPathResolver.d.ts.map +1 -1
- package/dist/utils/commandPathResolver.js +16 -93
- package/dist/utils/configValidator.d.ts +2 -2
- package/dist/utils/configValidator.d.ts.map +1 -1
- package/dist/utils/configValidator.js +4 -6
- package/dist/utils/containerSetup.d.ts +3 -4
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +14 -9
- package/dist/utils/customCommands.d.ts +2 -3
- package/dist/utils/customCommands.d.ts.map +1 -1
- package/dist/utils/customCommands.js +20 -60
- package/dist/utils/gitUtils.d.ts +25 -0
- package/dist/utils/gitUtils.d.ts.map +1 -1
- package/dist/utils/gitUtils.js +75 -0
- package/dist/utils/markdownParser.d.ts +4 -0
- package/dist/utils/markdownParser.d.ts.map +1 -1
- package/dist/utils/markdownParser.js +33 -0
- package/dist/utils/messageOperations.d.ts +16 -7
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +45 -20
- package/dist/utils/nameGenerator.d.ts +1 -1
- package/dist/utils/nameGenerator.d.ts.map +1 -1
- package/dist/utils/nameGenerator.js +10 -6
- package/dist/utils/skillParser.d.ts.map +1 -1
- package/dist/utils/skillParser.js +48 -0
- package/package.json +1 -1
- package/src/agent.ts +103 -458
- package/src/index.ts +2 -2
- package/src/managers/aiManager.ts +23 -17
- package/src/managers/backgroundTaskManager.ts +2 -2
- package/src/managers/{bashManager.ts → bangManager.ts} +11 -8
- package/src/managers/hookManager.ts +13 -3
- package/src/managers/messageManager.ts +55 -26
- package/src/managers/permissionManager.ts +121 -98
- package/src/managers/planManager.ts +26 -0
- package/src/managers/skillManager.ts +51 -14
- package/src/managers/slashCommandManager.ts +75 -55
- package/src/managers/subagentManager.ts +57 -13
- package/src/managers/toolManager.ts +22 -2
- package/src/prompts/index.ts +0 -15
- package/src/services/aiService.ts +9 -12
- package/src/services/configurationService.ts +4 -4
- package/src/services/hook.ts +7 -0
- package/src/services/initializationService.ts +291 -0
- package/src/services/interactionService.ts +171 -0
- package/src/services/session.ts +1 -1
- package/src/services/taskManager.ts +18 -2
- package/src/tools/bashTool.ts +8 -18
- package/src/tools/editTool.ts +1 -1
- package/src/tools/exitPlanMode.ts +1 -1
- package/src/tools/lsTool.ts +1 -1
- package/src/tools/lspTool.ts +184 -52
- package/src/tools/skillTool.ts +127 -2
- package/src/tools/taskManagementTools.ts +32 -2
- package/src/tools/taskTool.ts +13 -15
- package/src/tools/types.ts +1 -2
- package/src/tools/writeTool.ts +1 -1
- package/src/types/agent.ts +83 -0
- package/src/types/commands.ts +0 -6
- package/src/types/config.ts +1 -1
- package/src/types/hooks.ts +5 -1
- package/src/types/index.ts +1 -0
- package/src/types/messaging.ts +3 -3
- package/src/types/skills.ts +13 -0
- package/src/utils/commandPathResolver.ts +14 -117
- package/src/utils/configValidator.ts +5 -9
- package/src/utils/containerSetup.ts +17 -14
- package/src/utils/customCommands.ts +20 -83
- package/src/utils/gitUtils.ts +75 -0
- package/src/utils/markdownParser.ts +47 -0
- package/src/utils/messageOperations.ts +58 -28
- package/src/utils/nameGenerator.ts +10 -6
- package/src/utils/skillParser.ts +52 -0
- package/dist/managers/backgroundBashManager.d.ts +0 -27
- package/dist/managers/backgroundBashManager.d.ts.map +0 -1
- package/dist/managers/backgroundBashManager.js +0 -169
- package/src/managers/backgroundBashManager.ts +0 -206
package/src/tools/lspTool.ts
CHANGED
|
@@ -14,6 +14,9 @@ import type {
|
|
|
14
14
|
LspCallHierarchyOutgoingCall as CallHierarchyOutgoingCall,
|
|
15
15
|
} from "../types/lsp.js";
|
|
16
16
|
|
|
17
|
+
export const MAX_RESULTS = 1000;
|
|
18
|
+
export const MAX_FILES = 100;
|
|
19
|
+
|
|
17
20
|
/**
|
|
18
21
|
* Formats an LSP URI into a readable file path
|
|
19
22
|
*/
|
|
@@ -126,10 +129,16 @@ function formatGoToDefinitionResult(
|
|
|
126
129
|
return `Defined in ${formatLocation(validLocations[0], workdir)}`;
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
const
|
|
132
|
+
const shownLocations = validLocations.slice(0, MAX_RESULTS);
|
|
133
|
+
const formatted = shownLocations
|
|
130
134
|
.map((loc) => ` ${formatLocation(loc, workdir)}`)
|
|
131
135
|
.join("\n");
|
|
132
|
-
|
|
136
|
+
|
|
137
|
+
let header = `Found ${validLocations.length} definitions:`;
|
|
138
|
+
if (validLocations.length > MAX_RESULTS) {
|
|
139
|
+
header += ` (showing first ${MAX_RESULTS})`;
|
|
140
|
+
}
|
|
141
|
+
return `${header}\n${formatted}`;
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
const loc = isLocationLink(result) ? locationLinkToLocation(result) : result;
|
|
@@ -157,18 +166,42 @@ function formatFindReferencesResult(
|
|
|
157
166
|
}
|
|
158
167
|
|
|
159
168
|
const grouped = groupItemsByUri(validLocations, workdir);
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
const totalResults = validLocations.length;
|
|
170
|
+
const totalFiles = grouped.size;
|
|
171
|
+
|
|
172
|
+
let resultsShown = 0;
|
|
173
|
+
let filesShown = 0;
|
|
174
|
+
const lines: string[] = [];
|
|
163
175
|
|
|
164
176
|
for (const [path, locs] of grouped) {
|
|
177
|
+
if (resultsShown >= MAX_RESULTS || filesShown >= MAX_FILES) break;
|
|
178
|
+
|
|
179
|
+
filesShown++;
|
|
180
|
+
const remainingResults = MAX_RESULTS - resultsShown;
|
|
181
|
+
const locsToShow = locs.slice(0, remainingResults);
|
|
182
|
+
const isTruncated = locsToShow.length < locs.length;
|
|
183
|
+
|
|
165
184
|
lines.push(`\n${path}:`);
|
|
166
|
-
for (const loc of
|
|
185
|
+
for (const loc of locsToShow) {
|
|
167
186
|
const line = loc.range.start.line + 1;
|
|
168
187
|
const character = loc.range.start.character + 1;
|
|
169
188
|
lines.push(` Line ${line}:${character}`);
|
|
170
189
|
}
|
|
190
|
+
|
|
191
|
+
if (isTruncated) {
|
|
192
|
+
lines.push(
|
|
193
|
+
` ... and ${locs.length - locsToShow.length} more in this file`,
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
resultsShown += locsToShow.length;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
let header = `Found ${totalResults} references across ${totalFiles} files:`;
|
|
201
|
+
if (totalResults > resultsShown || totalFiles > filesShown) {
|
|
202
|
+
header += ` (showing first ${resultsShown} results and ${filesShown} files)`;
|
|
171
203
|
}
|
|
204
|
+
lines.unshift(header);
|
|
172
205
|
|
|
173
206
|
return lines.join("\n");
|
|
174
207
|
}
|
|
@@ -243,23 +276,32 @@ function getSymbolKindName(kind: number): string {
|
|
|
243
276
|
/**
|
|
244
277
|
* Formats a single document symbol recursively
|
|
245
278
|
*/
|
|
246
|
-
function formatDocumentSymbol(
|
|
279
|
+
function formatDocumentSymbol(
|
|
280
|
+
symbol: DocumentSymbol,
|
|
281
|
+
state: { count: number; total: number },
|
|
282
|
+
depth = 0,
|
|
283
|
+
): string[] {
|
|
284
|
+
state.total++;
|
|
247
285
|
const results: string[] = [];
|
|
248
|
-
const indent = " ".repeat(depth);
|
|
249
|
-
const kindName = getSymbolKindName(symbol.kind);
|
|
250
|
-
let line = `${indent}${symbol.name} (${kindName})`;
|
|
251
286
|
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
|
|
287
|
+
if (state.count < MAX_RESULTS) {
|
|
288
|
+
const indent = " ".repeat(depth);
|
|
289
|
+
const kindName = getSymbolKindName(symbol.kind);
|
|
290
|
+
let line = `${indent}${symbol.name} (${kindName})`;
|
|
291
|
+
|
|
292
|
+
if (symbol.detail) {
|
|
293
|
+
line += ` ${symbol.detail}`;
|
|
294
|
+
}
|
|
255
295
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
296
|
+
const startLine = symbol.range.start.line + 1;
|
|
297
|
+
line += ` - Line ${startLine}`;
|
|
298
|
+
results.push(line);
|
|
299
|
+
state.count++;
|
|
300
|
+
}
|
|
259
301
|
|
|
260
302
|
if (symbol.children && symbol.children.length > 0) {
|
|
261
303
|
for (const child of symbol.children) {
|
|
262
|
-
results.push(...formatDocumentSymbol(child, depth + 1));
|
|
304
|
+
results.push(...formatDocumentSymbol(child, state, depth + 1));
|
|
263
305
|
}
|
|
264
306
|
}
|
|
265
307
|
|
|
@@ -282,10 +324,18 @@ function formatDocumentSymbolResult(
|
|
|
282
324
|
return formatWorkspaceSymbolResult(result as SymbolInformation[], workdir);
|
|
283
325
|
}
|
|
284
326
|
|
|
285
|
-
const
|
|
327
|
+
const state = { count: 0, total: 0 };
|
|
328
|
+
const lines: string[] = [];
|
|
286
329
|
for (const symbol of result as DocumentSymbol[]) {
|
|
287
|
-
lines.push(...formatDocumentSymbol(symbol));
|
|
330
|
+
lines.push(...formatDocumentSymbol(symbol, state));
|
|
288
331
|
}
|
|
332
|
+
|
|
333
|
+
let header = "Document symbols:";
|
|
334
|
+
if (state.total > MAX_RESULTS) {
|
|
335
|
+
header += ` (showing first ${MAX_RESULTS} of ${state.total})`;
|
|
336
|
+
}
|
|
337
|
+
lines.unshift(header);
|
|
338
|
+
|
|
289
339
|
return lines.join("\n");
|
|
290
340
|
}
|
|
291
341
|
|
|
@@ -305,14 +355,24 @@ function formatWorkspaceSymbolResult(
|
|
|
305
355
|
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.";
|
|
306
356
|
}
|
|
307
357
|
|
|
308
|
-
const lines = [
|
|
309
|
-
`Found ${validSymbols.length} symbol${validSymbols.length === 1 ? "" : "s"} in workspace:`,
|
|
310
|
-
];
|
|
311
358
|
const grouped = groupItemsByUri(validSymbols, workdir);
|
|
359
|
+
const totalResults = validSymbols.length;
|
|
360
|
+
const totalFiles = grouped.size;
|
|
361
|
+
|
|
362
|
+
let resultsShown = 0;
|
|
363
|
+
let filesShown = 0;
|
|
364
|
+
const lines: string[] = [];
|
|
312
365
|
|
|
313
366
|
for (const [path, symbols] of grouped) {
|
|
367
|
+
if (resultsShown >= MAX_RESULTS || filesShown >= MAX_FILES) break;
|
|
368
|
+
|
|
369
|
+
filesShown++;
|
|
370
|
+
const remainingResults = MAX_RESULTS - resultsShown;
|
|
371
|
+
const symbolsToShow = symbols.slice(0, remainingResults);
|
|
372
|
+
const isTruncated = symbolsToShow.length < symbols.length;
|
|
373
|
+
|
|
314
374
|
lines.push(`\n${path}:`);
|
|
315
|
-
for (const s of
|
|
375
|
+
for (const s of symbolsToShow) {
|
|
316
376
|
const kindName = getSymbolKindName(s.kind);
|
|
317
377
|
const startLine = s.location.range.start.line + 1;
|
|
318
378
|
let line = ` ${s.name} (${kindName}) - Line ${startLine}`;
|
|
@@ -321,7 +381,21 @@ function formatWorkspaceSymbolResult(
|
|
|
321
381
|
}
|
|
322
382
|
lines.push(line);
|
|
323
383
|
}
|
|
384
|
+
|
|
385
|
+
if (isTruncated) {
|
|
386
|
+
lines.push(
|
|
387
|
+
` ... and ${symbols.length - symbolsToShow.length} more in this file`,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
resultsShown += symbolsToShow.length;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
let header = `Found ${totalResults} symbol${totalResults === 1 ? "" : "s"} in workspace:`;
|
|
395
|
+
if (totalResults > resultsShown || totalFiles > filesShown) {
|
|
396
|
+
header += ` (showing first ${resultsShown} results and ${filesShown} files)`;
|
|
324
397
|
}
|
|
398
|
+
lines.unshift(header);
|
|
325
399
|
|
|
326
400
|
return lines.join("\n");
|
|
327
401
|
}
|
|
@@ -364,10 +438,18 @@ function formatPrepareCallHierarchyResult(
|
|
|
364
438
|
return `Call hierarchy item: ${formatCallHierarchyItem(result[0], workdir)}`;
|
|
365
439
|
}
|
|
366
440
|
|
|
367
|
-
const
|
|
368
|
-
|
|
441
|
+
const shownItems = result.slice(0, MAX_RESULTS);
|
|
442
|
+
const lines: string[] = [];
|
|
443
|
+
for (const item of shownItems) {
|
|
369
444
|
lines.push(` ${formatCallHierarchyItem(item, workdir)}`);
|
|
370
445
|
}
|
|
446
|
+
|
|
447
|
+
let header = `Found ${result.length} call hierarchy items:`;
|
|
448
|
+
if (result.length > MAX_RESULTS) {
|
|
449
|
+
header += ` (showing first ${MAX_RESULTS})`;
|
|
450
|
+
}
|
|
451
|
+
lines.unshift(header);
|
|
452
|
+
|
|
371
453
|
return lines.join("\n");
|
|
372
454
|
}
|
|
373
455
|
|
|
@@ -382,10 +464,8 @@ function formatIncomingCallsResult(
|
|
|
382
464
|
return "No incoming calls found (nothing calls this function)";
|
|
383
465
|
}
|
|
384
466
|
|
|
385
|
-
const lines = [
|
|
386
|
-
`Found ${result.length} incoming call${result.length === 1 ? "" : "s"}:`,
|
|
387
|
-
];
|
|
388
467
|
const grouped = new Map<string, CallHierarchyIncomingCall[]>();
|
|
468
|
+
const totalResults = result.length;
|
|
389
469
|
|
|
390
470
|
for (const call of result) {
|
|
391
471
|
if (!call.from) {
|
|
@@ -403,9 +483,21 @@ function formatIncomingCallsResult(
|
|
|
403
483
|
}
|
|
404
484
|
}
|
|
405
485
|
|
|
486
|
+
const totalFiles = grouped.size;
|
|
487
|
+
let resultsShown = 0;
|
|
488
|
+
let filesShown = 0;
|
|
489
|
+
const lines: string[] = [];
|
|
490
|
+
|
|
406
491
|
for (const [path, calls] of grouped) {
|
|
492
|
+
if (resultsShown >= MAX_RESULTS || filesShown >= MAX_FILES) break;
|
|
493
|
+
|
|
494
|
+
filesShown++;
|
|
495
|
+
const remainingResults = MAX_RESULTS - resultsShown;
|
|
496
|
+
const callsToShow = calls.slice(0, remainingResults);
|
|
497
|
+
const isTruncated = callsToShow.length < calls.length;
|
|
498
|
+
|
|
407
499
|
lines.push(`\n${path}:`);
|
|
408
|
-
for (const call of
|
|
500
|
+
for (const call of callsToShow) {
|
|
409
501
|
if (!call.from) continue;
|
|
410
502
|
const kindName = getSymbolKindName(call.from.kind);
|
|
411
503
|
const startLine = call.from.range.start.line + 1;
|
|
@@ -419,8 +511,22 @@ function formatIncomingCallsResult(
|
|
|
419
511
|
}
|
|
420
512
|
lines.push(line);
|
|
421
513
|
}
|
|
514
|
+
|
|
515
|
+
if (isTruncated) {
|
|
516
|
+
lines.push(
|
|
517
|
+
` ... and ${calls.length - callsToShow.length} more in this file`,
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
resultsShown += callsToShow.length;
|
|
422
522
|
}
|
|
423
523
|
|
|
524
|
+
let header = `Found ${totalResults} incoming call${totalResults === 1 ? "" : "s"}:`;
|
|
525
|
+
if (totalResults > resultsShown || totalFiles > filesShown) {
|
|
526
|
+
header += ` (showing first ${resultsShown} results and ${filesShown} files)`;
|
|
527
|
+
}
|
|
528
|
+
lines.unshift(header);
|
|
529
|
+
|
|
424
530
|
return lines.join("\n");
|
|
425
531
|
}
|
|
426
532
|
|
|
@@ -435,10 +541,8 @@ function formatOutgoingCallsResult(
|
|
|
435
541
|
return "No outgoing calls found (this function calls nothing)";
|
|
436
542
|
}
|
|
437
543
|
|
|
438
|
-
const lines = [
|
|
439
|
-
`Found ${result.length} outgoing call${result.length === 1 ? "" : "s"}:`,
|
|
440
|
-
];
|
|
441
544
|
const grouped = new Map<string, CallHierarchyOutgoingCall[]>();
|
|
545
|
+
const totalResults = result.length;
|
|
442
546
|
|
|
443
547
|
for (const call of result) {
|
|
444
548
|
if (!call.to) {
|
|
@@ -456,9 +560,21 @@ function formatOutgoingCallsResult(
|
|
|
456
560
|
}
|
|
457
561
|
}
|
|
458
562
|
|
|
563
|
+
const totalFiles = grouped.size;
|
|
564
|
+
let resultsShown = 0;
|
|
565
|
+
let filesShown = 0;
|
|
566
|
+
const lines: string[] = [];
|
|
567
|
+
|
|
459
568
|
for (const [path, calls] of grouped) {
|
|
569
|
+
if (resultsShown >= MAX_RESULTS || filesShown >= MAX_FILES) break;
|
|
570
|
+
|
|
571
|
+
filesShown++;
|
|
572
|
+
const remainingResults = MAX_RESULTS - resultsShown;
|
|
573
|
+
const callsToShow = calls.slice(0, remainingResults);
|
|
574
|
+
const isTruncated = callsToShow.length < calls.length;
|
|
575
|
+
|
|
460
576
|
lines.push(`\n${path}:`);
|
|
461
|
-
for (const call of
|
|
577
|
+
for (const call of callsToShow) {
|
|
462
578
|
if (!call.to) continue;
|
|
463
579
|
const kindName = getSymbolKindName(call.to.kind);
|
|
464
580
|
const startLine = call.to.range.start.line + 1;
|
|
@@ -472,7 +588,21 @@ function formatOutgoingCallsResult(
|
|
|
472
588
|
}
|
|
473
589
|
lines.push(line);
|
|
474
590
|
}
|
|
591
|
+
|
|
592
|
+
if (isTruncated) {
|
|
593
|
+
lines.push(
|
|
594
|
+
` ... and ${calls.length - callsToShow.length} more in this file`,
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
resultsShown += callsToShow.length;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
let header = `Found ${totalResults} outgoing call${totalResults === 1 ? "" : "s"}:`;
|
|
602
|
+
if (totalResults > resultsShown || totalFiles > filesShown) {
|
|
603
|
+
header += ` (showing first ${resultsShown} results and ${filesShown} files)`;
|
|
475
604
|
}
|
|
605
|
+
lines.unshift(header);
|
|
476
606
|
|
|
477
607
|
return lines.join("\n");
|
|
478
608
|
}
|
|
@@ -486,25 +616,7 @@ export const lspTool: ToolPlugin = {
|
|
|
486
616
|
type: "function",
|
|
487
617
|
function: {
|
|
488
618
|
name: LSP_TOOL_NAME,
|
|
489
|
-
description: `Interact with Language Server Protocol (LSP) servers to get code intelligence features
|
|
490
|
-
|
|
491
|
-
Supported operations:
|
|
492
|
-
- goToDefinition: Find where a symbol is defined
|
|
493
|
-
- findReferences: Find all references to a symbol
|
|
494
|
-
- hover: Get hover information (documentation, type info) for a symbol
|
|
495
|
-
- documentSymbol: Get all symbols (functions, classes, variables) in a document
|
|
496
|
-
- workspaceSymbol: Search for symbols across the entire workspace
|
|
497
|
-
- goToImplementation: Find implementations of an interface or abstract method
|
|
498
|
-
- prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)
|
|
499
|
-
- incomingCalls: Find all functions/methods that call the function at a position
|
|
500
|
-
- outgoingCalls: Find all functions/methods called by the function at a position
|
|
501
|
-
|
|
502
|
-
All operations require:
|
|
503
|
-
- filePath: The file to operate on
|
|
504
|
-
- line: The line number (1-based, as shown in editors)
|
|
505
|
-
- character: The character offset (1-based, as shown in editors)
|
|
506
|
-
|
|
507
|
-
Note: LSP servers must be configured for the file type. If no server is available, an error will be returned.`,
|
|
619
|
+
description: `Interact with Language Server Protocol (LSP) servers to get code intelligence features.`,
|
|
508
620
|
parameters: {
|
|
509
621
|
type: "object",
|
|
510
622
|
properties: {
|
|
@@ -540,6 +652,26 @@ Note: LSP servers must be configured for the file type. If no server is availabl
|
|
|
540
652
|
},
|
|
541
653
|
},
|
|
542
654
|
},
|
|
655
|
+
prompt:
|
|
656
|
+
() => `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
|
|
657
|
+
|
|
658
|
+
Supported operations:
|
|
659
|
+
- goToDefinition: Find where a symbol is defined
|
|
660
|
+
- findReferences: Find all references to a symbol
|
|
661
|
+
- hover: Get hover information (documentation, type info) for a symbol
|
|
662
|
+
- documentSymbol: Get all symbols (functions, classes, variables) in a document
|
|
663
|
+
- workspaceSymbol: Search for symbols across the entire workspace
|
|
664
|
+
- goToImplementation: Find implementations of an interface or abstract method
|
|
665
|
+
- prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)
|
|
666
|
+
- incomingCalls: Find all functions/methods that call the function at a position
|
|
667
|
+
- outgoingCalls: Find all functions/methods called by the function at a position
|
|
668
|
+
|
|
669
|
+
All operations require:
|
|
670
|
+
- filePath: The file to operate on
|
|
671
|
+
- line: The line number (1-based, as shown in editors)
|
|
672
|
+
- character: The character offset (1-based, as shown in editors)
|
|
673
|
+
|
|
674
|
+
Note: LSP servers must be configured for the file type. If no server is available, an error will be returned.`,
|
|
543
675
|
execute: async (
|
|
544
676
|
args: Record<string, unknown>,
|
|
545
677
|
context: ToolContext,
|
package/src/tools/skillTool.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
|
|
2
2
|
import { SKILL_TOOL_NAME } from "../constants/tools.js";
|
|
3
|
+
import { GENERAL_PURPOSE_SUBAGENT_TYPE } from "../constants/subagents.js";
|
|
3
4
|
import type { SkillMetadata } from "../types/skills.js";
|
|
5
|
+
import { logger } from "../utils/globalLogger.js";
|
|
6
|
+
import {
|
|
7
|
+
countToolBlocks,
|
|
8
|
+
formatToolTokenSummary,
|
|
9
|
+
} from "../utils/messageOperations.js";
|
|
4
10
|
|
|
5
11
|
/**
|
|
6
12
|
* Skill tool plugin for invoking Wave skills
|
|
@@ -20,6 +26,10 @@ export const skillTool: ToolPlugin = {
|
|
|
20
26
|
type: "string",
|
|
21
27
|
description: "Name of the skill to invoke",
|
|
22
28
|
},
|
|
29
|
+
args: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Optional arguments to pass to the skill",
|
|
32
|
+
},
|
|
23
33
|
},
|
|
24
34
|
required: ["skill_name"],
|
|
25
35
|
},
|
|
@@ -27,7 +37,9 @@ export const skillTool: ToolPlugin = {
|
|
|
27
37
|
},
|
|
28
38
|
|
|
29
39
|
prompt: (args?: { availableSkills?: SkillMetadata[] }) => {
|
|
30
|
-
const availableSkills = args?.availableSkills
|
|
40
|
+
const availableSkills = args?.availableSkills?.filter(
|
|
41
|
+
(skill) => !skill.disableModelInvocation,
|
|
42
|
+
);
|
|
31
43
|
if (!availableSkills || availableSkills.length === 0) {
|
|
32
44
|
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.";
|
|
33
45
|
}
|
|
@@ -57,6 +69,8 @@ export const skillTool: ToolPlugin = {
|
|
|
57
69
|
|
|
58
70
|
// Validate arguments
|
|
59
71
|
const skillName = args.skill_name as string;
|
|
72
|
+
const skillArgs = args.args as string | undefined;
|
|
73
|
+
|
|
60
74
|
if (!skillName || typeof skillName !== "string") {
|
|
61
75
|
return {
|
|
62
76
|
success: false,
|
|
@@ -65,11 +79,122 @@ export const skillTool: ToolPlugin = {
|
|
|
65
79
|
};
|
|
66
80
|
}
|
|
67
81
|
|
|
68
|
-
|
|
82
|
+
const skillMetadata = skillManager.getSkillMetadata(skillName);
|
|
83
|
+
|
|
84
|
+
if (skillMetadata?.disableModelInvocation) {
|
|
85
|
+
return {
|
|
86
|
+
success: false,
|
|
87
|
+
content: "",
|
|
88
|
+
error: `Skill "${skillName}" is not available for model invocation.`,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Handle fork context
|
|
93
|
+
if (skillMetadata?.context === "fork") {
|
|
94
|
+
const subagentManager = context.subagentManager;
|
|
95
|
+
if (!subagentManager) {
|
|
96
|
+
return {
|
|
97
|
+
success: false,
|
|
98
|
+
content: "",
|
|
99
|
+
error: "Subagent manager not available in tool context",
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const agentType = skillMetadata.agent || GENERAL_PURPOSE_SUBAGENT_TYPE;
|
|
104
|
+
const configuration = await subagentManager.findSubagent(agentType);
|
|
105
|
+
|
|
106
|
+
if (!configuration) {
|
|
107
|
+
return {
|
|
108
|
+
success: false,
|
|
109
|
+
content: "",
|
|
110
|
+
error: `No subagent found matching "${agentType}" for skill "${skillName}"`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Execute the skill to get the content
|
|
115
|
+
const skillResult = await skillManager.executeSkill({
|
|
116
|
+
skill_name: skillName,
|
|
117
|
+
args: skillArgs,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
logger.debug(`Skill ${skillName} executed, allowedTools:`, {
|
|
121
|
+
allowedTools: skillResult.allowedTools,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Create subagent instance
|
|
125
|
+
const instance = await subagentManager.createInstance(
|
|
126
|
+
configuration,
|
|
127
|
+
{
|
|
128
|
+
description: `Skill: ${skillName}`,
|
|
129
|
+
prompt: skillResult.content,
|
|
130
|
+
subagent_type: agentType,
|
|
131
|
+
allowedTools: skillResult.allowedTools,
|
|
132
|
+
model: skillMetadata.model,
|
|
133
|
+
},
|
|
134
|
+
false, // run_in_background
|
|
135
|
+
() => {
|
|
136
|
+
// Update shortResult
|
|
137
|
+
const messages = instance.messageManager.getMessages();
|
|
138
|
+
const tokens = instance.messageManager.getlatestTotalTokens();
|
|
139
|
+
const lastTools = instance.lastTools;
|
|
140
|
+
|
|
141
|
+
const toolCount = countToolBlocks(messages);
|
|
142
|
+
const summary = formatToolTokenSummary(toolCount, tokens);
|
|
143
|
+
|
|
144
|
+
let shortResult = "";
|
|
145
|
+
if (toolCount > 2) {
|
|
146
|
+
shortResult += "... ";
|
|
147
|
+
}
|
|
148
|
+
if (lastTools.length > 0) {
|
|
149
|
+
shortResult += `${lastTools.join(", ")} `;
|
|
150
|
+
}
|
|
151
|
+
shortResult += summary;
|
|
152
|
+
|
|
153
|
+
context.onShortResultUpdate?.(shortResult);
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
const result = await subagentManager.executeTask(
|
|
159
|
+
instance,
|
|
160
|
+
skillResult.content,
|
|
161
|
+
context.abortSignal,
|
|
162
|
+
false,
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
// Cleanup subagent instance after task completion
|
|
166
|
+
subagentManager.cleanupInstance(instance.subagentId);
|
|
167
|
+
|
|
168
|
+
const messages = instance.messageManager.getMessages();
|
|
169
|
+
const tokens = instance.messageManager.getlatestTotalTokens();
|
|
170
|
+
const toolCount = countToolBlocks(messages);
|
|
171
|
+
const summary = formatToolTokenSummary(toolCount, tokens);
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
success: true,
|
|
175
|
+
content: result,
|
|
176
|
+
shortResult: `Invoked skill: ${skillName}${summary ? ` ${summary}` : ""}`,
|
|
177
|
+
};
|
|
178
|
+
} catch (error) {
|
|
179
|
+
return {
|
|
180
|
+
success: false,
|
|
181
|
+
content: "",
|
|
182
|
+
error: `Skill fork failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Standard execution
|
|
69
188
|
const result = await skillManager.executeSkill({
|
|
70
189
|
skill_name: skillName,
|
|
190
|
+
args: skillArgs,
|
|
71
191
|
});
|
|
72
192
|
|
|
193
|
+
// Add temporary rules if allowedTools are present
|
|
194
|
+
if (result.allowedTools && result.allowedTools.length > 0) {
|
|
195
|
+
context.permissionManager?.addTemporaryRules(result.allowedTools);
|
|
196
|
+
}
|
|
197
|
+
|
|
73
198
|
return {
|
|
74
199
|
success: true,
|
|
75
200
|
content: result.content,
|
|
@@ -116,11 +116,12 @@ NOTE that you should not use this tool if there is only one trivial task to do.
|
|
|
116
116
|
|
|
117
117
|
if (context.reversionManager && context.messageId) {
|
|
118
118
|
const taskPath = taskManager.getTaskPath(taskId);
|
|
119
|
-
await context.reversionManager.recordSnapshot(
|
|
119
|
+
const snapshotId = await context.reversionManager.recordSnapshot(
|
|
120
120
|
context.messageId,
|
|
121
121
|
taskPath,
|
|
122
122
|
"create",
|
|
123
123
|
);
|
|
124
|
+
await context.reversionManager.commitSnapshot(snapshotId);
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
return {
|
|
@@ -333,9 +334,10 @@ Set up task dependencies:
|
|
|
333
334
|
};
|
|
334
335
|
}
|
|
335
336
|
|
|
337
|
+
let snapshotId: string | undefined;
|
|
336
338
|
if (context.reversionManager && context.messageId) {
|
|
337
339
|
const taskPath = taskManager.getTaskPath(taskId);
|
|
338
|
-
await context.reversionManager.recordSnapshot(
|
|
340
|
+
snapshotId = await context.reversionManager.recordSnapshot(
|
|
339
341
|
context.messageId,
|
|
340
342
|
taskPath,
|
|
341
343
|
"modify",
|
|
@@ -402,10 +404,22 @@ Set up task dependencies:
|
|
|
402
404
|
for (const targetId of blocksToAdd) {
|
|
403
405
|
const targetTask = await taskManager.getTask(targetId);
|
|
404
406
|
if (targetTask && !targetTask.blockedBy.includes(taskId)) {
|
|
407
|
+
let targetSnapshotId: string | undefined;
|
|
408
|
+
if (context.reversionManager && context.messageId) {
|
|
409
|
+
const targetPath = taskManager.getTaskPath(targetId);
|
|
410
|
+
targetSnapshotId = await context.reversionManager.recordSnapshot(
|
|
411
|
+
context.messageId,
|
|
412
|
+
targetPath,
|
|
413
|
+
"modify",
|
|
414
|
+
);
|
|
415
|
+
}
|
|
405
416
|
await taskManager.updateTask({
|
|
406
417
|
...targetTask,
|
|
407
418
|
blockedBy: [...targetTask.blockedBy, taskId],
|
|
408
419
|
});
|
|
420
|
+
if (context.reversionManager && targetSnapshotId) {
|
|
421
|
+
await context.reversionManager.commitSnapshot(targetSnapshotId);
|
|
422
|
+
}
|
|
409
423
|
}
|
|
410
424
|
}
|
|
411
425
|
}
|
|
@@ -423,10 +437,22 @@ Set up task dependencies:
|
|
|
423
437
|
for (const targetId of blockedByToAdd) {
|
|
424
438
|
const targetTask = await taskManager.getTask(targetId);
|
|
425
439
|
if (targetTask && !targetTask.blocks.includes(taskId)) {
|
|
440
|
+
let targetSnapshotId: string | undefined;
|
|
441
|
+
if (context.reversionManager && context.messageId) {
|
|
442
|
+
const targetPath = taskManager.getTaskPath(targetId);
|
|
443
|
+
targetSnapshotId = await context.reversionManager.recordSnapshot(
|
|
444
|
+
context.messageId,
|
|
445
|
+
targetPath,
|
|
446
|
+
"modify",
|
|
447
|
+
);
|
|
448
|
+
}
|
|
426
449
|
await taskManager.updateTask({
|
|
427
450
|
...targetTask,
|
|
428
451
|
blocks: [...targetTask.blocks, taskId],
|
|
429
452
|
});
|
|
453
|
+
if (context.reversionManager && targetSnapshotId) {
|
|
454
|
+
await context.reversionManager.commitSnapshot(targetSnapshotId);
|
|
455
|
+
}
|
|
430
456
|
}
|
|
431
457
|
}
|
|
432
458
|
}
|
|
@@ -434,6 +460,10 @@ Set up task dependencies:
|
|
|
434
460
|
|
|
435
461
|
await taskManager.updateTask(updatedTask);
|
|
436
462
|
|
|
463
|
+
if (context.reversionManager && snapshotId) {
|
|
464
|
+
await context.reversionManager.commitSnapshot(snapshotId);
|
|
465
|
+
}
|
|
466
|
+
|
|
437
467
|
let content = `Updated task #${taskId} ${updatedFields.join(", ")}`;
|
|
438
468
|
if (updatedTask.status === "completed") {
|
|
439
469
|
content += `\n\nTask completed. Call TaskList now to find your next available task or see if your work unblocked others.`;
|
package/src/tools/taskTool.ts
CHANGED
|
@@ -2,6 +2,10 @@ import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
|
|
|
2
2
|
import { EXPLORE_SUBAGENT_TYPE } from "../constants/subagents.js";
|
|
3
3
|
import { TASK_TOOL_NAME } from "../constants/tools.js";
|
|
4
4
|
import type { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
5
|
+
import {
|
|
6
|
+
countToolBlocks,
|
|
7
|
+
formatToolTokenSummary,
|
|
8
|
+
} from "../utils/messageOperations.js";
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* Task tool plugin for delegating tasks to specialized subagents
|
|
@@ -141,15 +145,8 @@ ${subagentList || "No subagents configured"}
|
|
|
141
145
|
const tokens = instance.messageManager.getlatestTotalTokens();
|
|
142
146
|
const lastTools = instance.lastTools;
|
|
143
147
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
messages.forEach((msg) => {
|
|
147
|
-
msg.blocks.forEach((block) => {
|
|
148
|
-
if (block.type === "tool") {
|
|
149
|
-
toolCount++;
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
});
|
|
148
|
+
const toolCount = countToolBlocks(messages);
|
|
149
|
+
const summary = formatToolTokenSummary(toolCount, tokens);
|
|
153
150
|
|
|
154
151
|
let shortResult = "";
|
|
155
152
|
if (toolCount > 2) {
|
|
@@ -159,11 +156,7 @@ ${subagentList || "No subagents configured"}
|
|
|
159
156
|
shortResult += `${lastTools.join(", ")} `;
|
|
160
157
|
}
|
|
161
158
|
|
|
162
|
-
shortResult +=
|
|
163
|
-
if (tokens > 0) {
|
|
164
|
-
shortResult += ` | ${tokens.toLocaleString()} tokens`;
|
|
165
|
-
}
|
|
166
|
-
shortResult += ")";
|
|
159
|
+
shortResult += summary;
|
|
167
160
|
|
|
168
161
|
context.onShortResultUpdate?.(shortResult);
|
|
169
162
|
},
|
|
@@ -214,10 +207,15 @@ ${subagentList || "No subagents configured"}
|
|
|
214
207
|
// Cleanup subagent instance after task completion
|
|
215
208
|
subagentManager.cleanupInstance(instance.subagentId);
|
|
216
209
|
|
|
210
|
+
const messages = instance.messageManager.getMessages();
|
|
211
|
+
const tokens = instance.messageManager.getlatestTotalTokens();
|
|
212
|
+
const toolCount = countToolBlocks(messages);
|
|
213
|
+
const summary = formatToolTokenSummary(toolCount, tokens);
|
|
214
|
+
|
|
217
215
|
return {
|
|
218
216
|
success: true,
|
|
219
217
|
content: result,
|
|
220
|
-
shortResult: `Task completed
|
|
218
|
+
shortResult: `Task completed${summary ? ` ${summary}` : ""}`,
|
|
221
219
|
};
|
|
222
220
|
} finally {
|
|
223
221
|
if (!run_in_background && context.foregroundTaskManager) {
|
package/src/tools/types.ts
CHANGED
|
@@ -23,7 +23,7 @@ export interface ToolPlugin {
|
|
|
23
23
|
context: ToolContext,
|
|
24
24
|
) => string;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Function to provide a prompt to be added to the tool description
|
|
27
27
|
*/
|
|
28
28
|
prompt?: (args?: {
|
|
29
29
|
availableSubagents?: SubagentConfiguration[];
|
|
@@ -53,7 +53,6 @@ export interface ToolResult {
|
|
|
53
53
|
|
|
54
54
|
export interface ToolContext {
|
|
55
55
|
abortSignal?: AbortSignal;
|
|
56
|
-
backgroundBashManager?: import("../managers/backgroundBashManager.js").BackgroundBashManager;
|
|
57
56
|
backgroundTaskManager?: import("../managers/backgroundTaskManager.js").BackgroundTaskManager;
|
|
58
57
|
workdir: string;
|
|
59
58
|
/** Permission mode for this tool execution */
|