wave-agent-sdk 0.14.1 → 0.14.3

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 (92) hide show
  1. package/builtin/skills/settings/HOOKS.md +69 -0
  2. package/builtin/skills/settings/PLUGINS.md +171 -0
  3. package/builtin/skills/settings/SKILL.md +8 -3
  4. package/builtin/skills/settings/SUBAGENTS.md +21 -2
  5. package/dist/agent.d.ts +2 -2
  6. package/dist/agent.d.ts.map +1 -1
  7. package/dist/agent.js +12 -3
  8. package/dist/managers/aiManager.d.ts +6 -6
  9. package/dist/managers/aiManager.d.ts.map +1 -1
  10. package/dist/managers/aiManager.js +122 -59
  11. package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
  12. package/dist/managers/backgroundTaskManager.js +28 -18
  13. package/dist/managers/hookManager.d.ts +16 -1
  14. package/dist/managers/hookManager.d.ts.map +1 -1
  15. package/dist/managers/hookManager.js +97 -8
  16. package/dist/managers/messageManager.d.ts +19 -4
  17. package/dist/managers/messageManager.d.ts.map +1 -1
  18. package/dist/managers/messageManager.js +63 -18
  19. package/dist/managers/pluginManager.d.ts +1 -0
  20. package/dist/managers/pluginManager.d.ts.map +1 -1
  21. package/dist/managers/pluginManager.js +7 -0
  22. package/dist/managers/subagentManager.d.ts +5 -0
  23. package/dist/managers/subagentManager.d.ts.map +1 -1
  24. package/dist/managers/subagentManager.js +35 -0
  25. package/dist/prompts/index.d.ts +1 -1
  26. package/dist/prompts/index.d.ts.map +1 -1
  27. package/dist/prompts/index.js +1 -1
  28. package/dist/services/MarketplaceService.d.ts +0 -11
  29. package/dist/services/MarketplaceService.d.ts.map +1 -1
  30. package/dist/services/MarketplaceService.js +21 -89
  31. package/dist/services/aiService.d.ts +3 -3
  32. package/dist/services/aiService.d.ts.map +1 -1
  33. package/dist/services/aiService.js +7 -7
  34. package/dist/services/hook.d.ts.map +1 -1
  35. package/dist/services/hook.js +15 -0
  36. package/dist/services/initializationService.d.ts.map +1 -1
  37. package/dist/services/initializationService.js +24 -1
  38. package/dist/services/interactionService.js +1 -1
  39. package/dist/services/pluginLoader.d.ts +5 -6
  40. package/dist/services/pluginLoader.d.ts.map +1 -1
  41. package/dist/services/pluginLoader.js +43 -53
  42. package/dist/services/session.d.ts +1 -1
  43. package/dist/services/session.js +7 -7
  44. package/dist/services/taskManager.d.ts +1 -1
  45. package/dist/services/taskManager.js +1 -1
  46. package/dist/types/core.d.ts +1 -1
  47. package/dist/types/core.d.ts.map +1 -1
  48. package/dist/types/hooks.d.ts +9 -1
  49. package/dist/types/hooks.d.ts.map +1 -1
  50. package/dist/types/hooks.js +2 -0
  51. package/dist/types/marketplace.d.ts +1 -26
  52. package/dist/types/marketplace.d.ts.map +1 -1
  53. package/dist/types/messaging.d.ts +3 -3
  54. package/dist/types/messaging.d.ts.map +1 -1
  55. package/dist/types/plugins.d.ts +3 -13
  56. package/dist/types/plugins.d.ts.map +1 -1
  57. package/dist/utils/convertMessagesForAPI.d.ts +1 -1
  58. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  59. package/dist/utils/convertMessagesForAPI.js +18 -7
  60. package/dist/utils/groupMessagesByApiRound.d.ts +1 -1
  61. package/dist/utils/groupMessagesByApiRound.js +6 -6
  62. package/dist/utils/messageOperations.d.ts.map +1 -1
  63. package/dist/utils/messageOperations.js +3 -3
  64. package/dist/utils/subagentParser.d.ts +8 -1
  65. package/dist/utils/subagentParser.d.ts.map +1 -1
  66. package/dist/utils/subagentParser.js +18 -3
  67. package/package.json +1 -1
  68. package/src/agent.ts +16 -3
  69. package/src/managers/aiManager.ts +142 -63
  70. package/src/managers/backgroundTaskManager.ts +32 -22
  71. package/src/managers/hookManager.ts +125 -10
  72. package/src/managers/messageManager.ts +76 -22
  73. package/src/managers/pluginManager.ts +10 -0
  74. package/src/managers/subagentManager.ts +47 -0
  75. package/src/prompts/index.ts +1 -1
  76. package/src/services/MarketplaceService.ts +26 -127
  77. package/src/services/aiService.ts +11 -11
  78. package/src/services/hook.ts +17 -0
  79. package/src/services/initializationService.ts +33 -1
  80. package/src/services/interactionService.ts +1 -1
  81. package/src/services/pluginLoader.ts +51 -67
  82. package/src/services/session.ts +7 -7
  83. package/src/services/taskManager.ts +1 -1
  84. package/src/types/core.ts +1 -1
  85. package/src/types/hooks.ts +16 -2
  86. package/src/types/marketplace.ts +1 -24
  87. package/src/types/messaging.ts +3 -3
  88. package/src/types/plugins.ts +3 -13
  89. package/src/utils/convertMessagesForAPI.ts +24 -9
  90. package/src/utils/groupMessagesByApiRound.ts +6 -6
  91. package/src/utils/messageOperations.ts +3 -5
  92. package/src/utils/subagentParser.ts +31 -4
@@ -7,24 +7,8 @@ export interface MarketplaceOwner {
7
7
 
8
8
  export interface MarketplacePluginEntry {
9
9
  name: string;
10
- source: string | MarketplaceSource;
10
+ source: string;
11
11
  description: string;
12
- /** Claude Code compatibility: plugin category */
13
- category?: string;
14
- /** Claude Code compatibility: plugin tags */
15
- tags?: string[];
16
- /** Claude Code compatibility: when false, plugin.json is optional */
17
- strict?: boolean;
18
- /** Claude Code compatibility: inline manifest fields */
19
- version?: string;
20
- author?: { name: string; url?: string };
21
- homepage?: string;
22
- repository?: string;
23
- license?: string;
24
- keywords?: string[];
25
- commands?: string;
26
- skills?: string;
27
- agents?: string;
28
12
  }
29
13
 
30
14
  export interface MarketplacePluginStatus extends MarketplacePluginEntry {
@@ -40,8 +24,6 @@ export interface MarketplaceManifest {
40
24
  name: string;
41
25
  owner: MarketplaceOwner;
42
26
  plugins: MarketplacePluginEntry[];
43
- /** Claude Code compatibility: additional metadata */
44
- metadata?: Record<string, unknown>;
45
27
  }
46
28
 
47
29
  export type MarketplaceSource =
@@ -58,11 +40,6 @@ export type MarketplaceSource =
58
40
  source: "git";
59
41
  url: string;
60
42
  ref?: string;
61
- }
62
- | {
63
- source: "url";
64
- url: string;
65
- ref?: string;
66
43
  };
67
44
 
68
45
  export interface KnownMarketplace {
@@ -25,7 +25,7 @@ export type MessageBlock =
25
25
  | ToolBlock
26
26
  | ImageBlock
27
27
  | BangBlock
28
- | CompressBlock
28
+ | CompactBlock
29
29
  | ReasoningBlock
30
30
  | FileHistoryBlock
31
31
  | TaskNotificationBlock;
@@ -85,8 +85,8 @@ export interface BangBlock {
85
85
  exitCode: number | null;
86
86
  }
87
87
 
88
- export interface CompressBlock {
89
- type: "compress";
88
+ export interface CompactBlock {
89
+ type: "compact";
90
90
  content: string;
91
91
  sessionId: string;
92
92
  }
@@ -3,9 +3,10 @@ import { Skill } from "./skills.js";
3
3
  import { LspConfig } from "./lsp.js";
4
4
  import { McpConfig } from "./mcp.js";
5
5
  import { PartialHookConfiguration } from "./configuration.js";
6
+ import { SubagentConfiguration } from "../utils/subagentParser.js";
6
7
 
7
8
  /**
8
- * Plugin manifest structure (.wave-plugin/plugin.json or .claude-plugin/plugin.json)
9
+ * Plugin manifest structure (.wave-plugin/plugin.json)
9
10
  */
10
11
  export interface PluginManifest {
11
12
  name: string;
@@ -14,18 +15,6 @@ export interface PluginManifest {
14
15
  author?: {
15
16
  name: string;
16
17
  };
17
- /** Claude Code compatibility: plugin keywords */
18
- keywords?: string[];
19
- /** Claude Code compatibility: plugin homepage URL */
20
- homepage?: string;
21
- /** Claude Code compatibility: repository info */
22
- repository?: string;
23
- /** Claude Code compatibility: license info */
24
- license?: string;
25
- /** Claude Code compatibility: plugin dependencies */
26
- dependencies?: Record<string, string>;
27
- /** Claude Code compatibility: user configuration schema */
28
- userConfig?: Record<string, unknown>;
29
18
  }
30
19
 
31
20
  /**
@@ -43,6 +32,7 @@ export interface Plugin extends PluginManifest {
43
32
  path: string;
44
33
  commands: CustomSlashCommand[];
45
34
  skills: Skill[];
35
+ agents: SubagentConfiguration[];
46
36
  lspConfig?: LspConfig;
47
37
  mcpConfig?: McpConfig;
48
38
  hooksConfig?: PartialHookConfiguration;
@@ -33,7 +33,7 @@ function safeToolArguments(args: string): string {
33
33
  }
34
34
 
35
35
  /**
36
- * Convert message format to API call format, stopping when a compressed message is encountered.
36
+ * Convert message format to API call format, stopping when a compacted message is encountered.
37
37
  * Messages with no meaningful content or tool calls are filtered out.
38
38
  * @param messages Message list
39
39
  * @returns Converted API message format list
@@ -47,19 +47,19 @@ export function convertMessagesForAPI(
47
47
  for (let i = startIndex; i >= 0; i--) {
48
48
  const message = messages[i];
49
49
 
50
- // Check if a compression block is encountered, if so, stop iteration
50
+ // Check if a compaction block is encountered, if so, stop iteration
51
51
  if (
52
52
  message.role === "assistant" &&
53
- message.blocks.some((block) => block.type === "compress")
53
+ message.blocks.some((block) => block.type === "compact")
54
54
  ) {
55
- // Add the content of the compression block as an assistant message to the history
56
- const compressBlock = message.blocks.find(
57
- (block) => block.type === "compress",
55
+ // Add the content of the compaction block as an assistant message to the history
56
+ const compactBlock = message.blocks.find(
57
+ (block) => block.type === "compact",
58
58
  );
59
- if (compressBlock && compressBlock.type === "compress") {
59
+ if (compactBlock && compactBlock.type === "compact") {
60
60
  recentMessages.unshift({
61
61
  role: "user",
62
- content: compressBlock.content,
62
+ content: compactBlock.content,
63
63
  });
64
64
  }
65
65
  break;
@@ -145,6 +145,20 @@ export function convertMessagesForAPI(
145
145
  .join("\n");
146
146
  }
147
147
 
148
+ // Extract reasoning content from reasoning blocks
149
+ const reasoningBlocks = message.blocks.filter(
150
+ (block) =>
151
+ block.type === "reasoning" &&
152
+ block.content &&
153
+ block.content.trim().length > 0,
154
+ );
155
+ let reasoning_content: string | undefined;
156
+ if (reasoningBlocks.length > 0) {
157
+ reasoning_content = reasoningBlocks
158
+ .map((block) => (block.type === "reasoning" ? block.content : ""))
159
+ .join("\n");
160
+ }
161
+
148
162
  // Construct tool calls from tool blocks
149
163
  if (toolBlocks.length > 0) {
150
164
  tool_calls = toolBlocks
@@ -176,8 +190,9 @@ export function convertMessagesForAPI(
176
190
  role: "assistant",
177
191
  content: hasContent ? content : undefined,
178
192
  tool_calls,
193
+ ...(reasoning_content ? { reasoning_content } : {}),
179
194
  ...(message.additionalFields ? { ...message.additionalFields } : {}),
180
- };
195
+ } as ChatCompletionMessageParam;
181
196
 
182
197
  recentMessages.unshift(assistantMessage);
183
198
  }
@@ -14,7 +14,7 @@ export interface ApiRound {
14
14
  * Boundaries:
15
15
  * - A new `role: "user"` message starts a new round.
16
16
  * - A new `role: "assistant"` message with a different `id` starts a new round.
17
- * - A message with a `compress` block is pushed as its own round and starts a
17
+ * - A message with a `compact` block is pushed as its own round and starts a
18
18
  * new round after it.
19
19
  */
20
20
  export function groupMessagesByApiRound(messages: Message[]): ApiRound[] {
@@ -28,9 +28,9 @@ export function groupMessagesByApiRound(messages: Message[]): ApiRound[] {
28
28
  if (msg.role === "user") {
29
29
  startNewRound = true;
30
30
  } else if (msg.role === "assistant") {
31
- // Compress block is always its own round
32
- const hasCompress = msg.blocks.some((b) => b.type === "compress");
33
- if (hasCompress) {
31
+ // Compact block is always its own round
32
+ const hasCompact = msg.blocks.some((b) => b.type === "compact");
33
+ if (hasCompact) {
34
34
  startNewRound = true;
35
35
  } else if (msg.id !== lastAssistantId) {
36
36
  // New assistant id starts a new round.
@@ -58,10 +58,10 @@ export function groupMessagesByApiRound(messages: Message[]): ApiRound[] {
58
58
 
59
59
  currentRound.push(msg);
60
60
 
61
- // After pushing a compress message as its own round, flush immediately
61
+ // After pushing a compact message as its own round, flush immediately
62
62
  if (
63
63
  msg.role === "assistant" &&
64
- msg.blocks.some((b) => b.type === "compress")
64
+ msg.blocks.some((b) => b.type === "compact")
65
65
  ) {
66
66
  rounds.push({
67
67
  messages: currentRound,
@@ -582,11 +582,9 @@ export function getMessageContent(message: Message): string {
582
582
  return `!${bangBlock.command}`;
583
583
  }
584
584
 
585
- const compressBlock = message.blocks.find(
586
- (block) => block.type === "compress",
587
- );
588
- if (compressBlock && "content" in compressBlock) {
589
- return compressBlock.content;
585
+ const compactBlock = message.blocks.find((block) => block.type === "compact");
586
+ if (compactBlock && "content" in compactBlock) {
587
+ return compactBlock.content;
590
588
  }
591
589
 
592
590
  return "";
@@ -10,8 +10,10 @@ export interface SubagentConfiguration {
10
10
  model?: string;
11
11
  systemPrompt: string;
12
12
  filePath: string;
13
- scope: "project" | "user" | "builtin";
13
+ scope: "project" | "user" | "builtin" | "plugin";
14
14
  priority: number;
15
+ /** Plugin root directory path, set when scope is "plugin" */
16
+ pluginRoot?: string;
15
17
  }
16
18
 
17
19
  interface SubagentFrontmatter {
@@ -119,11 +121,12 @@ function validateConfiguration(
119
121
  }
120
122
 
121
123
  /**
122
- * Parse a single subagent markdown file
124
+ * Parse a single subagent markdown file with optional pluginRoot support
123
125
  */
124
126
  function parseSubagentFile(
125
127
  filePath: string,
126
- scope: "project" | "user" | "builtin",
128
+ scope: "project" | "user" | "builtin" | "plugin",
129
+ pluginRoot?: string,
127
130
  ): SubagentConfiguration {
128
131
  try {
129
132
  const content = readFileSync(filePath, "utf-8");
@@ -143,16 +146,28 @@ function parseSubagentFile(
143
146
  let priority = 1;
144
147
  if (scope === "user") priority = 2;
145
148
  if (scope === "builtin") priority = 3;
149
+ if (scope === "plugin") priority = 2; // Same priority as user-level
150
+
151
+ let systemPrompt = body;
152
+
153
+ // Substitute ${WAVE_PLUGIN_ROOT} for plugin scope at parse time
154
+ if (scope === "plugin" && pluginRoot) {
155
+ systemPrompt = systemPrompt.replace(
156
+ /\$\{WAVE_PLUGIN_ROOT\}/g,
157
+ pluginRoot,
158
+ );
159
+ }
146
160
 
147
161
  return {
148
162
  name: frontmatter.name!,
149
163
  description: frontmatter.description!,
150
164
  tools: frontmatter.tools,
151
165
  model: frontmatter.model,
152
- systemPrompt: body,
166
+ systemPrompt,
153
167
  filePath,
154
168
  scope,
155
169
  priority,
170
+ pluginRoot: scope === "plugin" ? pluginRoot : undefined,
156
171
  };
157
172
  } catch (error) {
158
173
  throw new Error(
@@ -161,6 +176,18 @@ function parseSubagentFile(
161
176
  }
162
177
  }
163
178
 
179
+ /**
180
+ * Parse a plugin agent markdown file.
181
+ * Exposed as a public API for PluginLoader to use.
182
+ */
183
+ export function parseAgentFile(
184
+ filePath: string,
185
+ scope: "plugin",
186
+ pluginRoot: string,
187
+ ): SubagentConfiguration {
188
+ return parseSubagentFile(filePath, scope, pluginRoot);
189
+ }
190
+
164
191
  /**
165
192
  * Scan directory for subagent files
166
193
  */