wave-agent-sdk 1.0.5 → 1.0.6

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 (193) hide show
  1. package/dist/agent.d.ts +23 -1
  2. package/dist/agent.js +34 -4
  3. package/dist/managers/aiManager.d.ts +36 -0
  4. package/dist/managers/aiManager.js +240 -8
  5. package/dist/managers/messageManager.d.ts +1 -3
  6. package/dist/managers/messageManager.js +13 -6
  7. package/dist/managers/slashCommandManager.js +28 -0
  8. package/dist/managers/subagentManager.d.ts +0 -2
  9. package/dist/telemetry/instrumentation.d.ts +1 -1
  10. package/dist/telemetry/instrumentation.js +57 -28
  11. package/dist/tools/bashTool.js +16 -6
  12. package/dist/tools/grepTool.js +11 -3
  13. package/dist/types/index.d.ts +3 -0
  14. package/dist/types/messaging.d.ts +2 -0
  15. package/dist/utils/containerSetup.js +0 -3
  16. package/dist/utils/messageOperations.d.ts +2 -1
  17. package/dist/utils/messageOperations.js +2 -1
  18. package/dist/utils/notificationXml.js +5 -0
  19. package/dist/utils/ripgrep.d.ts +4 -4
  20. package/dist/utils/ripgrep.js +4 -27
  21. package/package.json +20 -8
  22. package/bin/rg +0 -79
  23. package/dist/managers/forkedAgentManager.d.ts +0 -50
  24. package/dist/managers/forkedAgentManager.js +0 -130
  25. package/scripts/install_ripgrep.js +0 -111
  26. package/scripts/postinstall.js +0 -38
  27. package/src/agent.ts +0 -1271
  28. package/src/constants/subagents.ts +0 -4
  29. package/src/constants/toolLimits.ts +0 -15
  30. package/src/constants/tools.ts +0 -24
  31. package/src/core/plugin.ts +0 -237
  32. package/src/core/session.ts +0 -9
  33. package/src/index.ts +0 -38
  34. package/src/managers/MemoryRuleManager.ts +0 -198
  35. package/src/managers/aiManager.ts +0 -2429
  36. package/src/managers/backgroundTaskManager.ts +0 -480
  37. package/src/managers/bangManager.ts +0 -119
  38. package/src/managers/cronManager.ts +0 -401
  39. package/src/managers/foregroundTaskManager.ts +0 -30
  40. package/src/managers/forkedAgentManager.ts +0 -216
  41. package/src/managers/hookManager.ts +0 -1089
  42. package/src/managers/liveConfigManager.ts +0 -445
  43. package/src/managers/lspManager.ts +0 -470
  44. package/src/managers/mcpManager.ts +0 -1010
  45. package/src/managers/messageManager.ts +0 -1184
  46. package/src/managers/messageQueue.ts +0 -157
  47. package/src/managers/permissionManager.ts +0 -1140
  48. package/src/managers/planManager.ts +0 -112
  49. package/src/managers/pluginManager.ts +0 -330
  50. package/src/managers/pluginScopeManager.ts +0 -124
  51. package/src/managers/reversionManager.ts +0 -178
  52. package/src/managers/skillManager.ts +0 -578
  53. package/src/managers/slashCommandManager.ts +0 -564
  54. package/src/managers/subagentManager.ts +0 -915
  55. package/src/managers/toolManager.ts +0 -489
  56. package/src/managers/workflowManager.ts +0 -493
  57. package/src/prompts/autoMemory.ts +0 -33
  58. package/src/prompts/autoMemoryExtraction.ts +0 -146
  59. package/src/prompts/index.ts +0 -506
  60. package/src/prompts/planModeReminders.ts +0 -126
  61. package/src/services/GitService.ts +0 -131
  62. package/src/services/MarketplaceService.ts +0 -1052
  63. package/src/services/MemoryRuleService.ts +0 -71
  64. package/src/services/aiService.ts +0 -919
  65. package/src/services/authService.ts +0 -565
  66. package/src/services/autoMemoryService.ts +0 -280
  67. package/src/services/configurationService.ts +0 -1520
  68. package/src/services/fileWatcher.ts +0 -319
  69. package/src/services/hook.ts +0 -348
  70. package/src/services/initializationService.ts +0 -357
  71. package/src/services/interactionService.ts +0 -229
  72. package/src/services/jsonlHandler.ts +0 -295
  73. package/src/services/memory.ts +0 -234
  74. package/src/services/pluginLoader.ts +0 -252
  75. package/src/services/remoteSettingsService.ts +0 -366
  76. package/src/services/reversionService.ts +0 -122
  77. package/src/services/session.ts +0 -917
  78. package/src/services/taskManager.ts +0 -321
  79. package/src/telemetry/events.ts +0 -65
  80. package/src/telemetry/instrumentation.ts +0 -499
  81. package/src/telemetry/sessionTracing.ts +0 -348
  82. package/src/tools/agentTool.ts +0 -322
  83. package/src/tools/askUserQuestion.ts +0 -160
  84. package/src/tools/bashTool.ts +0 -621
  85. package/src/tools/buildTool.ts +0 -61
  86. package/src/tools/cronCreateTool.ts +0 -161
  87. package/src/tools/cronDeleteTool.ts +0 -51
  88. package/src/tools/cronListTool.ts +0 -47
  89. package/src/tools/editTool.ts +0 -313
  90. package/src/tools/enterPlanMode.ts +0 -124
  91. package/src/tools/enterWorktreeTool.ts +0 -190
  92. package/src/tools/exitPlanMode.ts +0 -139
  93. package/src/tools/exitWorktreeTool.ts +0 -236
  94. package/src/tools/globTool.ts +0 -167
  95. package/src/tools/grepTool.ts +0 -399
  96. package/src/tools/lspTool.ts +0 -883
  97. package/src/tools/readTool.ts +0 -426
  98. package/src/tools/skillTool.ts +0 -248
  99. package/src/tools/taskManagementTools.ts +0 -574
  100. package/src/tools/taskStopTool.ts +0 -78
  101. package/src/tools/types.ts +0 -137
  102. package/src/tools/webFetchTool.ts +0 -373
  103. package/src/tools/workflowTool.ts +0 -205
  104. package/src/tools/writeTool.ts +0 -267
  105. package/src/types/agent.ts +0 -128
  106. package/src/types/auth.ts +0 -19
  107. package/src/types/commands.ts +0 -30
  108. package/src/types/config.ts +0 -43
  109. package/src/types/configuration.ts +0 -168
  110. package/src/types/core.ts +0 -105
  111. package/src/types/cron.ts +0 -13
  112. package/src/types/environment.ts +0 -106
  113. package/src/types/fileSearch.ts +0 -4
  114. package/src/types/history.ts +0 -7
  115. package/src/types/hooks.ts +0 -256
  116. package/src/types/index.ts +0 -41
  117. package/src/types/lsp.ts +0 -98
  118. package/src/types/marketplace.ts +0 -71
  119. package/src/types/mcp.ts +0 -43
  120. package/src/types/memoryRule.ts +0 -31
  121. package/src/types/messaging.ts +0 -114
  122. package/src/types/permissions.ts +0 -80
  123. package/src/types/plugins.ts +0 -39
  124. package/src/types/processes.ts +0 -99
  125. package/src/types/reversion.ts +0 -29
  126. package/src/types/session.ts +0 -12
  127. package/src/types/skills.ts +0 -108
  128. package/src/types/tasks.ts +0 -13
  129. package/src/types/telemetry.ts +0 -98
  130. package/src/types/tools.ts +0 -44
  131. package/src/types/workflow.ts +0 -6
  132. package/src/utils/abortUtils.ts +0 -118
  133. package/src/utils/atomicWrite.ts +0 -61
  134. package/src/utils/bashParser.ts +0 -899
  135. package/src/utils/cacheControlUtils.ts +0 -426
  136. package/src/utils/commandArgumentParser.ts +0 -161
  137. package/src/utils/commandPathResolver.ts +0 -88
  138. package/src/utils/configPaths.ts +0 -220
  139. package/src/utils/configValidator.ts +0 -100
  140. package/src/utils/constants.ts +0 -39
  141. package/src/utils/container.ts +0 -92
  142. package/src/utils/containerSetup.ts +0 -371
  143. package/src/utils/convertMessagesForAPI.ts +0 -326
  144. package/src/utils/cronTasks.ts +0 -128
  145. package/src/utils/cronTasksLock.ts +0 -182
  146. package/src/utils/cronToHuman.ts +0 -99
  147. package/src/utils/customCommands.ts +0 -95
  148. package/src/utils/editUtils.ts +0 -20
  149. package/src/utils/fileFormat.ts +0 -40
  150. package/src/utils/fileSearch.ts +0 -151
  151. package/src/utils/fileUtils.ts +0 -223
  152. package/src/utils/gitUtils.ts +0 -315
  153. package/src/utils/globalLogger.ts +0 -128
  154. package/src/utils/groupMessagesByApiRound.ts +0 -121
  155. package/src/utils/hookMatcher.ts +0 -176
  156. package/src/utils/markdownParser.ts +0 -317
  157. package/src/utils/mcpUtils.ts +0 -138
  158. package/src/utils/messageOperations.ts +0 -659
  159. package/src/utils/modelCapabilities.ts +0 -30
  160. package/src/utils/nameGenerator.ts +0 -99
  161. package/src/utils/notificationXml.ts +0 -57
  162. package/src/utils/openaiClient.ts +0 -251
  163. package/src/utils/parseCronExpression.ts +0 -78
  164. package/src/utils/path.ts +0 -72
  165. package/src/utils/pathEncoder.ts +0 -400
  166. package/src/utils/pathSafety.ts +0 -40
  167. package/src/utils/promptHistory.ts +0 -168
  168. package/src/utils/ripgrep.ts +0 -35
  169. package/src/utils/shellResolver.ts +0 -190
  170. package/src/utils/skillParser.ts +0 -246
  171. package/src/utils/stringUtils.ts +0 -156
  172. package/src/utils/subagentParser.ts +0 -279
  173. package/src/utils/taskReminder.ts +0 -96
  174. package/src/utils/tokenCalculation.ts +0 -43
  175. package/src/utils/tokenEstimate.ts +0 -34
  176. package/src/utils/toolResultStorage.ts +0 -117
  177. package/src/utils/worktreeSession.ts +0 -26
  178. package/src/utils/worktreeUtils.ts +0 -786
  179. package/src/workflow/budgetTracker.ts +0 -34
  180. package/src/workflow/concurrencyLimiter.ts +0 -47
  181. package/src/workflow/journal.ts +0 -95
  182. package/src/workflow/progressReporter.ts +0 -141
  183. package/src/workflow/runState.ts +0 -65
  184. package/src/workflow/scriptRuntime.ts +0 -274
  185. package/src/workflow/structuredOutput.ts +0 -123
  186. package/src/workflow/types.ts +0 -101
  187. package/src/workflow/workflowApis.ts +0 -410
  188. package/vendor/ripgrep/linux-aarch64/rg +0 -0
  189. package/vendor/ripgrep/linux-x86_64/rg +0 -0
  190. package/vendor/ripgrep/macos-aarch64/rg +0 -0
  191. package/vendor/ripgrep/macos-x86_64/rg +0 -0
  192. package/vendor/ripgrep/windows-aarch64/rg.exe +0 -0
  193. package/vendor/ripgrep/windows-x86_64/rg.exe +0 -0
@@ -1,321 +0,0 @@
1
- import { promises as fs } from "fs";
2
- import { join } from "path";
3
- import { homedir } from "os";
4
- import { EventEmitter } from "events";
5
- import { Task } from "../types/tasks.js";
6
- import { logger } from "../utils/globalLogger.js";
7
- import { Container } from "../utils/container.js";
8
- import type { MessageManager } from "../managers/messageManager.js";
9
- import type { ConfigurationService } from "./configurationService.js";
10
-
11
- function byIdAsc(a: Task, b: Task) {
12
- const aNum = parseInt(a.id, 10);
13
- const bNum = parseInt(b.id, 10);
14
- if (!isNaN(aNum) && !isNaN(bNum)) return aNum - bNum;
15
- return a.id.localeCompare(b.id);
16
- }
17
-
18
- export class TaskManager extends EventEmitter {
19
- private readonly baseDir: string;
20
- private taskListId: string;
21
-
22
- constructor(
23
- private container: Container,
24
- taskListId: string,
25
- ) {
26
- super();
27
- this.taskListId = taskListId;
28
- this.baseDir = join(homedir(), ".wave", "tasks");
29
- }
30
-
31
- public getTaskListId(): string {
32
- return this.taskListId;
33
- }
34
-
35
- public setTaskListId(taskListId: string): void {
36
- this.taskListId = taskListId;
37
- }
38
-
39
- /**
40
- * Syncs the task list ID with the current session's root session ID.
41
- * This is typically called when the session is cleared or compacted.
42
- */
43
- public async syncWithSession(): Promise<void> {
44
- const messageManager = this.container.get<MessageManager>("MessageManager");
45
- if (!messageManager) return;
46
-
47
- const rootSessionId = messageManager.getRootSessionId();
48
- // Read the per-session snapshot (not process.env) so multiple sessions in
49
- // one `wave --stdio` process don't cross-pollute this flag.
50
- const envSnap =
51
- this.container
52
- .get<ConfigurationService>("ConfigurationService")
53
- ?.getEnvSnapshot() ?? {};
54
- const pinnedTaskListId =
55
- envSnap.WAVE_TASK_LIST_ID ?? process.env.WAVE_TASK_LIST_ID;
56
- if (this.taskListId !== rootSessionId && !pinnedTaskListId) {
57
- this.setTaskListId(rootSessionId);
58
- await this.refreshTasks();
59
- }
60
- }
61
-
62
- private getSessionDir(): string {
63
- return join(this.baseDir, this.taskListId);
64
- }
65
-
66
- public getTaskPath(taskId: string): string {
67
- return join(this.getSessionDir(), `${taskId}.json`);
68
- }
69
-
70
- private getLockPath(): string {
71
- return join(this.getSessionDir(), `.lock`);
72
- }
73
-
74
- async ensureSessionDir(): Promise<void> {
75
- await fs.mkdir(this.getSessionDir(), { recursive: true });
76
- }
77
-
78
- private async withLock<T>(operation: () => Promise<T>): Promise<T> {
79
- const lockPath = this.getLockPath();
80
- let lockHandle;
81
- const maxRetries = 100;
82
- const retryDelay = process.env.NODE_ENV === "test" ? 1 : 100;
83
- const staleThreshold = 10000;
84
-
85
- await this.ensureSessionDir();
86
-
87
- for (let i = 0; i < maxRetries; i++) {
88
- try {
89
- lockHandle = await fs.open(lockPath, "wx");
90
- break;
91
- } catch (error) {
92
- const code = (error as NodeJS.ErrnoException).code;
93
-
94
- // Only EEXIST (lock held) and EPERM (Windows pending-delete window)
95
- // are transient lock-contention errors. EACCES/ENOENT are real failures
96
- // and must not be retried as lock competition.
97
- if (code !== "EEXIST" && code !== "EPERM") {
98
- throw error;
99
- }
100
-
101
- if (i === maxRetries - 1) {
102
- throw new Error(
103
- `Could not acquire lock for task list ${this.taskListId} after ${maxRetries} retries`,
104
- );
105
- }
106
-
107
- // Stale recovery: if the lock holder crashed without releasing, the
108
- // lock file remains forever. Check mtime — if older than the threshold,
109
- // remove it. Aligns with proper-lockfile's default 10s stale detection.
110
- // The lock file is empty (no PID content), so mtime is the only signal.
111
- if (
112
- code === "EEXIST" &&
113
- (await this.isLockStale(lockPath, staleThreshold))
114
- ) {
115
- logger.warn(
116
- `TaskManager: removing stale lock for task list ${this.taskListId}`,
117
- );
118
- try {
119
- await fs.unlink(lockPath);
120
- } catch {
121
- // Another waiter may have already removed it — retry anyway
122
- }
123
- continue;
124
- }
125
-
126
- await new Promise((resolve) => setTimeout(resolve, retryDelay));
127
- }
128
- }
129
-
130
- try {
131
- return await operation();
132
- } finally {
133
- if (lockHandle) {
134
- await lockHandle.close();
135
- }
136
- try {
137
- await fs.unlink(lockPath);
138
- } catch (error) {
139
- logger.error(
140
- `Failed to release lock for task list ${this.taskListId}:`,
141
- error,
142
- );
143
- }
144
- }
145
- }
146
-
147
- private async isLockStale(
148
- lockPath: string,
149
- threshold: number,
150
- ): Promise<boolean> {
151
- try {
152
- const stats = await fs.stat(lockPath);
153
- return Date.now() - stats.mtimeMs > threshold;
154
- } catch {
155
- // Lock was removed between our EEXIST and stat — not stale, just retry
156
- return false;
157
- }
158
- }
159
-
160
- private validateTask(task: Task): void {
161
- if (!task.id || typeof task.id !== "string")
162
- throw new Error("Invalid task ID");
163
- if (!task.subject || typeof task.subject !== "string")
164
- throw new Error("Invalid task subject");
165
- if (!task.description || typeof task.description !== "string")
166
- throw new Error("Invalid task description");
167
- if (
168
- !task.status ||
169
- !["pending", "in_progress", "completed", "deleted"].includes(task.status)
170
- ) {
171
- throw new Error(`Invalid task status: ${task.status}`);
172
- }
173
- }
174
-
175
- async createTask(task: Omit<Task, "id">): Promise<string> {
176
- return await this.withLock(async () => {
177
- const taskId = await this.getNextTaskId();
178
- const fullTask: Task = { ...task, id: taskId };
179
- this.validateTask(fullTask);
180
- const taskPath = this.getTaskPath(taskId);
181
- const content = JSON.stringify(fullTask, null, 2);
182
- await fs.writeFile(taskPath, content, "utf8");
183
- this.emit("tasksChange", this.taskListId);
184
- logger.debug(`Task ${taskId} created in task list ${this.taskListId}`);
185
- return taskId;
186
- });
187
- }
188
-
189
- async getTask(taskId: string): Promise<Task | null> {
190
- const taskPath = this.getTaskPath(taskId);
191
- try {
192
- const content = await fs.readFile(taskPath, "utf8");
193
- try {
194
- return JSON.parse(content.trim()) as Task;
195
- } catch (parseError) {
196
- logger.error(`Failed to parse task file ${taskPath}:`, parseError);
197
- logger.error(`Corrupted content: ${content}`);
198
- throw parseError;
199
- }
200
- } catch (error) {
201
- if ((error as NodeJS.ErrnoException).code === "ENOENT") {
202
- return null;
203
- }
204
- throw error;
205
- }
206
- }
207
-
208
- async updateTask(task: Task): Promise<void> {
209
- this.validateTask(task);
210
- await this.withLock(async () => {
211
- const taskPath = this.getTaskPath(task.id);
212
- const content = JSON.stringify(task, null, 2);
213
- await fs.writeFile(taskPath, content, "utf8");
214
- this.emit("tasksChange", this.taskListId);
215
- logger.debug(`Task ${task.id} updated in task list ${this.taskListId}`);
216
- });
217
- }
218
-
219
- async deleteTask(taskId: string): Promise<void> {
220
- await this.withLock(async () => {
221
- const taskPath = this.getTaskPath(taskId);
222
- try {
223
- await fs.unlink(taskPath);
224
- this.emit("tasksChange", this.taskListId);
225
- logger.debug(
226
- `Task ${taskId} deleted from task list ${this.taskListId}`,
227
- );
228
- } catch (error) {
229
- if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
230
- throw error;
231
- }
232
- }
233
- });
234
- }
235
-
236
- async cleanupOldTaskLists(days: number = 30): Promise<void> {
237
- const threshold = Date.now() - days * 24 * 60 * 60 * 1000;
238
- try {
239
- const dirs = await fs.readdir(this.baseDir);
240
- for (const dir of dirs) {
241
- if (dir === this.taskListId) continue;
242
-
243
- const dirPath = join(this.baseDir, dir);
244
- const stats = await fs.stat(dirPath);
245
- if (!stats.isDirectory()) continue;
246
-
247
- // Check mtime of the directory and its contents
248
- let latestMtime = stats.mtimeMs;
249
- const files = await fs.readdir(dirPath);
250
- for (const file of files) {
251
- const filePath = join(dirPath, file);
252
- const fileStats = await fs.stat(filePath);
253
- if (fileStats.mtimeMs > latestMtime) {
254
- latestMtime = fileStats.mtimeMs;
255
- }
256
- }
257
-
258
- if (latestMtime < threshold) {
259
- logger.info(`Cleaning up old task list directory: ${dirPath}`);
260
- await fs.rm(dirPath, { recursive: true, force: true });
261
- }
262
- }
263
- } catch (error) {
264
- if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
265
- logger.error("Failed to cleanup old task lists:", error);
266
- }
267
- }
268
- }
269
-
270
- async listTasks(): Promise<Task[]> {
271
- const sessionDir = this.getSessionDir();
272
- try {
273
- const files = await fs.readdir(sessionDir);
274
- const taskFiles = files.filter((f) => f.endsWith(".json"));
275
-
276
- const tasks = await Promise.all(
277
- taskFiles.map(async (file) => {
278
- const taskPath = join(sessionDir, file);
279
- try {
280
- const content = await fs.readFile(taskPath, "utf8");
281
- return JSON.parse(content.trim()) as Task;
282
- } catch (error) {
283
- logger.error(
284
- `Failed to read or parse task file ${taskPath}:`,
285
- error,
286
- );
287
- return null;
288
- }
289
- }),
290
- );
291
-
292
- return tasks.filter((t): t is Task => t !== null).sort(byIdAsc);
293
- } catch (error) {
294
- if ((error as NodeJS.ErrnoException).code === "ENOENT") {
295
- return [];
296
- }
297
- throw error;
298
- }
299
- }
300
-
301
- async getNextTaskId(): Promise<string> {
302
- const tasks = await this.listTasks();
303
- if (tasks.length === 0) {
304
- return "1";
305
- }
306
- const ids = tasks.map((t) => parseInt(t.id, 10)).filter((id) => !isNaN(id));
307
-
308
- if (ids.length === 0) {
309
- return (tasks.length + 1).toString();
310
- }
311
-
312
- return (Math.max(...ids) + 1).toString();
313
- }
314
-
315
- /**
316
- * Refreshes the task list by re-reading tasks from disk and emitting a change event.
317
- */
318
- public async refreshTasks(): Promise<void> {
319
- this.emit("tasksChange", this.taskListId);
320
- }
321
- }
@@ -1,65 +0,0 @@
1
- /**
2
- * OpenTelemetry Event Logging
3
- *
4
- * Provides the `logOTelEvent` API for structured session lifecycle events
5
- * with PII gates.
6
- */
7
-
8
- import type { OTelEventName } from "../types/telemetry.js";
9
- import {
10
- isInitialized,
11
- getCurrentConfig,
12
- getTelemetryAttributes,
13
- } from "./instrumentation.js";
14
-
15
- interface OTelLogger {
16
- emit: (logRecord: {
17
- body?: unknown;
18
- attributes?: Record<string, unknown>;
19
- }) => void;
20
- }
21
-
22
- let cachedLogger: OTelLogger | undefined;
23
-
24
- async function getOTelLogger(): Promise<OTelLogger | undefined> {
25
- if (cachedLogger) return cachedLogger;
26
- try {
27
- const { logs } = await import("@opentelemetry/api-logs");
28
- cachedLogger = logs.getLogger("wave") as OTelLogger;
29
- return cachedLogger;
30
- } catch {
31
- return undefined;
32
- }
33
- }
34
-
35
- /**
36
- * Logs a structured event via the OTEL logs API. Respects PII gates.
37
- */
38
- export async function logOTelEvent(
39
- eventName: OTelEventName,
40
- metadata: Record<string, string | undefined>,
41
- ): Promise<void> {
42
- if (!isInitialized()) return;
43
-
44
- const log = await getOTelLogger();
45
- if (!log) return;
46
-
47
- // PII gate: strip prompt text if logUserPrompts is false
48
- const attributes: Record<string, string> = {};
49
- const config = getCurrentConfig();
50
-
51
- for (const [key, value] of Object.entries(metadata)) {
52
- if (value === undefined) continue;
53
- if (key === "prompt" && !config?.logUserPrompts) continue;
54
- attributes[key] = value;
55
- }
56
-
57
- log.emit({
58
- body: eventName,
59
- attributes: {
60
- "event.name": eventName,
61
- ...getTelemetryAttributes(),
62
- ...attributes,
63
- },
64
- });
65
- }