wave-agent-sdk 0.0.8 → 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 (236) hide show
  1. package/dist/agent.d.ts +92 -23
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +340 -137
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -0
  7. package/dist/managers/aiManager.d.ts +14 -36
  8. package/dist/managers/aiManager.d.ts.map +1 -1
  9. package/dist/managers/aiManager.js +74 -77
  10. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  11. package/dist/managers/backgroundBashManager.js +4 -3
  12. package/dist/managers/hookManager.d.ts +3 -8
  13. package/dist/managers/hookManager.d.ts.map +1 -1
  14. package/dist/managers/hookManager.js +39 -29
  15. package/dist/managers/liveConfigManager.d.ts +55 -18
  16. package/dist/managers/liveConfigManager.d.ts.map +1 -1
  17. package/dist/managers/liveConfigManager.js +372 -90
  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 +8 -16
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +52 -74
  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 +0 -1
  32. package/dist/managers/subagentManager.d.ts +8 -23
  33. package/dist/managers/subagentManager.d.ts.map +1 -1
  34. package/dist/managers/subagentManager.js +97 -117
  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 +3 -1
  39. package/dist/services/aiService.d.ts.map +1 -1
  40. package/dist/services/aiService.js +123 -30
  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.map +1 -1
  45. package/dist/services/fileWatcher.js +5 -6
  46. package/dist/services/hook.d.ts +7 -124
  47. package/dist/services/hook.d.ts.map +1 -1
  48. package/dist/services/hook.js +46 -458
  49. package/dist/services/jsonlHandler.d.ts +24 -15
  50. package/dist/services/jsonlHandler.d.ts.map +1 -1
  51. package/dist/services/jsonlHandler.js +67 -88
  52. package/dist/services/memory.d.ts +0 -9
  53. package/dist/services/memory.d.ts.map +1 -1
  54. package/dist/services/memory.js +2 -49
  55. package/dist/services/session.d.ts +82 -33
  56. package/dist/services/session.d.ts.map +1 -1
  57. package/dist/services/session.js +275 -181
  58. package/dist/tools/bashTool.d.ts.map +1 -1
  59. package/dist/tools/bashTool.js +72 -13
  60. package/dist/tools/deleteFileTool.d.ts.map +1 -1
  61. package/dist/tools/deleteFileTool.js +25 -0
  62. package/dist/tools/editTool.d.ts.map +1 -1
  63. package/dist/tools/editTool.js +30 -6
  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 +26 -7
  69. package/dist/tools/readTool.d.ts.map +1 -1
  70. package/dist/tools/readTool.js +111 -2
  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 +25 -9
  78. package/dist/types/commands.d.ts +0 -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 +10 -0
  86. package/dist/types/core.d.ts.map +1 -1
  87. package/dist/types/environment.d.ts +41 -0
  88. package/dist/types/environment.d.ts.map +1 -1
  89. package/dist/types/fileSearch.d.ts +5 -0
  90. package/dist/types/fileSearch.d.ts.map +1 -0
  91. package/dist/types/fileSearch.js +1 -0
  92. package/dist/types/hooks.d.ts +11 -2
  93. package/dist/types/hooks.d.ts.map +1 -1
  94. package/dist/types/hooks.js +1 -7
  95. package/dist/types/index.d.ts +5 -0
  96. package/dist/types/index.d.ts.map +1 -1
  97. package/dist/types/index.js +5 -0
  98. package/dist/types/lsp.d.ts +90 -0
  99. package/dist/types/lsp.d.ts.map +1 -0
  100. package/dist/types/lsp.js +4 -0
  101. package/dist/types/messaging.d.ts +6 -11
  102. package/dist/types/messaging.d.ts.map +1 -1
  103. package/dist/types/permissions.d.ts +35 -0
  104. package/dist/types/permissions.d.ts.map +1 -0
  105. package/dist/types/permissions.js +12 -0
  106. package/dist/types/session.d.ts +1 -6
  107. package/dist/types/session.d.ts.map +1 -1
  108. package/dist/types/skills.d.ts +1 -0
  109. package/dist/types/skills.d.ts.map +1 -1
  110. package/dist/types/tools.d.ts +35 -0
  111. package/dist/types/tools.d.ts.map +1 -0
  112. package/dist/types/tools.js +4 -0
  113. package/dist/utils/abortUtils.d.ts +34 -0
  114. package/dist/utils/abortUtils.d.ts.map +1 -0
  115. package/dist/utils/abortUtils.js +92 -0
  116. package/dist/utils/bashHistory.d.ts +4 -0
  117. package/dist/utils/bashHistory.d.ts.map +1 -1
  118. package/dist/utils/bashHistory.js +21 -4
  119. package/dist/utils/builtinSubagents.d.ts +7 -0
  120. package/dist/utils/builtinSubagents.d.ts.map +1 -0
  121. package/dist/utils/builtinSubagents.js +65 -0
  122. package/dist/utils/cacheControlUtils.d.ts +8 -33
  123. package/dist/utils/cacheControlUtils.d.ts.map +1 -1
  124. package/dist/utils/cacheControlUtils.js +83 -126
  125. package/dist/utils/constants.d.ts +0 -12
  126. package/dist/utils/constants.d.ts.map +1 -1
  127. package/dist/utils/constants.js +1 -13
  128. package/dist/utils/convertMessagesForAPI.d.ts +2 -1
  129. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  130. package/dist/utils/convertMessagesForAPI.js +33 -14
  131. package/dist/utils/fileSearch.d.ts +14 -0
  132. package/dist/utils/fileSearch.d.ts.map +1 -0
  133. package/dist/utils/fileSearch.js +88 -0
  134. package/dist/utils/fileUtils.d.ts +14 -2
  135. package/dist/utils/fileUtils.d.ts.map +1 -1
  136. package/dist/utils/fileUtils.js +101 -17
  137. package/dist/utils/globalLogger.d.ts +0 -14
  138. package/dist/utils/globalLogger.d.ts.map +1 -1
  139. package/dist/utils/globalLogger.js +0 -16
  140. package/dist/utils/largeOutputHandler.d.ts +15 -0
  141. package/dist/utils/largeOutputHandler.d.ts.map +1 -0
  142. package/dist/utils/largeOutputHandler.js +40 -0
  143. package/dist/utils/markdownParser.d.ts.map +1 -1
  144. package/dist/utils/markdownParser.js +1 -17
  145. package/dist/utils/messageOperations.d.ts +1 -11
  146. package/dist/utils/messageOperations.d.ts.map +1 -1
  147. package/dist/utils/messageOperations.js +7 -24
  148. package/dist/utils/pathEncoder.d.ts +4 -0
  149. package/dist/utils/pathEncoder.d.ts.map +1 -1
  150. package/dist/utils/pathEncoder.js +16 -9
  151. package/dist/utils/subagentParser.d.ts +2 -2
  152. package/dist/utils/subagentParser.d.ts.map +1 -1
  153. package/dist/utils/subagentParser.js +10 -7
  154. package/dist/utils/tokenEstimator.d.ts +39 -0
  155. package/dist/utils/tokenEstimator.d.ts.map +1 -0
  156. package/dist/utils/tokenEstimator.js +55 -0
  157. package/package.json +5 -8
  158. package/src/agent.ts +460 -216
  159. package/src/index.ts +2 -0
  160. package/src/managers/aiManager.ts +107 -111
  161. package/src/managers/backgroundBashManager.ts +4 -3
  162. package/src/managers/hookManager.ts +44 -39
  163. package/src/managers/liveConfigManager.ts +524 -138
  164. package/src/managers/lspManager.ts +434 -0
  165. package/src/managers/messageManager.ts +73 -103
  166. package/src/managers/permissionManager.ts +276 -0
  167. package/src/managers/skillManager.ts +3 -1
  168. package/src/managers/slashCommandManager.ts +1 -2
  169. package/src/managers/subagentManager.ts +116 -159
  170. package/src/managers/toolManager.ts +95 -3
  171. package/src/services/aiService.ts +207 -26
  172. package/src/services/configurationService.ts +762 -0
  173. package/src/services/fileWatcher.ts +5 -6
  174. package/src/services/hook.ts +50 -631
  175. package/src/services/jsonlHandler.ts +84 -100
  176. package/src/services/memory.ts +2 -59
  177. package/src/services/session.ts +338 -213
  178. package/src/tools/bashTool.ts +89 -16
  179. package/src/tools/deleteFileTool.ts +36 -0
  180. package/src/tools/editTool.ts +41 -7
  181. package/src/tools/lspTool.ts +760 -0
  182. package/src/tools/multiEditTool.ts +37 -8
  183. package/src/tools/readTool.ts +125 -2
  184. package/src/tools/skillTool.ts +2 -2
  185. package/src/tools/todoWriteTool.ts +33 -1
  186. package/src/tools/types.ts +15 -9
  187. package/src/tools/writeTool.ts +36 -10
  188. package/src/types/commands.ts +0 -1
  189. package/src/types/config.ts +5 -0
  190. package/src/types/configuration.ts +73 -0
  191. package/src/types/core.ts +11 -0
  192. package/src/types/environment.ts +44 -0
  193. package/src/types/fileSearch.ts +4 -0
  194. package/src/types/hooks.ts +14 -11
  195. package/src/types/index.ts +5 -0
  196. package/src/types/lsp.ts +96 -0
  197. package/src/types/messaging.ts +8 -13
  198. package/src/types/permissions.ts +48 -0
  199. package/src/types/session.ts +3 -8
  200. package/src/types/skills.ts +1 -0
  201. package/src/types/tools.ts +38 -0
  202. package/src/utils/abortUtils.ts +118 -0
  203. package/src/utils/bashHistory.ts +28 -4
  204. package/src/utils/builtinSubagents.ts +71 -0
  205. package/src/utils/cacheControlUtils.ts +106 -171
  206. package/src/utils/constants.ts +1 -16
  207. package/src/utils/convertMessagesForAPI.ts +38 -14
  208. package/src/utils/fileSearch.ts +107 -0
  209. package/src/utils/fileUtils.ts +114 -19
  210. package/src/utils/globalLogger.ts +0 -17
  211. package/src/utils/largeOutputHandler.ts +55 -0
  212. package/src/utils/markdownParser.ts +1 -19
  213. package/src/utils/messageOperations.ts +7 -35
  214. package/src/utils/pathEncoder.ts +24 -9
  215. package/src/utils/subagentParser.ts +11 -8
  216. package/src/utils/tokenEstimator.ts +68 -0
  217. package/dist/constants/events.d.ts +0 -28
  218. package/dist/constants/events.d.ts.map +0 -1
  219. package/dist/constants/events.js +0 -27
  220. package/dist/services/configurationWatcher.d.ts +0 -120
  221. package/dist/services/configurationWatcher.d.ts.map +0 -1
  222. package/dist/services/configurationWatcher.js +0 -439
  223. package/dist/services/memoryStore.d.ts +0 -81
  224. package/dist/services/memoryStore.d.ts.map +0 -1
  225. package/dist/services/memoryStore.js +0 -200
  226. package/dist/types/memoryStore.d.ts +0 -82
  227. package/dist/types/memoryStore.d.ts.map +0 -1
  228. package/dist/types/memoryStore.js +0 -7
  229. package/dist/utils/configResolver.d.ts +0 -65
  230. package/dist/utils/configResolver.d.ts.map +0 -1
  231. package/dist/utils/configResolver.js +0 -210
  232. package/src/constants/events.ts +0 -38
  233. package/src/services/configurationWatcher.ts +0 -622
  234. package/src/services/memoryStore.ts +0 -279
  235. package/src/types/memoryStore.ts +0 -94
  236. package/src/utils/configResolver.ts +0 -302
@@ -0,0 +1,96 @@
1
+ /**
2
+ * LSP (Language Server Protocol) configuration and communication types
3
+ */
4
+
5
+ export interface LspServerConfig {
6
+ command: string;
7
+ args?: string[];
8
+ extensionToLanguage: Record<string, string>;
9
+ transport?: "stdio" | "socket";
10
+ env?: Record<string, string>;
11
+ initializationOptions?: unknown;
12
+ settings?: unknown;
13
+ workspaceFolder?: string;
14
+ startupTimeout?: number;
15
+ shutdownTimeout?: number;
16
+ restartOnCrash?: boolean;
17
+ maxRestarts?: number;
18
+ }
19
+
20
+ export interface LspConfig {
21
+ [language: string]: LspServerConfig;
22
+ }
23
+
24
+ export interface LspPosition {
25
+ line: number;
26
+ character: number;
27
+ }
28
+
29
+ export interface LspRange {
30
+ start: LspPosition;
31
+ end: LspPosition;
32
+ }
33
+
34
+ export interface LspLocation {
35
+ uri: string;
36
+ range: LspRange;
37
+ }
38
+
39
+ export interface LspLocationLink {
40
+ originSelectionRange?: LspRange;
41
+ targetUri: string;
42
+ targetRange: LspRange;
43
+ targetSelectionRange?: LspRange;
44
+ }
45
+
46
+ export interface LspHover {
47
+ contents:
48
+ | string
49
+ | { kind: string; value: string }
50
+ | Array<string | { kind: string; value: string }>;
51
+ range?: LspRange;
52
+ }
53
+
54
+ export interface LspSymbolInformation {
55
+ name: string;
56
+ kind: number;
57
+ location: LspLocation;
58
+ containerName?: string;
59
+ }
60
+
61
+ export interface LspDocumentSymbol {
62
+ name: string;
63
+ detail?: string;
64
+ kind: number;
65
+ range: LspRange;
66
+ selectionRange: LspRange;
67
+ children?: LspDocumentSymbol[];
68
+ }
69
+
70
+ export interface LspCallHierarchyItem {
71
+ name: string;
72
+ kind: number;
73
+ detail?: string;
74
+ uri: string;
75
+ range: LspRange;
76
+ selectionRange: LspRange;
77
+ }
78
+
79
+ export interface LspCallHierarchyIncomingCall {
80
+ from: LspCallHierarchyItem;
81
+ fromRanges: LspRange[];
82
+ }
83
+
84
+ export interface LspCallHierarchyOutgoingCall {
85
+ to: LspCallHierarchyItem;
86
+ fromRanges: LspRange[];
87
+ }
88
+
89
+ export interface ILspManager {
90
+ execute(args: {
91
+ operation: string;
92
+ filePath: string;
93
+ line: number;
94
+ character: number;
95
+ }): Promise<{ success: boolean; content: string }>;
96
+ }
@@ -15,7 +15,7 @@ export interface Message {
15
15
  role: "user" | "assistant";
16
16
  blocks: MessageBlock[];
17
17
  usage?: Usage; // Usage data for this message's AI operation (assistant messages only)
18
- metadata?: Record<string, unknown>; // Additional metadata from AI responses
18
+ additionalFields?: Record<string, unknown>; // Additional metadata from AI responses
19
19
  }
20
20
 
21
21
  export type MessageBlock =
@@ -23,11 +23,11 @@ export type MessageBlock =
23
23
  | ErrorBlock
24
24
  | ToolBlock
25
25
  | ImageBlock
26
- | DiffBlock
27
26
  | CommandOutputBlock
28
27
  | CompressBlock
29
28
  | MemoryBlock
30
- | SubagentBlock;
29
+ | SubagentBlock
30
+ | ReasoningBlock;
31
31
 
32
32
  export interface TextBlock {
33
33
  type: "text";
@@ -72,16 +72,6 @@ export interface ImageBlock {
72
72
  imageUrls?: string[];
73
73
  }
74
74
 
75
- export interface DiffBlock {
76
- type: "diff";
77
- path: string;
78
- diffResult: Array<{
79
- value: string;
80
- added?: boolean;
81
- removed?: boolean;
82
- }>;
83
- }
84
-
85
75
  export interface CommandOutputBlock {
86
76
  type: "command_output";
87
77
  command: string;
@@ -112,3 +102,8 @@ export interface SubagentBlock {
112
102
  sessionId: string;
113
103
  configuration: SubagentConfiguration;
114
104
  }
105
+
106
+ export interface ReasoningBlock {
107
+ type: "reasoning";
108
+ content: string;
109
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Permission system types for Wave Agent SDK
3
+ * Dependencies: None
4
+ */
5
+
6
+ /** Permission mode configuration */
7
+ export type PermissionMode = "default" | "bypassPermissions" | "acceptEdits";
8
+
9
+ /** Result of a permission check */
10
+ export interface PermissionDecision {
11
+ /** Whether to allow or deny the operation */
12
+ behavior: "allow" | "deny";
13
+ /** Optional message explaining the decision (required for deny) */
14
+ message?: string;
15
+ /** Signal to change the session's permission mode */
16
+ newPermissionMode?: PermissionMode;
17
+ /** Signal to persist a new allowed rule */
18
+ newPermissionRule?: string;
19
+ }
20
+
21
+ /** Callback function for custom permission logic */
22
+ export type PermissionCallback = (
23
+ context: ToolPermissionContext,
24
+ ) => Promise<PermissionDecision>;
25
+
26
+ /** Internal context passed to PermissionManager */
27
+ export interface ToolPermissionContext {
28
+ /** Name of the tool being executed */
29
+ toolName: string;
30
+ /** Current permission mode */
31
+ permissionMode: PermissionMode;
32
+ /** Custom permission callback if provided */
33
+ canUseToolCallback?: PermissionCallback;
34
+ /** Tool input parameters for better context */
35
+ toolInput?: Record<string, unknown>;
36
+ }
37
+
38
+ /** List of tools that require permission checks in default mode */
39
+ export const RESTRICTED_TOOLS = [
40
+ "Edit",
41
+ "MultiEdit",
42
+ "Delete",
43
+ "Bash",
44
+ "Write",
45
+ ] as const;
46
+
47
+ /** Type for restricted tool names */
48
+ export type RestrictedTool = (typeof RESTRICTED_TOOLS)[number];
@@ -10,16 +10,11 @@ import type { Message } from "./messaging.js";
10
10
  // Enhanced message interface for JSONL storage (extends existing Message)
11
11
  export interface SessionMessage extends Message {
12
12
  timestamp: string; // ISO 8601 - added for JSONL format
13
- // Inherits: role: "user" | "assistant", blocks: MessageBlock[], usage?, metadata?
13
+ // Inherits: role: "user" | "assistant", blocks: MessageBlock[], usage?, additionalFields?
14
14
  }
15
15
 
16
- // Metadata line that appears as the first line in JSONL session files
17
- export interface SessionMetadataLine {
18
- __meta__: true;
16
+ // Session filename structure for simple filename-based metadata
17
+ export interface SessionFilename {
19
18
  sessionId: string;
20
19
  sessionType: "main" | "subagent";
21
- parentSessionId?: string;
22
- subagentType?: string;
23
- workdir: string;
24
- startedAt: string;
25
20
  }
@@ -61,6 +61,7 @@ export interface SkillManagerOptions {
61
61
  personalSkillsPath?: string;
62
62
  scanTimeout?: number;
63
63
  logger?: Logger;
64
+ workdir?: string;
64
65
  }
65
66
 
66
67
  export interface ParsedSkillFile {
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Tool parameter types for edit and write operations
3
+ */
4
+
5
+ /**
6
+ * Parameters for the Write tool
7
+ */
8
+ export interface WriteToolParameters {
9
+ file_path: string;
10
+ content: string;
11
+ }
12
+
13
+ /**
14
+ * Parameters for a single edit operation in the Edit tool
15
+ */
16
+ export interface EditOperation {
17
+ old_string: string;
18
+ new_string: string;
19
+ replace_all?: boolean;
20
+ }
21
+
22
+ /**
23
+ * Parameters for the Edit tool
24
+ */
25
+ export interface EditToolParameters {
26
+ file_path: string;
27
+ old_string: string;
28
+ new_string: string;
29
+ replace_all?: boolean;
30
+ }
31
+
32
+ /**
33
+ * Parameters for the MultiEdit tool
34
+ */
35
+ export interface MultiEditToolParameters {
36
+ file_path: string;
37
+ edits: EditOperation[];
38
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Utilities for safe AbortSignal listener management to prevent memory leaks
3
+ */
4
+
5
+ /**
6
+ * Safely adds a one-time abort listener that automatically cleans up after firing
7
+ * @param signal - The AbortSignal to listen to
8
+ * @param callback - The function to call when aborted
9
+ * @returns A cleanup function to manually remove the listener if needed
10
+ */
11
+ export function addOnceAbortListener(
12
+ signal: AbortSignal,
13
+ callback: () => void,
14
+ ): () => void {
15
+ if (signal.aborted) {
16
+ // Signal already aborted, call immediately
17
+ callback();
18
+ return () => {}; // No cleanup needed
19
+ }
20
+
21
+ const handler = () => {
22
+ callback();
23
+ };
24
+
25
+ // Use { once: true } to automatically remove listener after first call
26
+ signal.addEventListener("abort", handler, { once: true });
27
+
28
+ // Return cleanup function for manual removal if needed
29
+ return () => {
30
+ signal.removeEventListener("abort", handler);
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Creates a Promise that rejects when the AbortSignal is aborted
36
+ * Uses once-only listener to prevent accumulation
37
+ * @param signal - The AbortSignal to listen to
38
+ * @param errorMessage - Optional custom error message
39
+ * @returns Promise that rejects on abort
40
+ */
41
+ export function createAbortPromise(
42
+ signal: AbortSignal,
43
+ errorMessage: string = "Operation was aborted",
44
+ ): Promise<never> {
45
+ return new Promise<never>((_, reject) => {
46
+ if (signal.aborted) {
47
+ reject(new Error(errorMessage));
48
+ return;
49
+ }
50
+
51
+ // Use once-only listener to prevent accumulation
52
+ signal.addEventListener(
53
+ "abort",
54
+ () => {
55
+ reject(new Error(errorMessage));
56
+ },
57
+ { once: true },
58
+ );
59
+ });
60
+ }
61
+
62
+ /**
63
+ * Wrapper that manages abort signal listeners with automatic cleanup
64
+ * @param signal - The AbortSignal to manage
65
+ * @param operation - Function that sets up listeners and returns cleanup
66
+ * @returns Promise that resolves with the operation result
67
+ */
68
+ export async function withAbortCleanup<T>(
69
+ signal: AbortSignal,
70
+ operation: (signal: AbortSignal) => Promise<T>,
71
+ ): Promise<T> {
72
+ // Track all cleanup functions
73
+ const cleanups: (() => void)[] = [];
74
+
75
+ try {
76
+ const result = await operation(signal);
77
+ return result;
78
+ } finally {
79
+ // Clean up all listeners
80
+ cleanups.forEach((cleanup) => cleanup());
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Consolidates multiple abort listeners into a single listener
86
+ * Useful when multiple handlers need to respond to the same abort signal
87
+ * @param signal - The AbortSignal to listen to
88
+ * @param callbacks - Array of functions to call when aborted
89
+ * @returns Cleanup function to remove the consolidated listener
90
+ */
91
+ export function addConsolidatedAbortListener(
92
+ signal: AbortSignal,
93
+ callbacks: (() => void)[],
94
+ ): () => void {
95
+ if (signal.aborted) {
96
+ // Signal already aborted, call all callbacks immediately
97
+ callbacks.forEach((cb) => cb());
98
+ return () => {}; // No cleanup needed
99
+ }
100
+
101
+ const handler = () => {
102
+ callbacks.forEach((cb) => {
103
+ try {
104
+ cb();
105
+ } catch (error) {
106
+ console.error("Error in abort callback:", error);
107
+ }
108
+ });
109
+ };
110
+
111
+ // Use { once: true } to automatically remove listener after first call
112
+ signal.addEventListener("abort", handler, { once: true });
113
+
114
+ // Return cleanup function for manual removal if needed
115
+ return () => {
116
+ signal.removeEventListener("abort", handler);
117
+ };
118
+ }
@@ -153,7 +153,7 @@ export const searchBashHistory = (
153
153
  if (!normalizedQuery) {
154
154
  // If no search query, return recent commands (deduplicated)
155
155
  const deduped = deduplicateCommands(filteredCommands);
156
- return deduped.slice(-limit).reverse(); // Latest first
156
+ return deduped.slice(0, limit); // Latest first
157
157
  }
158
158
 
159
159
  // Search by relevance
@@ -226,9 +226,9 @@ const deduplicateCommands = (
226
226
  }
227
227
  }
228
228
 
229
- // Sort by timestamp and return
229
+ // Sort by timestamp and return (new to old)
230
230
  return Array.from(commandMap.values()).sort(
231
- (a, b) => a.timestamp - b.timestamp,
231
+ (a, b) => b.timestamp - a.timestamp,
232
232
  );
233
233
  };
234
234
 
@@ -247,13 +247,37 @@ export const getRecentBashCommands = (
247
247
 
248
248
  // Return recent commands after deduplication
249
249
  const deduped = deduplicateCommands(filtered);
250
- return deduped.slice(-limit).reverse(); // Latest first
250
+ return deduped.slice(0, limit); // Latest first
251
251
  } catch (error) {
252
252
  logger.debug("Failed to get recent bash commands:", error);
253
253
  return [];
254
254
  }
255
255
  };
256
256
 
257
+ /**
258
+ * Delete a specific command from bash history
259
+ */
260
+ export const deleteBashCommandFromHistory = (
261
+ command: string,
262
+ workdir: string,
263
+ ): void => {
264
+ try {
265
+ const history = loadBashHistory();
266
+ const initialLength = history.commands.length;
267
+
268
+ history.commands = history.commands.filter(
269
+ (entry) => !(entry.command === command && entry.workdir === workdir),
270
+ );
271
+
272
+ if (history.commands.length !== initialLength) {
273
+ saveBashHistory(history);
274
+ logger.debug("Deleted bash command from history:", { command, workdir });
275
+ }
276
+ } catch (error) {
277
+ logger.debug("Failed to delete bash command from history:", error);
278
+ }
279
+ };
280
+
257
281
  /**
258
282
  * Clear bash history
259
283
  */
@@ -0,0 +1,71 @@
1
+ import type { SubagentConfiguration } from "./subagentParser.js";
2
+
3
+ /**
4
+ * Get all built-in subagent configurations
5
+ * Built-in subagents have priority 3 (lowest) and can be overridden by user/project configs
6
+ */
7
+ export function getBuiltinSubagents(): SubagentConfiguration[] {
8
+ return [
9
+ createExploreSubagent(),
10
+ // Add more built-in subagents here as needed
11
+ ];
12
+ }
13
+
14
+ /**
15
+ * Create the Explore built-in subagent configuration
16
+ * Specialized for codebase exploration and file search tasks
17
+ */
18
+ function createExploreSubagent(): SubagentConfiguration {
19
+ const systemPrompt = `You are a file search specialist. You excel at thoroughly navigating and exploring codebases.
20
+
21
+ === CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===
22
+ This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:
23
+ - Creating new files (no Write, touch, or file creation of any kind)
24
+ - Modifying existing files (no Edit operations)
25
+ - Deleting files (no rm or deletion)
26
+ - Moving or copying files (no mv or cp)
27
+ - Creating temporary files anywhere, including /tmp
28
+ - Using redirect operators (>, >>, |) or heredocs to write to files
29
+ - Running ANY commands that change system state
30
+
31
+ Your role is EXCLUSIVELY to search and analyze existing code. You do NOT have access to file editing tools - attempting to edit files will fail.
32
+
33
+ Your strengths:
34
+ - Rapidly finding files using glob patterns
35
+ - Searching code and text with powerful regex patterns
36
+ - Reading and analyzing file contents
37
+ - Using Language Server Protocol (LSP) for deep code intelligence (definitions, references, etc.)
38
+
39
+ Guidelines:
40
+ - Use Glob for broad file pattern matching
41
+ - Use Grep for searching file contents with regex
42
+ - Use Read when you know the specific file path you need to read
43
+ - Use LSP for code intelligence features like finding definitions, references, implementations, and symbols. This is especially useful for understanding complex code relationships.
44
+ - Use Bash ONLY for read-only operations (ls, git status, git log, git diff, find, cat, head, tail)
45
+ - NEVER use Bash for: mkdir, touch, rm, cp, mv, git add, git commit, npm install, pip install, or any file creation/modification
46
+ - Adapt your search approach based on the thoroughness level specified by the caller
47
+ - Return file paths as absolute paths in your final response
48
+ - For clear communication, avoid using emojis
49
+ - Communicate your final report directly as a regular message - do NOT attempt to create files
50
+
51
+ NOTE: You are meant to be a fast agent that returns output as quickly as possible. In order to achieve this you must:
52
+ - Make efficient use of the tools that you have at your disposal: be smart about how you search for files and implementations
53
+ - Wherever possible you should try to spawn multiple parallel tool calls for grepping and reading files
54
+
55
+ Complete the user's search request efficiently and report your findings clearly.`;
56
+
57
+ // Define allowed tools for read-only operations
58
+ const allowedTools = ["Glob", "Grep", "Read", "Bash", "LS", "LSP"];
59
+
60
+ return {
61
+ name: "Explore",
62
+ description:
63
+ 'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.',
64
+ systemPrompt,
65
+ tools: allowedTools,
66
+ model: "fastModel", // Special value that will use parent's fastModel
67
+ filePath: "<builtin:Explore>",
68
+ scope: "builtin",
69
+ priority: 3, // Lowest priority - can be overridden by user configs
70
+ };
71
+ }