wave-agent-sdk 1.1.4 → 1.2.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 (89) hide show
  1. package/dist/agent.d.ts +72 -24
  2. package/dist/agent.js +123 -31
  3. package/dist/builtin/plugins.js +17 -2
  4. package/dist/builtin/skills/settings.js +6 -8
  5. package/dist/core/plugin.d.ts +4 -0
  6. package/dist/core/plugin.js +7 -1
  7. package/dist/index.d.ts +2 -1
  8. package/dist/index.js +2 -1
  9. package/dist/managers/aiManager.d.ts +0 -24
  10. package/dist/managers/aiManager.js +23 -181
  11. package/dist/managers/bashModeManager.d.ts +33 -0
  12. package/dist/managers/bashModeManager.js +110 -0
  13. package/dist/managers/hookManager.d.ts +5 -0
  14. package/dist/managers/hookManager.js +7 -0
  15. package/dist/managers/liveConfigManager.js +3 -3
  16. package/dist/managers/mcpManager.d.ts +23 -0
  17. package/dist/managers/mcpManager.js +162 -14
  18. package/dist/managers/messageManager.d.ts +12 -13
  19. package/dist/managers/messageManager.js +63 -60
  20. package/dist/managers/permissionManager.d.ts +29 -0
  21. package/dist/managers/permissionManager.js +158 -70
  22. package/dist/managers/planManager.d.ts +9 -0
  23. package/dist/managers/planManager.js +19 -1
  24. package/dist/managers/skillManager.d.ts +31 -0
  25. package/dist/managers/skillManager.js +122 -12
  26. package/dist/managers/slashCommandManager.js +9 -28
  27. package/dist/managers/subagentManager.d.ts +7 -0
  28. package/dist/managers/subagentManager.js +61 -9
  29. package/dist/managers/workflowManager.js +6 -0
  30. package/dist/prompts/index.d.ts +0 -1
  31. package/dist/prompts/index.js +0 -4
  32. package/dist/services/MarketplaceService.js +36 -14
  33. package/dist/services/configurationService.d.ts +34 -2
  34. package/dist/services/configurationService.js +123 -16
  35. package/dist/services/initializationService.js +2 -2
  36. package/dist/services/jsonlHandler.d.ts +14 -0
  37. package/dist/services/jsonlHandler.js +44 -1
  38. package/dist/services/memory.d.ts +14 -0
  39. package/dist/services/memory.js +33 -0
  40. package/dist/services/officialMarketplaceMirror.d.ts +85 -0
  41. package/dist/services/officialMarketplaceMirror.js +289 -0
  42. package/dist/services/remoteSettingsService.js +4 -4
  43. package/dist/services/session.js +30 -13
  44. package/dist/services/worktreeHooks.js +6 -1
  45. package/dist/stdio/index.d.ts +10 -0
  46. package/dist/stdio/index.js +10 -0
  47. package/dist/stdio/notificationRouter.d.ts +38 -0
  48. package/dist/stdio/notificationRouter.js +96 -0
  49. package/dist/stdio/rpcClient.d.ts +18 -0
  50. package/dist/stdio/rpcClient.js +10 -0
  51. package/dist/stdio/stdioAgent.d.ts +222 -0
  52. package/dist/stdio/stdioAgent.js +341 -0
  53. package/dist/tools/bashTool.js +2 -0
  54. package/dist/tools/exitPlanMode.js +10 -2
  55. package/dist/types/agent.d.ts +8 -0
  56. package/dist/types/commands.d.ts +7 -0
  57. package/dist/types/configuration.d.ts +6 -1
  58. package/dist/types/hooks.d.ts +1 -0
  59. package/dist/types/hooks.js +19 -0
  60. package/dist/types/mcp.d.ts +3 -0
  61. package/dist/types/messaging.d.ts +1 -8
  62. package/dist/types/skills.d.ts +11 -0
  63. package/dist/utils/bashParser.d.ts +17 -0
  64. package/dist/utils/bashParser.js +72 -0
  65. package/dist/utils/bashStructure/bashLexer.d.ts +96 -0
  66. package/dist/utils/bashStructure/bashLexer.js +676 -0
  67. package/dist/utils/bashStructure/bashParser.d.ts +144 -0
  68. package/dist/utils/bashStructure/bashParser.js +606 -0
  69. package/dist/utils/bashStructure/bashSemantics.d.ts +70 -0
  70. package/dist/utils/bashStructure/bashSemantics.js +477 -0
  71. package/dist/utils/bashStructure/index.d.ts +26 -0
  72. package/dist/utils/bashStructure/index.js +27 -0
  73. package/dist/utils/bashStructure/types.d.ts +62 -0
  74. package/dist/utils/bashStructure/types.js +47 -0
  75. package/dist/utils/container.d.ts +6 -0
  76. package/dist/utils/container.js +9 -0
  77. package/dist/utils/containerSetup.d.ts +11 -1
  78. package/dist/utils/containerSetup.js +26 -11
  79. package/dist/utils/fileUtils.d.ts +11 -0
  80. package/dist/utils/fileUtils.js +37 -0
  81. package/dist/utils/messageOperations.d.ts +0 -18
  82. package/dist/utils/messageOperations.js +0 -62
  83. package/dist/utils/subagentParser.js +9 -2
  84. package/dist/utils/tokenCalculation.js +0 -8
  85. package/dist/utils/worktreeUtils.d.ts +2 -1
  86. package/dist/utils/worktreeUtils.js +64 -34
  87. package/package.json +6 -1
  88. package/dist/managers/bangManager.d.ts +0 -26
  89. package/dist/managers/bangManager.js +0 -78
@@ -0,0 +1,38 @@
1
+ /**
2
+ * NotificationRouter — demultiplexes server→client notifications by sessionId.
3
+ *
4
+ * In the single-shared-process architecture, all sessions share one StdioClient.
5
+ * The server tags each session-scoped notification with `sessionId` on the
6
+ * JSON-RPC envelope. The router inspects that field and dispatches to the
7
+ * matching StdioAgent; notifications without sessionId (e.g. `authUrl`) go to
8
+ * a global handler.
9
+ *
10
+ * Lifecycle:
11
+ * 1. `attach()` once — subscribes to every notification method on the shared client
12
+ * 2. Per session: `register(sessionId, agent)` after `initialize` response
13
+ * 3. On `sessionIdChange`: router auto-rekeys the agent (old → new)
14
+ * 4. On `destroy`: `unregister(sessionId)` removes the agent
15
+ */
16
+ import type { RpcClient } from "./rpcClient.js";
17
+ type GlobalHandler = (params: unknown) => void;
18
+ import type { StdioAgent } from "./stdioAgent.js";
19
+ export declare class NotificationRouter {
20
+ private client;
21
+ private sessions;
22
+ private globalHandlers;
23
+ private attached;
24
+ constructor(client: RpcClient);
25
+ /**
26
+ * Subscribe to all notification methods on the shared client.
27
+ * Must be called once after construction. Idempotent.
28
+ */
29
+ attach(): void;
30
+ /** Register a session-scoped agent. Call after `initialize` response. */
31
+ register(sessionId: string, agent: StdioAgent): void;
32
+ /** Unregister a session. Call on destroy. */
33
+ unregister(sessionId: string): void;
34
+ /** Register a global (non-session-scoped) notification handler. */
35
+ registerGlobal(method: string, handler: GlobalHandler): void;
36
+ private dispatch;
37
+ }
38
+ export {};
@@ -0,0 +1,96 @@
1
+ /**
2
+ * NotificationRouter — demultiplexes server→client notifications by sessionId.
3
+ *
4
+ * In the single-shared-process architecture, all sessions share one StdioClient.
5
+ * The server tags each session-scoped notification with `sessionId` on the
6
+ * JSON-RPC envelope. The router inspects that field and dispatches to the
7
+ * matching StdioAgent; notifications without sessionId (e.g. `authUrl`) go to
8
+ * a global handler.
9
+ *
10
+ * Lifecycle:
11
+ * 1. `attach()` once — subscribes to every notification method on the shared client
12
+ * 2. Per session: `register(sessionId, agent)` after `initialize` response
13
+ * 3. On `sessionIdChange`: router auto-rekeys the agent (old → new)
14
+ * 4. On `destroy`: `unregister(sessionId)` removes the agent
15
+ */
16
+ const ALL_NOTIFICATION_METHODS = [
17
+ "userMessageAdded",
18
+ "assistantMessageAdded",
19
+ "assistantContentUpdated",
20
+ "assistantReasoningUpdated",
21
+ "toolBlockUpdated",
22
+ "errorBlockAdded",
23
+ "loadingChange",
24
+ "contextUsage",
25
+ "commandRunningChange",
26
+ "queuedMessagesChange",
27
+ "tasksChange",
28
+ "sessionIdChange",
29
+ "permissionModeChange",
30
+ "mcpServersChange",
31
+ "workdirChange",
32
+ "notificationMessageAdded",
33
+ "permissionRequest",
34
+ "authUrl",
35
+ "btwContent",
36
+ "compactBlockAdded",
37
+ "compactionStateChange",
38
+ "compactionContentUpdate",
39
+ "backgroundTasksChange",
40
+ ];
41
+ export class NotificationRouter {
42
+ constructor(client) {
43
+ this.client = client;
44
+ this.sessions = new Map();
45
+ this.globalHandlers = new Map();
46
+ this.attached = false;
47
+ }
48
+ /**
49
+ * Subscribe to all notification methods on the shared client.
50
+ * Must be called once after construction. Idempotent.
51
+ */
52
+ attach() {
53
+ if (this.attached)
54
+ return;
55
+ this.attached = true;
56
+ for (const method of ALL_NOTIFICATION_METHODS) {
57
+ this.client.onNotification(method, (params, sessionId) => {
58
+ this.dispatch(method, params, sessionId);
59
+ });
60
+ }
61
+ }
62
+ /** Register a session-scoped agent. Call after `initialize` response. */
63
+ register(sessionId, agent) {
64
+ this.sessions.set(sessionId, agent);
65
+ }
66
+ /** Unregister a session. Call on destroy. */
67
+ unregister(sessionId) {
68
+ this.sessions.delete(sessionId);
69
+ }
70
+ /** Register a global (non-session-scoped) notification handler. */
71
+ registerGlobal(method, handler) {
72
+ this.globalHandlers.set(method, handler);
73
+ }
74
+ dispatch(method, params, sessionId) {
75
+ if (sessionId) {
76
+ const agent = this.sessions.get(sessionId);
77
+ if (!agent)
78
+ return; // early notification before register — drop (v1)
79
+ // sessionIdChange requires rekeying the agent in the map
80
+ if (method === "sessionIdChange") {
81
+ const newId = params.sessionId;
82
+ if (newId && newId !== sessionId) {
83
+ this.sessions.delete(sessionId);
84
+ this.sessions.set(newId, agent);
85
+ }
86
+ }
87
+ agent.handleNotification(method, params);
88
+ }
89
+ else {
90
+ // Global notification (e.g. authUrl)
91
+ const handler = this.globalHandlers.get(method);
92
+ if (handler)
93
+ handler(params);
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * RpcClient — the structural transport surface StdioAgent + NotificationRouter
3
+ * depend on.
4
+ *
5
+ * Both hosts keep their own transports (vscode's `StdioClient`; desktop's
6
+ * `JsonRpcClient` subclasses `StdioClient` / `SocketClient`); each satisfies
7
+ * this interface structurally (TypeScript), so the shared stdio layer never
8
+ * needs to know which transport backs it.
9
+ */
10
+ export type NotificationHandler = (params: unknown, sessionId?: string) => void;
11
+ export interface RpcClient {
12
+ /** Send a request; resolves with the JSON-RPC result. */
13
+ request(method: string, params?: unknown, sessionId?: string): Promise<unknown>;
14
+ /** Fire-and-forget JSON-RPC notification (no response expected). */
15
+ notify(method: string, params?: unknown, sessionId?: string): void;
16
+ /** Subscribe to a server→client notification method. */
17
+ onNotification(method: string, handler: NotificationHandler): void;
18
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * RpcClient — the structural transport surface StdioAgent + NotificationRouter
3
+ * depend on.
4
+ *
5
+ * Both hosts keep their own transports (vscode's `StdioClient`; desktop's
6
+ * `JsonRpcClient` subclasses `StdioClient` / `SocketClient`); each satisfies
7
+ * this interface structurally (TypeScript), so the shared stdio layer never
8
+ * needs to know which transport backs it.
9
+ */
10
+ export {};
@@ -0,0 +1,222 @@
1
+ /**
2
+ * StdioAgent — host-side typed wrapper around a JSON-RPC client that mirrors
3
+ * the Agent API (shared by the VS Code extension and the desktop app).
4
+ *
5
+ * In the single-shared-process architecture, all sessions share one transport
6
+ * client. The NotificationRouter dispatches incoming notifications to the
7
+ * appropriate StdioAgent via `handleNotification()`. The agent no longer
8
+ * subscribes directly to the client.
9
+ *
10
+ * All session-scoped requests carry `this.sessionId` on the JSON-RPC envelope
11
+ * so the server can route them to the right Agent.
12
+ *
13
+ * `destroy()` only unregisters from the router and sends the destroy request;
14
+ * it does NOT dispose the shared client.
15
+ *
16
+ * The client dependency is the structural `RpcClient` surface (request/notify/
17
+ * onNotification) so both hosts keep their own transports: vscode's
18
+ * `StdioClient` (spawn + hostLog) and desktop's `JsonRpcClient` subclasses
19
+ * (StdioClient / SocketClient).
20
+ */
21
+ import type { Message, Task, BackgroundTaskSummary, SerializableWorkflowRun, QueuedMessage, McpServerStatus, PermissionMode, PermissionDecision, ToolPermissionContext, ToolBlockUpdateCallbackParams, SlashCommand, McpServerConfig, SubagentConfiguration, SkillMetadata } from "../types/index.js";
22
+ import type { RpcClient } from "./rpcClient.js";
23
+ import type { NotificationRouter } from "./notificationRouter.js";
24
+ export interface InitializeParams {
25
+ workdir?: string;
26
+ restoreSessionId?: string;
27
+ apiKey?: string;
28
+ baseURL?: string;
29
+ serverUrl?: string;
30
+ defaultHeaders?: Record<string, string>;
31
+ model?: string;
32
+ fastModel?: string;
33
+ language?: string;
34
+ autoMemoryEnabled?: boolean;
35
+ autoMemoryFrequency?: number;
36
+ permissionMode?: PermissionMode;
37
+ tools?: string[];
38
+ allowedTools?: string[];
39
+ disallowedTools?: string[];
40
+ pluginDirs?: string[];
41
+ mcpServers?: Record<string, McpServerConfig>;
42
+ worktreeName?: string;
43
+ isNewWorktree?: boolean;
44
+ }
45
+ export interface InitializeResult {
46
+ sessionId: string;
47
+ workingDirectory: string;
48
+ permissionMode: PermissionMode;
49
+ latestTotalTokens: number;
50
+ }
51
+ export interface UpdateConfigParams {
52
+ apiKey?: string;
53
+ baseURL?: string;
54
+ serverUrl?: string;
55
+ defaultHeaders?: Record<string, string>;
56
+ model?: string;
57
+ fastModel?: string;
58
+ language?: string;
59
+ contextLength?: number;
60
+ autoMemoryEnabled?: boolean;
61
+ autoMemoryFrequency?: number;
62
+ }
63
+ export interface StdioAgentCallbacks {
64
+ onUserMessageAdded?: (message: Message) => void;
65
+ onAssistantMessageAdded?: (message: Message) => void;
66
+ onAssistantContentUpdated?: (params: {
67
+ messageId: string;
68
+ chunk: string;
69
+ stage: "streaming" | "end";
70
+ }) => void;
71
+ onAssistantReasoningUpdated?: (params: {
72
+ messageId: string;
73
+ chunk: string;
74
+ stage: "streaming" | "end";
75
+ }) => void;
76
+ onToolBlockUpdated?: (params: ToolBlockUpdateCallbackParams) => void;
77
+ onErrorBlockAdded?: (error: string) => void;
78
+ onCompactBlockAdded?: (content: string) => void;
79
+ onCompactionStateChange?: (isCompacting: boolean) => void;
80
+ onCompactionContentUpdate?: (content: string) => void;
81
+ onLoadingChange?: (loading: boolean) => void;
82
+ onContextUsage?: (percent: number) => void;
83
+ onCommandRunningChange?: (running: boolean) => void;
84
+ onQueuedMessagesChange?: (messages: QueuedMessage[]) => void;
85
+ onTasksChange?: (tasks: Task[]) => void;
86
+ onBackgroundTasksChange?: (tasks: BackgroundTaskSummary[]) => void;
87
+ onSessionIdChange?: (sessionId: string) => void;
88
+ onPermissionModeChange?: (mode: PermissionMode) => void;
89
+ onMcpServersChange?: (servers: McpServerStatus[]) => void;
90
+ onWorkdirChange?: (workdir: string) => void;
91
+ onNotificationMessageAdded?: (params: {
92
+ taskId: string;
93
+ taskType: string;
94
+ status: string;
95
+ summary: string;
96
+ message?: Message;
97
+ }) => void;
98
+ onPermissionRequest?: (requestId: string, context: ToolPermissionContext) => void;
99
+ onBtwContent?: (params: {
100
+ question: string;
101
+ content: string;
102
+ type: "thinking" | "content";
103
+ }) => void;
104
+ }
105
+ export declare class StdioAgent {
106
+ sessionId: string | undefined;
107
+ workingDirectory: string | undefined;
108
+ /**
109
+ * Initialize-time cwd — the session's stable root. Unlike
110
+ * `workingDirectory` it is never overwritten by the workdirChange
111
+ * notification (bash cd), so @file search and the /status workdir stay
112
+ * anchored to the project root.
113
+ */
114
+ sessionCwd: string | undefined;
115
+ latestTotalTokens: number;
116
+ /**
117
+ * Context-usage percentage reported with the most recent getMessages pull.
118
+ * A host whose webview was re-created long after the last token change gets
119
+ * no contextUsage notification, so it replays this on webviewReady instead.
120
+ */
121
+ contextUsagePercent: number | undefined;
122
+ permissionMode: PermissionMode | undefined;
123
+ messages: Message[];
124
+ queuedMessages: QueuedMessage[];
125
+ tasks: Task[];
126
+ backgroundTasks: BackgroundTaskSummary[];
127
+ isStreaming: boolean;
128
+ isCommandRunning: boolean;
129
+ isCompacting: boolean;
130
+ private client;
131
+ private router;
132
+ private callbacks;
133
+ constructor(client: RpcClient, router: NotificationRouter, callbacks: StdioAgentCallbacks);
134
+ initialize(params: InitializeParams): Promise<InitializeResult>;
135
+ destroy(): Promise<void>;
136
+ restoreSession(sessionId: string): Promise<void>;
137
+ updateConfig(params: UpdateConfigParams): Promise<{
138
+ sessionId: string;
139
+ }>;
140
+ sendMessage(text: string, images?: Array<{
141
+ path: string;
142
+ mimeType: string;
143
+ }>, force?: boolean): Promise<void>;
144
+ bang(command: string): Promise<void>;
145
+ abortMessage(): Promise<void>;
146
+ clearMessages(): Promise<void>;
147
+ compact(customInstructions?: string): Promise<void>;
148
+ rewindToMessage(messageId: string): Promise<{
149
+ inputContent: string;
150
+ }>;
151
+ askBtw(question: string): Promise<string>;
152
+ removeQueuedMessage(index: number): Promise<void>;
153
+ updateQueuedMessageById(id: string, patch: {
154
+ content?: string;
155
+ images?: Array<{
156
+ path: string;
157
+ mimeType: string;
158
+ }>;
159
+ type?: "message" | "bang";
160
+ }): Promise<boolean>;
161
+ removeQueuedMessageById(id: string): Promise<void>;
162
+ getFullMessageThread(): Promise<{
163
+ messages: Message[];
164
+ sessionIds: string[];
165
+ }>;
166
+ getMessages(): Promise<Message[]>;
167
+ listRewindCheckpoints(): Promise<{
168
+ checkpoints: Array<{
169
+ id: string;
170
+ content: string;
171
+ }>;
172
+ }>;
173
+ getConfiguredModels(): Promise<{
174
+ models: string[];
175
+ currentModel: string | undefined;
176
+ }>;
177
+ setModel(model: string): Promise<void>;
178
+ setPermissionMode(mode: PermissionMode): Promise<void>;
179
+ /** Returns cached permission mode (updated via notification). */
180
+ getPermissionMode(): PermissionMode | undefined;
181
+ /**
182
+ * Reads the session's current plan file (path + contents). Used by the
183
+ * /plan command to display the plan when already in plan mode; the CLI side
184
+ * awaits the path if it is still being generated after setPermissionMode.
185
+ */
186
+ getPlanFile(): Promise<{
187
+ path: string | null;
188
+ content: string | null;
189
+ }>;
190
+ sendPermissionResponse(requestId: string, decision: PermissionDecision): void;
191
+ getBackgroundTaskOutput(taskId: string): Promise<{
192
+ stdout: string;
193
+ stderr: string;
194
+ status: string;
195
+ outputPath?: string;
196
+ type: string;
197
+ exitCode?: number;
198
+ } | null>;
199
+ stopBackgroundTask(taskId: string): Promise<boolean>;
200
+ backgroundCurrentTask(): Promise<void>;
201
+ getWorkflowRuns(): Promise<SerializableWorkflowRun[]>;
202
+ stopWorkflowRun(runId: string): Promise<boolean>;
203
+ getMcpServers(): Promise<McpServerStatus[]>;
204
+ connectMcpServer(serverName: string): Promise<boolean>;
205
+ disconnectMcpServer(serverName: string): Promise<boolean>;
206
+ getMcpConfigPaths(): Promise<{
207
+ userPath: string | null;
208
+ projectPath: string | null;
209
+ }>;
210
+ removeMcpServer(scope: "user" | "project", serverName: string): Promise<boolean>;
211
+ deleteSkill(name: string): Promise<boolean>;
212
+ deleteSubagent(name: string): Promise<boolean>;
213
+ getHooksByScope(scope: "user" | "project" | "plugin"): Promise<{
214
+ hooks: Partial<Record<string, unknown[]>>;
215
+ configPath: string | null;
216
+ }>;
217
+ deleteHook(scope: "user" | "project", hookName: string): Promise<void>;
218
+ getSlashCommands(): Promise<SlashCommand[]>;
219
+ getSubagentConfigurations(): Promise<SubagentConfiguration[]>;
220
+ getSkillMetadata(): Promise<SkillMetadata[]>;
221
+ handleNotification(method: string, params: unknown): void;
222
+ }