wave-agent-sdk 0.10.3 → 0.11.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 (136) hide show
  1. package/dist/agent.d.ts +8 -6
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +12 -9
  4. package/dist/builtin-skills/builtin-skills/loop/SKILL.md +53 -0
  5. package/dist/builtin-skills/builtin-skills/loop/parsing.ts +159 -0
  6. package/dist/builtin-skills/builtin-skills/settings/HOOKS.md +82 -0
  7. package/dist/builtin-skills/{settings → builtin-skills/settings}/SKILL.md +1 -1
  8. package/dist/builtin-skills/loop/parsing.d.ts +13 -0
  9. package/dist/builtin-skills/loop/parsing.d.ts.map +1 -0
  10. package/dist/builtin-skills/loop/parsing.js +125 -0
  11. package/dist/constants/tools.d.ts +3 -0
  12. package/dist/constants/tools.d.ts.map +1 -1
  13. package/dist/constants/tools.js +3 -0
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1 -0
  17. package/dist/managers/aiManager.d.ts +0 -2
  18. package/dist/managers/aiManager.d.ts.map +1 -1
  19. package/dist/managers/aiManager.js +53 -14
  20. package/dist/managers/cronManager.d.ts +19 -0
  21. package/dist/managers/cronManager.d.ts.map +1 -0
  22. package/dist/managers/cronManager.js +124 -0
  23. package/dist/managers/hookManager.d.ts.map +1 -1
  24. package/dist/managers/hookManager.js +21 -13
  25. package/dist/managers/liveConfigManager.js +1 -1
  26. package/dist/managers/mcpManager.d.ts +1 -1
  27. package/dist/managers/mcpManager.d.ts.map +1 -1
  28. package/dist/managers/mcpManager.js +10 -2
  29. package/dist/managers/messageManager.d.ts +0 -1
  30. package/dist/managers/messageManager.d.ts.map +1 -1
  31. package/dist/managers/permissionManager.d.ts +27 -7
  32. package/dist/managers/permissionManager.d.ts.map +1 -1
  33. package/dist/managers/permissionManager.js +119 -14
  34. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  35. package/dist/managers/slashCommandManager.js +11 -0
  36. package/dist/managers/subagentManager.d.ts +3 -0
  37. package/dist/managers/subagentManager.d.ts.map +1 -1
  38. package/dist/managers/subagentManager.js +10 -17
  39. package/dist/managers/toolManager.d.ts +1 -1
  40. package/dist/managers/toolManager.d.ts.map +1 -1
  41. package/dist/managers/toolManager.js +28 -4
  42. package/dist/services/configurationService.d.ts.map +1 -1
  43. package/dist/services/configurationService.js +8 -7
  44. package/dist/services/hook.d.ts.map +1 -1
  45. package/dist/services/hook.js +3 -10
  46. package/dist/services/initializationService.js +2 -2
  47. package/dist/services/jsonlHandler.d.ts.map +1 -1
  48. package/dist/services/jsonlHandler.js +3 -0
  49. package/dist/services/reversionService.d.ts +2 -2
  50. package/dist/services/reversionService.d.ts.map +1 -1
  51. package/dist/services/reversionService.js +3 -3
  52. package/dist/services/session.d.ts.map +1 -1
  53. package/dist/services/session.js +18 -11
  54. package/dist/tools/agentTool.js +1 -1
  55. package/dist/tools/bashTool.d.ts.map +1 -1
  56. package/dist/tools/bashTool.js +33 -12
  57. package/dist/tools/cronCreateTool.d.ts +3 -0
  58. package/dist/tools/cronCreateTool.d.ts.map +1 -0
  59. package/dist/tools/cronCreateTool.js +59 -0
  60. package/dist/tools/cronDeleteTool.d.ts +3 -0
  61. package/dist/tools/cronDeleteTool.d.ts.map +1 -0
  62. package/dist/tools/cronDeleteTool.js +38 -0
  63. package/dist/tools/cronListTool.d.ts +3 -0
  64. package/dist/tools/cronListTool.d.ts.map +1 -0
  65. package/dist/tools/cronListTool.js +30 -0
  66. package/dist/tools/readTool.d.ts.map +1 -1
  67. package/dist/tools/readTool.js +8 -32
  68. package/dist/tools/skillTool.d.ts +0 -3
  69. package/dist/tools/skillTool.d.ts.map +1 -1
  70. package/dist/tools/skillTool.js +4 -3
  71. package/dist/tools/taskOutputTool.d.ts.map +1 -1
  72. package/dist/tools/taskOutputTool.js +15 -8
  73. package/dist/tools/types.d.ts +2 -0
  74. package/dist/tools/types.d.ts.map +1 -1
  75. package/dist/types/agent.d.ts +10 -0
  76. package/dist/types/agent.d.ts.map +1 -1
  77. package/dist/types/configuration.d.ts +1 -1
  78. package/dist/types/configuration.d.ts.map +1 -1
  79. package/dist/types/cron.d.ts +10 -0
  80. package/dist/types/cron.d.ts.map +1 -0
  81. package/dist/types/cron.js +1 -0
  82. package/dist/types/hooks.d.ts +1 -5
  83. package/dist/types/hooks.d.ts.map +1 -1
  84. package/dist/types/hooks.js +1 -1
  85. package/dist/types/index.d.ts +1 -0
  86. package/dist/types/index.d.ts.map +1 -1
  87. package/dist/types/index.js +1 -0
  88. package/dist/types/messaging.d.ts +1 -1
  89. package/dist/types/messaging.d.ts.map +1 -1
  90. package/dist/utils/containerSetup.d.ts.map +1 -1
  91. package/dist/utils/containerSetup.js +40 -13
  92. package/dist/utils/mcpUtils.d.ts +2 -2
  93. package/dist/utils/mcpUtils.d.ts.map +1 -1
  94. package/dist/utils/mcpUtils.js +1 -5
  95. package/package.json +2 -1
  96. package/src/agent.ts +17 -12
  97. package/src/builtin-skills/loop/SKILL.md +53 -0
  98. package/src/builtin-skills/loop/parsing.ts +159 -0
  99. package/src/builtin-skills/settings/HOOKS.md +44 -57
  100. package/src/builtin-skills/settings/SKILL.md +1 -1
  101. package/src/constants/tools.ts +3 -0
  102. package/src/index.ts +1 -0
  103. package/src/managers/aiManager.ts +72 -24
  104. package/src/managers/cronManager.ts +167 -0
  105. package/src/managers/hookManager.ts +27 -13
  106. package/src/managers/liveConfigManager.ts +2 -2
  107. package/src/managers/mcpManager.ts +23 -2
  108. package/src/managers/messageManager.ts +0 -6
  109. package/src/managers/permissionManager.ts +154 -18
  110. package/src/managers/slashCommandManager.ts +12 -0
  111. package/src/managers/subagentManager.ts +15 -19
  112. package/src/managers/toolManager.ts +37 -4
  113. package/src/services/configurationService.ts +8 -7
  114. package/src/services/hook.ts +5 -11
  115. package/src/services/initializationService.ts +3 -3
  116. package/src/services/jsonlHandler.ts +4 -0
  117. package/src/services/reversionService.ts +9 -4
  118. package/src/services/session.ts +19 -12
  119. package/src/tools/agentTool.ts +1 -1
  120. package/src/tools/bashTool.ts +43 -14
  121. package/src/tools/cronCreateTool.ts +73 -0
  122. package/src/tools/cronDeleteTool.ts +47 -0
  123. package/src/tools/cronListTool.ts +38 -0
  124. package/src/tools/readTool.ts +11 -33
  125. package/src/tools/skillTool.ts +6 -4
  126. package/src/tools/taskOutputTool.ts +14 -8
  127. package/src/tools/types.ts +2 -0
  128. package/src/types/agent.ts +10 -0
  129. package/src/types/configuration.ts +1 -1
  130. package/src/types/cron.ts +9 -0
  131. package/src/types/hooks.ts +5 -9
  132. package/src/types/index.ts +1 -0
  133. package/src/types/messaging.ts +1 -1
  134. package/src/utils/containerSetup.ts +50 -16
  135. package/src/utils/mcpUtils.ts +2 -5
  136. package/dist/builtin-skills/settings/HOOKS.md +0 -95
@@ -67,7 +67,7 @@ The Agent tool launches specialized agents (subprocesses) that autonomously hand
67
67
  Available agent types and the tools they have access to:
68
68
  ${subagentList || "No agents configured"}
69
69
 
70
- When using the Agent tool, you must specify a subagent_type parameter to select which agent type to use.
70
+ When using the Agent tool, you must specify a subagent_type parameter to select which agent type to use from the list above. Choose the agent whose description best matches the task you want to delegate.
71
71
 
72
72
  - When doing file search, prefer to use the ${AGENT_TOOL_NAME} tool in order to reduce context usage.
73
73
  - You should proactively use the ${AGENT_TOOL_NAME} tool with specialized agents when the task at hand matches the agent's description.
@@ -1,4 +1,7 @@
1
1
  import { spawn, ChildProcess } from "child_process";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import * as os from "os";
2
5
  import { logger } from "../utils/globalLogger.js";
3
6
  import { stripAnsiColors } from "../utils/stringUtils.js";
4
7
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
@@ -15,6 +18,33 @@ import {
15
18
  const MAX_OUTPUT_LENGTH = 30000;
16
19
  const BASH_DEFAULT_TIMEOUT_MS = 120000;
17
20
 
21
+ /**
22
+ * Helper function to handle large output by truncation and persistence to a temporary file.
23
+ */
24
+ function processOutput(output: string): string {
25
+ if (output.length <= MAX_OUTPUT_LENGTH) {
26
+ return output;
27
+ }
28
+
29
+ try {
30
+ const tempDir = os.tmpdir();
31
+ const fileName = `bash_output_${Date.now()}_${Math.random().toString(36).substring(2, 11)}.txt`;
32
+ const filePath = path.join(tempDir, fileName);
33
+ fs.writeFileSync(filePath, output, "utf8");
34
+
35
+ return (
36
+ output.substring(0, MAX_OUTPUT_LENGTH) +
37
+ `\n\n... (output truncated)\nFull output persisted to: ${filePath}`
38
+ );
39
+ } catch (error) {
40
+ logger.error("Failed to persist large bash output:", error);
41
+ return (
42
+ output.substring(0, MAX_OUTPUT_LENGTH) +
43
+ "\n\n... (output truncated, failed to persist full output)"
44
+ );
45
+ }
46
+ }
47
+
18
48
  /**
19
49
  * Bash command execution tool - supports both foreground and background execution
20
50
  */
@@ -75,7 +105,7 @@ Usage notes:
75
105
  - The command argument is required.
76
106
  - You can specify an optional timeout in milliseconds (up to ${BASH_DEFAULT_TIMEOUT_MS}ms / ${BASH_DEFAULT_TIMEOUT_MS / 60000} minutes). If not specified, commands will timeout after ${BASH_DEFAULT_TIMEOUT_MS}ms (${BASH_DEFAULT_TIMEOUT_MS / 60000} minutes).
77
107
  - It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
78
- - If the output exceeds ${MAX_OUTPUT_LENGTH} characters, output will be truncated before being returned to you.
108
+ - If the output exceeds ${MAX_OUTPUT_LENGTH} characters, output will be truncated and the full output will be persisted to a temporary file.
79
109
  - You can use the \`run_in_background\` parameter to run the command in the background, which allows you to continue working while the command runs. You can monitor the output using the ${BASH_TOOL_NAME} tool as it becomes available. You do not need to use '&' at the end of the command when using this parameter.
80
110
  - Avoid using ${BASH_TOOL_NAME} with the \`find\`, \`sed\`, \`awk\`, or \`echo\` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:
81
111
  - File search: Use ${GLOB_TOOL_NAME} (NOT find or ls)
@@ -292,7 +322,9 @@ Usage notes:
292
322
 
293
323
  resolve({
294
324
  success: false,
295
- content: outputBuffer + (errorBuffer ? "\n" + errorBuffer : ""),
325
+ content: processOutput(
326
+ outputBuffer + (errorBuffer ? "\n" + errorBuffer : ""),
327
+ ),
296
328
  error: reason,
297
329
  });
298
330
  }
@@ -340,20 +372,17 @@ Usage notes:
340
372
  const combinedOutput =
341
373
  outputBuffer + (errorBuffer ? "\n" + errorBuffer : "");
342
374
 
343
- // Handle large output by truncation if needed
375
+ // Handle large output by truncation and persistence if needed
344
376
  const finalOutput =
345
377
  combinedOutput || `Command executed with exit code: ${exitCode}`;
346
- const content =
347
- finalOutput.length > MAX_OUTPUT_LENGTH
348
- ? finalOutput.substring(0, MAX_OUTPUT_LENGTH) +
349
- "\n\n... (output truncated)"
350
- : finalOutput;
351
-
352
- const shortResult = combinedOutput
353
- .trim()
354
- .split("\n")
355
- .slice(-3)
356
- .join("\n");
378
+ const content = processOutput(finalOutput);
379
+
380
+ const lines = combinedOutput.trim().split("\n");
381
+ const shortResult =
382
+ lines.length <= 3
383
+ ? lines.join("\n")
384
+ : lines.slice(0, 3).join("\n") +
385
+ `\n... +${lines.length - 3} lines`;
357
386
 
358
387
  resolve({
359
388
  success: exitCode === 0,
@@ -0,0 +1,73 @@
1
+ import { ToolPlugin, ToolResult, ToolContext } from "./types.js";
2
+ import { CRON_CREATE_TOOL_NAME } from "../constants/tools.js";
3
+
4
+ export const cronCreateTool: ToolPlugin = {
5
+ name: CRON_CREATE_TOOL_NAME,
6
+ config: {
7
+ type: "function",
8
+ function: {
9
+ name: CRON_CREATE_TOOL_NAME,
10
+ description:
11
+ "Schedule a prompt to be enqueued at a future time. Use for both recurring schedules and one-shot reminders.",
12
+ parameters: {
13
+ type: "object",
14
+ properties: {
15
+ cron: {
16
+ type: "string",
17
+ description:
18
+ 'Standard 5-field cron expression in local time: "M H DoM Mon DoW"',
19
+ },
20
+ prompt: {
21
+ type: "string",
22
+ description: "The prompt to enqueue at each fire time",
23
+ },
24
+ recurring: {
25
+ type: "boolean",
26
+ description:
27
+ "Default: true. true = fire on every cron match until deleted or auto-expired after 7 days. false = fire once at the next match, then auto-delete",
28
+ default: true,
29
+ },
30
+ },
31
+ required: ["cron", "prompt"],
32
+ },
33
+ },
34
+ },
35
+ execute: async (
36
+ args: Record<string, unknown>,
37
+ context: ToolContext,
38
+ ): Promise<ToolResult> => {
39
+ const {
40
+ cron,
41
+ prompt,
42
+ recurring = true,
43
+ } = args as { cron: string; prompt: string; recurring?: boolean };
44
+
45
+ if (!context.cronManager) {
46
+ return {
47
+ success: false,
48
+ content: "",
49
+ error: "CronManager not available",
50
+ };
51
+ }
52
+
53
+ try {
54
+ const job = context.cronManager.createJob({
55
+ cron,
56
+ prompt,
57
+ recurring,
58
+ });
59
+
60
+ return {
61
+ success: true,
62
+ content: JSON.stringify({ id: job.id }, null, 2),
63
+ shortResult: `Scheduled job ${job.id}`,
64
+ };
65
+ } catch (error) {
66
+ return {
67
+ success: false,
68
+ content: "",
69
+ error: error instanceof Error ? error.message : String(error),
70
+ };
71
+ }
72
+ },
73
+ };
@@ -0,0 +1,47 @@
1
+ import { ToolPlugin, ToolResult, ToolContext } from "./types.js";
2
+ import { CRON_DELETE_TOOL_NAME } from "../constants/tools.js";
3
+
4
+ export const cronDeleteTool: ToolPlugin = {
5
+ name: CRON_DELETE_TOOL_NAME,
6
+ config: {
7
+ type: "function",
8
+ function: {
9
+ name: CRON_DELETE_TOOL_NAME,
10
+ description:
11
+ "Cancel a cron job previously scheduled with CronCreate. Removes it from the in-memory session store.",
12
+ parameters: {
13
+ type: "object",
14
+ properties: {
15
+ id: {
16
+ type: "string",
17
+ description: "Job ID returned by CronCreate",
18
+ },
19
+ },
20
+ required: ["id"],
21
+ },
22
+ },
23
+ },
24
+ execute: async (
25
+ args: Record<string, unknown>,
26
+ context: ToolContext,
27
+ ): Promise<ToolResult> => {
28
+ const { id } = args as { id: string };
29
+
30
+ if (!context.cronManager) {
31
+ return {
32
+ success: false,
33
+ content: "",
34
+ error: "CronManager not available",
35
+ };
36
+ }
37
+
38
+ const success = context.cronManager.deleteJob(id);
39
+
40
+ return {
41
+ success,
42
+ content: JSON.stringify({ success }, null, 2),
43
+ shortResult: success ? `Deleted job ${id}` : `Job ${id} not found`,
44
+ error: success ? undefined : `Job ${id} not found`,
45
+ };
46
+ },
47
+ };
@@ -0,0 +1,38 @@
1
+ import { ToolPlugin, ToolResult, ToolContext } from "./types.js";
2
+ import { CRON_LIST_TOOL_NAME } from "../constants/tools.js";
3
+
4
+ export const cronListTool: ToolPlugin = {
5
+ name: CRON_LIST_TOOL_NAME,
6
+ config: {
7
+ type: "function",
8
+ function: {
9
+ name: CRON_LIST_TOOL_NAME,
10
+ description:
11
+ "List all cron jobs scheduled via CronCreate in this session.",
12
+ parameters: {
13
+ type: "object",
14
+ properties: {},
15
+ },
16
+ },
17
+ },
18
+ execute: async (
19
+ _args: Record<string, unknown>,
20
+ context: ToolContext,
21
+ ): Promise<ToolResult> => {
22
+ if (!context.cronManager) {
23
+ return {
24
+ success: false,
25
+ content: "",
26
+ error: "CronManager not available",
27
+ };
28
+ }
29
+
30
+ const jobs = context.cronManager.listJobs();
31
+
32
+ return {
33
+ success: true,
34
+ content: JSON.stringify({ jobs }, null, 2),
35
+ shortResult: `Found ${jobs.length} jobs`,
36
+ };
37
+ },
38
+ };
@@ -243,31 +243,19 @@ Usage:
243
243
  };
244
244
  }
245
245
 
246
- // Check content size limit (100KB)
247
- const MAX_CONTENT_SIZE = 100 * 1024; // 100KB
248
- let contentToProcess = fileContent;
249
- let contentTruncated = false;
250
-
251
- if (fileContent.length > MAX_CONTENT_SIZE) {
252
- contentToProcess = fileContent.substring(0, MAX_CONTENT_SIZE);
253
- contentTruncated = true;
254
- }
255
-
256
- const lines = contentToProcess.split("\n");
257
- const totalLines = lines.length;
258
- const originalTotalLines = fileContent.split("\n").length;
246
+ const allLines = fileContent.split("\n");
247
+ const totalLines = allLines.length;
259
248
 
260
249
  // Handle offset and limit
261
250
  let startLine = 1;
262
- let endLine = Math.min(totalLines, 2000); // Default maximum read 2000 lines
263
-
264
251
  if (typeof offset === "number") {
265
252
  startLine = Math.max(1, offset);
266
253
  }
267
254
 
268
- if (typeof limit === "number") {
269
- endLine = Math.min(totalLines, startLine + limit - 1);
270
- }
255
+ let endLine = Math.min(
256
+ totalLines,
257
+ startLine + (typeof limit === "number" ? limit : 2000) - 1,
258
+ );
271
259
 
272
260
  // If no offset and limit specified, read entire file (maximum 2000 lines)
273
261
  if (typeof offset !== "number" && typeof limit !== "number") {
@@ -285,7 +273,7 @@ Usage:
285
273
  }
286
274
 
287
275
  // Extract specified line range
288
- const selectedLines = lines.slice(startLine - 1, endLine);
276
+ const selectedLines = allLines.slice(startLine - 1, endLine);
289
277
 
290
278
  // Format output (cat -n format, with line numbers)
291
279
  const formattedContent = selectedLines
@@ -300,10 +288,7 @@ Usage:
300
288
 
301
289
  // Add file information header
302
290
  let content = `File: ${filePath}\n`;
303
- if (contentTruncated) {
304
- content += `Content truncated at ${MAX_CONTENT_SIZE} bytes\n`;
305
- content += `Lines ${startLine}-${endLine} of ${totalLines} (original file: ${originalTotalLines} lines)\n`;
306
- } else if (startLine > 1 || endLine < totalLines) {
291
+ if (startLine > 1 || endLine < totalLines) {
307
292
  content += `Lines ${startLine}-${endLine} of ${totalLines}\n`;
308
293
  } else {
309
294
  content += `Total lines: ${totalLines}\n`;
@@ -312,22 +297,15 @@ Usage:
312
297
  content += formattedContent;
313
298
 
314
299
  // If only showing partial content, add prompt
315
- if (endLine < totalLines || contentTruncated) {
300
+ if (endLine < totalLines) {
316
301
  content += `\n${"─".repeat(50)}\n`;
317
- if (contentTruncated) {
318
- content += `... content truncated due to size limit (${MAX_CONTENT_SIZE} bytes)`;
319
- if (endLine < totalLines) {
320
- content += ` and ${totalLines - endLine} more lines not shown`;
321
- }
322
- } else {
323
- content += `... ${totalLines - endLine} more lines not shown`;
324
- }
302
+ content += `... ${totalLines - endLine} more lines not shown`;
325
303
  }
326
304
 
327
305
  return {
328
306
  success: true,
329
307
  content,
330
- shortResult: `Read ${selectedLines.length} lines${totalLines > 2000 || contentTruncated ? " (truncated)" : ""}`,
308
+ shortResult: `Read ${selectedLines.length} lines${totalLines > 2000 ? " (truncated)" : ""}`,
331
309
  };
332
310
  } catch (error) {
333
311
  return {
@@ -11,14 +11,16 @@ import {
11
11
  /**
12
12
  * Skill tool plugin for invoking Wave skills
13
13
  */
14
+ const SKILL_TOOL_DESCRIPTION =
15
+ "Execute a skill within the main conversation. When users ask you to perform tasks, check if any of the available skills match. Skills provide specialized capabilities and domain knowledge.";
16
+
14
17
  export const skillTool: ToolPlugin = {
15
18
  name: SKILL_TOOL_NAME,
16
19
  config: {
17
20
  type: "function" as const,
18
21
  function: {
19
22
  name: SKILL_TOOL_NAME,
20
- description:
21
- "Invoke a Wave skill by name. Skills are user-defined automation templates that can be personal or project-specific.",
23
+ description: SKILL_TOOL_DESCRIPTION,
22
24
  parameters: {
23
25
  type: "object",
24
26
  properties: {
@@ -41,7 +43,7 @@ export const skillTool: ToolPlugin = {
41
43
  (skill) => !skill.disableModelInvocation,
42
44
  );
43
45
  if (!availableSkills || availableSkills.length === 0) {
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.";
46
+ return `${SKILL_TOOL_DESCRIPTION} No skills are currently available.`;
45
47
  }
46
48
 
47
49
  const skillList = availableSkills
@@ -50,7 +52,7 @@ export const skillTool: ToolPlugin = {
50
52
  )
51
53
  .join("\n");
52
54
 
53
- return `Invoke a Wave skill by name. Skills are user-defined automation templates that can be personal or project-specific.\n\nAvailable skills:\n${skillList}`;
55
+ return `${SKILL_TOOL_DESCRIPTION} Do not invoke the same skill repeatedly if it has already been called with the same arguments.\n\nAvailable skills:\n${skillList}`;
54
56
  },
55
57
 
56
58
  execute: async (
@@ -31,7 +31,7 @@ export const taskOutputTool: ToolPlugin = {
31
31
  description: "Max wait time in ms",
32
32
  },
33
33
  },
34
- required: ["task_id"],
34
+ required: ["task_id", "block", "timeout"],
35
35
  },
36
36
  },
37
37
  },
@@ -87,8 +87,8 @@ export const taskOutputTool: ToolPlugin = {
87
87
 
88
88
  if (finalContent.length > MAX_OUTPUT_LENGTH) {
89
89
  processedContent =
90
- finalContent.substring(0, MAX_OUTPUT_LENGTH) +
91
- "\n\n... (output truncated)";
90
+ "\n\n... (output truncated)\n" +
91
+ finalContent.substring(finalContent.length - MAX_OUTPUT_LENGTH);
92
92
  isTruncated = true;
93
93
  }
94
94
 
@@ -155,11 +155,17 @@ export const taskOutputTool: ToolPlugin = {
155
155
  if (context.abortSignal) {
156
156
  context.abortSignal.removeEventListener("abort", onAbort);
157
157
  }
158
- resolve({
159
- success: true,
160
- content: "Retrieval timed out",
161
- shortResult: `${taskId}: timeout`,
162
- });
158
+ const result = getResult();
159
+ if (result) {
160
+ result.shortResult = `${taskId}: timeout`;
161
+ resolve(result);
162
+ } else {
163
+ resolve({
164
+ success: true,
165
+ content: "Retrieval timed out",
166
+ shortResult: `${taskId}: timeout`,
167
+ });
168
+ }
163
169
  return;
164
170
  }
165
171
 
@@ -79,6 +79,8 @@ export interface ToolContext {
79
79
  subagentManager?: import("../managers/subagentManager.js").SubagentManager;
80
80
  /** Skill manager instance for skill invocation */
81
81
  skillManager?: import("../managers/skillManager.js").SkillManager;
82
+ /** Cron manager instance for scheduling tasks */
83
+ cronManager?: import("../managers/cronManager.js").CronManager;
82
84
  /** Current session ID */
83
85
  sessionId?: string;
84
86
  /** The ID of the current tool call */
@@ -67,6 +67,16 @@ export interface AgentOptions {
67
67
  isNewWorktree?: boolean;
68
68
  /**Whether to watch for skill changes - defaults to true */
69
69
  watchSkills?: boolean;
70
+ /**
71
+ * Optional list of tool names to always allow.
72
+ * These rules follow the standard permission rule syntax: `ToolName` or `ToolName(pattern)`.
73
+ */
74
+ allowedTools?: string[];
75
+ /**
76
+ * Optional list of tool names to always disallow.
77
+ * These rules follow the standard permission rule syntax: `ToolName` or `ToolName(pattern)`.
78
+ */
79
+ disallowedTools?: string[];
70
80
  }
71
81
 
72
82
  export interface AgentCallbacks
@@ -21,7 +21,7 @@ export interface WaveConfiguration {
21
21
  permissions?: {
22
22
  allow?: string[];
23
23
  deny?: string[];
24
- defaultMode?: PermissionMode; // Default permission mode for restricted tools
24
+ permissionMode?: PermissionMode; // Default permission mode for restricted tools
25
25
  /**
26
26
  * List of directories that are considered part of the Safe Zone.
27
27
  * File operations within these directories can be auto-accepted.
@@ -0,0 +1,9 @@
1
+ export interface CronJob {
2
+ id: string;
3
+ cron: string;
4
+ prompt: string;
5
+ recurring: boolean;
6
+ createdAt: number;
7
+ nextRun: number;
8
+ periodMs: number;
9
+ }
@@ -19,7 +19,7 @@ export type HookEvent =
19
19
  | "UserPromptSubmit"
20
20
  | "Stop"
21
21
  | "SubagentStop"
22
- | "Notification"
22
+ | "PermissionRequest"
23
23
  | "WorktreeCreate";
24
24
 
25
25
  // Individual hook command configuration
@@ -100,7 +100,7 @@ export function isValidHookEvent(event: string): event is HookEvent {
100
100
  "UserPromptSubmit",
101
101
  "Stop",
102
102
  "SubagentStop",
103
- "Notification",
103
+ "PermissionRequest",
104
104
  "WorktreeCreate",
105
105
  ].includes(event);
106
106
  }
@@ -154,16 +154,14 @@ export interface HookJsonInput {
154
154
  session_id: string; // Format: "wave_session_{uuid}_{shortId}"
155
155
  transcript_path: string; // Format: "~/.wave/sessions/session_{shortId}.json"
156
156
  cwd: string; // Absolute path to current working directory
157
- hook_event_name: HookEvent; // "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop" | "SubagentStop" | "Notification"
157
+ hook_event_name: HookEvent; // "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop" | "SubagentStop" | "PermissionRequest" | "WorktreeCreate"
158
158
 
159
159
  // Optional fields based on event type
160
- tool_name?: string; // Present for PreToolUse, PostToolUse
161
- tool_input?: unknown; // Present for PreToolUse, PostToolUse
160
+ tool_name?: string; // Present for PreToolUse, PostToolUse, PermissionRequest
161
+ tool_input?: unknown; // Present for PreToolUse, PostToolUse, PermissionRequest
162
162
  tool_response?: unknown; // Present for PostToolUse only
163
163
  user_prompt?: string; // Present for UserPromptSubmit only
164
164
  subagent_type?: string; // Present when hook is executed by a subagent
165
- message?: string; // Present for Notification events
166
- notification_type?: string; // Present for Notification events
167
165
  name?: string; // Present for WorktreeCreate events
168
166
  }
169
167
 
@@ -177,8 +175,6 @@ export interface ExtendedHookExecutionContext extends HookExecutionContext {
177
175
  env?: Record<string, string>; // Additional environment variables (from configuration)
178
176
  userPrompt?: string; // User prompt text (UserPromptSubmit only)
179
177
  subagentType?: string; // Subagent type when hook is executed by a subagent
180
- message?: string; // Notification message (Notification only)
181
- notificationType?: string; // Notification type (Notification only)
182
178
  worktreeName?: string; // Worktree name (WorktreeCreate only)
183
179
  }
184
180
 
@@ -35,3 +35,4 @@ export * from "./memoryRule.js";
35
35
  export * from "./history.js";
36
36
  export * from "./tasks.js";
37
37
  export * from "./agent.js";
38
+ export * from "./cron.js";
@@ -11,7 +11,7 @@ export enum MessageSource {
11
11
  }
12
12
 
13
13
  export interface Message {
14
- id?: string; // Unique identifier for the message
14
+ id: string; // Unique identifier for the 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)