wave-code 0.19.1 → 0.19.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.
@@ -1 +1 @@
1
- {"version":3,"file":"LoginCommand.d.ts","sourceRoot":"","sources":["../../src/components/LoginCommand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAoBhD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAuMpD,CAAC"}
1
+ {"version":3,"file":"LoginCommand.d.ts","sourceRoot":"","sources":["../../src/components/LoginCommand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAoBhD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAkMpD,CAAC"}
@@ -114,13 +114,7 @@ export const LoginCommand = ({ onCancel }) => {
114
114
  };
115
115
  const isAuthenticated = authService.isSSOAuthenticated();
116
116
  const token = authService.getSSOToken();
117
- let serverUrl;
118
- try {
119
- serverUrl = authService.getServerUrl();
120
- }
121
- catch {
122
- // serverUrl not configured, skip display
123
- }
117
+ const serverUrl = authService.getServerUrl();
124
118
  const truncatedToken = token && token.length > 14
125
119
  ? `${token.substring(0, 10)}...${token.substring(token.length - 4)}`
126
120
  : (token ?? "");
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,wBAAsB,IAAI,kBAqZzB;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,wBAAsB,IAAI,kBAsZzB;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -38,6 +38,12 @@ export async function main() {
38
38
  description: "Print response without interactive mode",
39
39
  type: "string",
40
40
  global: false,
41
+ })
42
+ .option("stdio", {
43
+ description: "Start in stdio mode (JSON-RPC over stdin/stdout)",
44
+ type: "boolean",
45
+ default: false,
46
+ global: false,
41
47
  })
42
48
  .option("show-stats", {
43
49
  description: "Show timing and usage statistics in print mode",
@@ -92,11 +98,6 @@ export async function main() {
92
98
  description: "MCP server configuration as JSON string (same format as .mcp.json)",
93
99
  type: "string",
94
100
  global: false,
95
- })
96
- .option("acp", {
97
- description: "Run as an ACP bridge",
98
- type: "boolean",
99
- global: false,
100
101
  })
101
102
  .command("plugin", "Manage plugins and marketplaces", (yargs) => {
102
103
  return yargs
@@ -250,11 +251,6 @@ export async function main() {
250
251
  if (worktreeSession) {
251
252
  process.chdir(workdir);
252
253
  }
253
- // Handle ACP mode
254
- if (argv.acp) {
255
- const { runAcp } = await import("./acp-cli.js");
256
- return runAcp();
257
- }
258
254
  // Handle restore session command
259
255
  if (argv.restore === "" ||
260
256
  (process.argv.includes("-r") && argv.restore === undefined) ||
@@ -302,6 +298,11 @@ export async function main() {
302
298
  mcpServers,
303
299
  });
304
300
  }
301
+ // Handle stdio mode
302
+ if (argv.stdio) {
303
+ const { startStdioCli } = await import("./stdio-cli.js");
304
+ return startStdioCli();
305
+ }
305
306
  await startCli({
306
307
  restoreSessionId: argv.restore,
307
308
  continueLastSession: argv.continue,
@@ -0,0 +1,74 @@
1
+ /**
2
+ * AgentBridge — wraps the SDK Agent and translates between the JSON-RPC-like
3
+ * stdio protocol and Agent method calls / callbacks.
4
+ *
5
+ * Responsibilities:
6
+ * - Route incoming requests to the appropriate Agent method
7
+ * - Translate AgentCallbacks into outgoing notifications
8
+ * - Implement the canUseTool permission flow over the stdio protocol
9
+ * - Handle config updates by destroying and recreating the Agent
10
+ */
11
+ import { type JsonRpcError } from "./protocol.js";
12
+ export type NotificationEmitter = (method: string, params: unknown) => void;
13
+ export interface AgentBridgeOptions {
14
+ emit: NotificationEmitter;
15
+ }
16
+ export declare class AgentBridge {
17
+ private agent;
18
+ private pendingPermissions;
19
+ private permissionCounter;
20
+ private storedConfig;
21
+ private emit;
22
+ private pluginCore;
23
+ private pluginCoreWorkdir;
24
+ constructor(options: AgentBridgeOptions);
25
+ handleRequest(method: string, params: unknown): Promise<unknown>;
26
+ handleNotification(method: string, params: unknown): void;
27
+ private initialize;
28
+ private destroy;
29
+ private restoreSession;
30
+ private listSessions;
31
+ private getSessionInfo;
32
+ private updateConfig;
33
+ private sendMessage;
34
+ private bang;
35
+ private abortMessage;
36
+ private clearMessages;
37
+ private rewindToMessage;
38
+ private deleteQueuedMessage;
39
+ private getMessages;
40
+ private getFullMessageThread;
41
+ private setPermissionMode;
42
+ private getPermissionMode;
43
+ private getMcpServers;
44
+ private connectMcpServer;
45
+ private disconnectMcpServer;
46
+ private getSlashCommands;
47
+ private searchFiles;
48
+ private getPromptHistory;
49
+ private searchPromptHistory;
50
+ private canUseTool;
51
+ private getAuthStatus;
52
+ private login;
53
+ private logout;
54
+ private getPluginCore;
55
+ private listPlugins;
56
+ private installPlugin;
57
+ private uninstallPlugin;
58
+ private enablePlugin;
59
+ private disablePlugin;
60
+ private updatePlugin;
61
+ private listMarketplaces;
62
+ private addMarketplace;
63
+ private removeMarketplace;
64
+ private updateMarketplace;
65
+ private createCallbacks;
66
+ private findLastUserMessage;
67
+ private requireAgent;
68
+ }
69
+ export declare class RpcError extends Error {
70
+ code: number;
71
+ constructor(code: number, message: string);
72
+ toJsonRpcError(): JsonRpcError;
73
+ }
74
+ //# sourceMappingURL=agentBridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentBridge.d.ts","sourceRoot":"","sources":["../../src/stdio/agentBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuBH,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;AAE5E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,mBAAmB,CAAC;CAC3B;AAoCD,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,kBAAkB,CAGtB;IACJ,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,iBAAiB,CAAqB;gBAElC,OAAO,EAAE,kBAAkB;IAMjC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAyItE,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;YAgB3C,UAAU;YAuCV,OAAO;YAQP,cAAc;YAMd,YAAY;IAS1B,OAAO,CAAC,cAAc;YAiBR,YAAY;YAmBZ,WAAW;YAwBX,IAAI;YAMJ,YAAY;YAMZ,aAAa;YAMb,eAAe;IAoB7B,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,WAAW;YAKL,oBAAoB;YAUpB,iBAAiB;IAM/B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,aAAa;YAKP,gBAAgB;YAQhB,mBAAmB;IAUjC,OAAO,CAAC,gBAAgB;YAOV,WAAW;YAWX,gBAAgB;YAShB,mBAAmB;IAcjC,OAAO,CAAC,UAAU;YA0BJ,aAAa;YAWb,KAAK;YAaL,MAAM;IAQpB,OAAO,CAAC,aAAa;YAUP,WAAW;YAoBX,aAAa;YAQb,eAAe;YAKf,YAAY;YAQZ,aAAa;YAQb,YAAY;YAIZ,gBAAgB;YAIhB,cAAc;YAId,iBAAiB;YASjB,iBAAiB;IAO/B,OAAO,CAAC,eAAe;IA4EvB,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,YAAY;CAKrB;AAID,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,MAAM,CAAC;gBACD,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAKzC,cAAc,IAAI,YAAY;CAG/B"}
@@ -0,0 +1,486 @@
1
+ /**
2
+ * AgentBridge — wraps the SDK Agent and translates between the JSON-RPC-like
3
+ * stdio protocol and Agent method calls / callbacks.
4
+ *
5
+ * Responsibilities:
6
+ * - Route incoming requests to the appropriate Agent method
7
+ * - Translate AgentCallbacks into outgoing notifications
8
+ * - Implement the canUseTool permission flow over the stdio protocol
9
+ * - Handle config updates by destroying and recreating the Agent
10
+ */
11
+ import { Agent, listSessions, searchFiles, PromptHistoryManager, AuthService, PluginCore, } from "wave-agent-sdk";
12
+ import { INTERNAL_ERROR as PROTOCOL_INTERNAL_ERROR, METHOD_NOT_FOUND as PROTOCOL_METHOD_NOT_FOUND, } from "./protocol.js";
13
+ export class AgentBridge {
14
+ constructor(options) {
15
+ this.pendingPermissions = new Map();
16
+ this.permissionCounter = 0;
17
+ this.storedConfig = {};
18
+ this.emit = options.emit;
19
+ }
20
+ // ── Public API ────────────────────────────────────────────────
21
+ async handleRequest(method, params) {
22
+ const p = (params ?? {});
23
+ switch (method) {
24
+ // ── Lifecycle ──
25
+ case "initialize":
26
+ return this.initialize(p);
27
+ case "destroy":
28
+ return this.destroy();
29
+ case "restoreSession":
30
+ return this.restoreSession(p.sessionId);
31
+ case "listSessions":
32
+ return this.listSessions(p.workdir);
33
+ case "getSessionInfo":
34
+ return this.getSessionInfo();
35
+ case "updateConfig":
36
+ return this.updateConfig(p);
37
+ // ── Messages ──
38
+ case "sendMessage":
39
+ return this.sendMessage(p);
40
+ case "bang":
41
+ return this.bang(p.command);
42
+ case "abortMessage":
43
+ return this.abortMessage();
44
+ case "clearMessages":
45
+ return this.clearMessages();
46
+ case "rewindToMessage":
47
+ return this.rewindToMessage(p.messageId);
48
+ case "deleteQueuedMessage":
49
+ return this.deleteQueuedMessage(p.index);
50
+ case "getMessages":
51
+ return this.getMessages();
52
+ case "getFullMessageThread":
53
+ return this.getFullMessageThread();
54
+ // ── Permissions ──
55
+ case "setPermissionMode":
56
+ return this.setPermissionMode(p.mode);
57
+ case "getPermissionMode":
58
+ return this.getPermissionMode();
59
+ // ── MCP ──
60
+ case "getMcpServers":
61
+ return this.getMcpServers();
62
+ case "connectMcpServer":
63
+ return this.connectMcpServer(p.serverName);
64
+ case "disconnectMcpServer":
65
+ return this.disconnectMcpServer(p.serverName);
66
+ // ── Commands ──
67
+ case "getSlashCommands":
68
+ return this.getSlashCommands();
69
+ // ── File / History ──
70
+ case "searchFiles":
71
+ return this.searchFiles(p);
72
+ case "getPromptHistory":
73
+ return this.getPromptHistory(p.workdir);
74
+ case "searchPromptHistory":
75
+ return this.searchPromptHistory(p.query, p.workdir);
76
+ // ── Auth ──
77
+ case "getAuthStatus":
78
+ return this.getAuthStatus();
79
+ case "login":
80
+ return this.login(p.serverUrl);
81
+ case "logout":
82
+ return this.logout();
83
+ // ── Plugins ──
84
+ case "listPlugins":
85
+ return this.listPlugins(p.workdir);
86
+ case "installPlugin":
87
+ return this.installPlugin(p.pluginId, p.scope, p.workdir);
88
+ case "uninstallPlugin":
89
+ return this.uninstallPlugin(p.pluginId, p.workdir);
90
+ case "enablePlugin":
91
+ return this.enablePlugin(p.pluginId, p.scope, p.workdir);
92
+ case "disablePlugin":
93
+ return this.disablePlugin(p.pluginId, p.scope, p.workdir);
94
+ case "updatePlugin":
95
+ return this.updatePlugin(p.pluginId, p.workdir);
96
+ case "listMarketplaces":
97
+ return this.listMarketplaces(p.workdir);
98
+ case "addMarketplace":
99
+ return this.addMarketplace(p.input, p.scope, p.workdir);
100
+ case "removeMarketplace":
101
+ return this.removeMarketplace(p.name, p.scope, p.workdir);
102
+ case "updateMarketplace":
103
+ return this.updateMarketplace(p.name, p.workdir);
104
+ default:
105
+ throw new RpcError(PROTOCOL_METHOD_NOT_FOUND, `Method not found: ${method}`);
106
+ }
107
+ }
108
+ handleNotification(method, params) {
109
+ if (method === "permissionResponse") {
110
+ const p = params;
111
+ const resolve = this.pendingPermissions.get(p.requestId);
112
+ if (resolve) {
113
+ this.pendingPermissions.delete(p.requestId);
114
+ resolve(p.decision);
115
+ }
116
+ }
117
+ }
118
+ // ── Lifecycle ─────────────────────────────────────────────────
119
+ async initialize(params) {
120
+ // Merge with stored config (CLI defaults can be overridden by client)
121
+ this.storedConfig = { ...this.storedConfig, ...params };
122
+ const callbacks = this.createCallbacks();
123
+ const options = {
124
+ callbacks,
125
+ workdir: params.workdir,
126
+ restoreSessionId: params.restoreSessionId,
127
+ apiKey: params.apiKey,
128
+ baseURL: params.baseURL,
129
+ defaultHeaders: params.defaultHeaders,
130
+ model: params.model,
131
+ fastModel: params.fastModel,
132
+ language: params.language,
133
+ permissionMode: params.permissionMode,
134
+ tools: params.tools,
135
+ allowedTools: params.allowedTools,
136
+ disallowedTools: params.disallowedTools,
137
+ plugins: params.pluginDirs?.map((path) => ({ type: "local", path })),
138
+ mcpServers: params.mcpServers,
139
+ canUseTool: (context) => this.canUseTool(context),
140
+ };
141
+ this.agent = await Agent.create(options);
142
+ return {
143
+ sessionId: this.agent.sessionId,
144
+ workingDirectory: this.agent.workingDirectory,
145
+ permissionMode: this.agent.getPermissionMode(),
146
+ latestTotalTokens: this.agent.latestTotalTokens,
147
+ };
148
+ }
149
+ async destroy() {
150
+ if (this.agent) {
151
+ await this.agent.destroy();
152
+ this.agent = undefined;
153
+ }
154
+ return null;
155
+ }
156
+ async restoreSession(sessionId) {
157
+ this.requireAgent();
158
+ await this.agent.restoreSession(sessionId);
159
+ return null;
160
+ }
161
+ async listSessions(workdir) {
162
+ const sessions = await listSessions(workdir || this.agent?.workingDirectory || process.cwd());
163
+ return { sessions };
164
+ }
165
+ getSessionInfo() {
166
+ this.requireAgent();
167
+ return {
168
+ sessionId: this.agent.sessionId,
169
+ workingDirectory: this.agent.workingDirectory,
170
+ latestTotalTokens: this.agent.latestTotalTokens,
171
+ permissionMode: this.agent.getPermissionMode(),
172
+ availableTools: this.agent.getAvailableToolNames(),
173
+ };
174
+ }
175
+ async updateConfig(params) {
176
+ this.requireAgent();
177
+ const currentSessionId = this.agent.sessionId;
178
+ // Merge new config into stored config
179
+ this.storedConfig = { ...this.storedConfig, ...params };
180
+ // Destroy and recreate
181
+ await this.agent.destroy();
182
+ this.agent = undefined;
183
+ await this.initialize({
184
+ ...this.storedConfig,
185
+ restoreSessionId: currentSessionId,
186
+ });
187
+ return { sessionId: this.agent.sessionId };
188
+ }
189
+ // ── Messages ──────────────────────────────────────────────────
190
+ async sendMessage(params) {
191
+ this.requireAgent();
192
+ if (params.force) {
193
+ this.agent.abortMessage();
194
+ }
195
+ // Save prompt to history (mirrors VSCE chatSession.ts:236-242)
196
+ try {
197
+ await PromptHistoryManager.addEntry(params.text, this.agent.sessionId, {}, this.agent.workingDirectory);
198
+ }
199
+ catch {
200
+ // Best-effort; don't block message sending on history save failure
201
+ }
202
+ await this.agent.sendMessage(params.text, params.images);
203
+ return null;
204
+ }
205
+ async bang(command) {
206
+ this.requireAgent();
207
+ await this.agent.bang(command);
208
+ return null;
209
+ }
210
+ async abortMessage() {
211
+ this.requireAgent();
212
+ this.agent.abortMessage();
213
+ return null;
214
+ }
215
+ async clearMessages() {
216
+ this.requireAgent();
217
+ this.agent.clearMessages();
218
+ return null;
219
+ }
220
+ async rewindToMessage(messageId) {
221
+ this.requireAgent();
222
+ const { messages } = await this.agent.getFullMessageThread();
223
+ const index = messages.findIndex((m) => m.id === messageId);
224
+ if (index === -1) {
225
+ throw new RpcError(PROTOCOL_INTERNAL_ERROR, `Message not found: ${messageId}`);
226
+ }
227
+ const message = messages[index];
228
+ const textBlock = message.blocks.find((b) => b.type === "text");
229
+ await this.agent.truncateHistory(index);
230
+ return { inputContent: textBlock?.content || "" };
231
+ }
232
+ deleteQueuedMessage(index) {
233
+ this.requireAgent();
234
+ this.agent.removeQueuedMessage(index);
235
+ return null;
236
+ }
237
+ getMessages() {
238
+ this.requireAgent();
239
+ return { messages: this.agent.messages };
240
+ }
241
+ async getFullMessageThread() {
242
+ this.requireAgent();
243
+ return this.agent.getFullMessageThread();
244
+ }
245
+ // ── Permissions ───────────────────────────────────────────────
246
+ async setPermissionMode(mode) {
247
+ this.requireAgent();
248
+ await this.agent.setPermissionMode(mode);
249
+ return null;
250
+ }
251
+ getPermissionMode() {
252
+ this.requireAgent();
253
+ return { mode: this.agent.getPermissionMode() };
254
+ }
255
+ // ── MCP ───────────────────────────────────────────────────────
256
+ getMcpServers() {
257
+ this.requireAgent();
258
+ return { servers: this.agent.getMcpServers() };
259
+ }
260
+ async connectMcpServer(serverName) {
261
+ this.requireAgent();
262
+ const success = await this.agent.connectMcpServer(serverName);
263
+ return { success };
264
+ }
265
+ async disconnectMcpServer(serverName) {
266
+ this.requireAgent();
267
+ const success = await this.agent.disconnectMcpServer(serverName);
268
+ return { success };
269
+ }
270
+ // ── Commands ──────────────────────────────────────────────────
271
+ getSlashCommands() {
272
+ this.requireAgent();
273
+ return { commands: this.agent.getSlashCommands() };
274
+ }
275
+ // ── File / History ────────────────────────────────────────────
276
+ async searchFiles(params) {
277
+ const files = await searchFiles(params.query, {
278
+ maxResults: params.maxResults,
279
+ workingDirectory: params.workdir || this.agent?.workingDirectory || process.cwd(),
280
+ });
281
+ return { files };
282
+ }
283
+ async getPromptHistory(workdir) {
284
+ const history = await PromptHistoryManager.getHistory({
285
+ workdir: workdir || this.agent?.workingDirectory,
286
+ });
287
+ return { history };
288
+ }
289
+ async searchPromptHistory(query, workdir) {
290
+ const history = await PromptHistoryManager.searchHistory(query, {
291
+ workdir: workdir || this.agent?.workingDirectory,
292
+ });
293
+ return { history };
294
+ }
295
+ // ── canUseTool flow ───────────────────────────────────────────
296
+ canUseTool(context) {
297
+ const requestId = `perm_${++this.permissionCounter}`;
298
+ return new Promise((resolve) => {
299
+ this.pendingPermissions.set(requestId, resolve);
300
+ this.emit("permissionRequest", { requestId, context });
301
+ // 5-minute timeout → auto-deny
302
+ setTimeout(() => {
303
+ if (this.pendingPermissions.has(requestId)) {
304
+ this.pendingPermissions.delete(requestId);
305
+ resolve({
306
+ behavior: "deny",
307
+ message: "Permission request timed out",
308
+ });
309
+ }
310
+ }, 5 * 60 * 1000);
311
+ });
312
+ }
313
+ // ── Auth ─────────────────────────────────────────────────────
314
+ async getAuthStatus() {
315
+ const authService = AuthService.getInstance();
316
+ return {
317
+ isAuthenticated: authService.isSSOAuthenticated(),
318
+ user: authService.getAuthUser(),
319
+ };
320
+ }
321
+ async login(serverUrl) {
322
+ const authService = AuthService.getInstance();
323
+ await authService.login({
324
+ onAuthUrl: (url) => {
325
+ this.emit("authUrl", { url });
326
+ },
327
+ serverUrl,
328
+ });
329
+ return { user: authService.getAuthUser() };
330
+ }
331
+ async logout() {
332
+ const authService = AuthService.getInstance();
333
+ await authService.clearAuth();
334
+ return null;
335
+ }
336
+ // ── Plugins ──────────────────────────────────────────────────
337
+ getPluginCore(workdir) {
338
+ const resolvedWorkdir = workdir || this.agent?.workingDirectory || process.cwd();
339
+ if (!this.pluginCore || this.pluginCoreWorkdir !== resolvedWorkdir) {
340
+ this.pluginCore = new PluginCore(resolvedWorkdir);
341
+ this.pluginCoreWorkdir = resolvedWorkdir;
342
+ }
343
+ return this.pluginCore;
344
+ }
345
+ async listPlugins(workdir) {
346
+ const core = this.getPluginCore(workdir);
347
+ const { plugins, mergedEnabled } = await core.listPlugins();
348
+ return {
349
+ plugins: plugins.map((p) => {
350
+ const pluginId = `${p.name}@${p.marketplace}`;
351
+ return {
352
+ id: pluginId,
353
+ name: p.name,
354
+ description: p.description,
355
+ marketplace: p.marketplace,
356
+ installed: p.installed,
357
+ version: p.version,
358
+ enabled: mergedEnabled[pluginId] !== false,
359
+ scope: p.scope,
360
+ };
361
+ }),
362
+ };
363
+ }
364
+ async installPlugin(pluginId, scope, workdir) {
365
+ return this.getPluginCore(workdir).installPlugin(pluginId, scope);
366
+ }
367
+ async uninstallPlugin(pluginId, workdir) {
368
+ await this.getPluginCore(workdir).uninstallPlugin(pluginId);
369
+ return null;
370
+ }
371
+ async enablePlugin(pluginId, scope, workdir) {
372
+ return this.getPluginCore(workdir).enablePlugin(pluginId, scope);
373
+ }
374
+ async disablePlugin(pluginId, scope, workdir) {
375
+ return this.getPluginCore(workdir).disablePlugin(pluginId, scope);
376
+ }
377
+ async updatePlugin(pluginId, workdir) {
378
+ return this.getPluginCore(workdir).updatePlugin(pluginId);
379
+ }
380
+ async listMarketplaces(workdir) {
381
+ return this.getPluginCore(workdir).listMarketplaces();
382
+ }
383
+ async addMarketplace(input, scope, workdir) {
384
+ return this.getPluginCore(workdir).addMarketplace(input, scope);
385
+ }
386
+ async removeMarketplace(name, scope, workdir) {
387
+ await this.getPluginCore(workdir).removeMarketplace(name, scope);
388
+ return null;
389
+ }
390
+ async updateMarketplace(name, workdir) {
391
+ await this.getPluginCore(workdir).updateMarketplace(name);
392
+ return null;
393
+ }
394
+ // ── Callbacks → Notifications ─────────────────────────────────
395
+ createCallbacks() {
396
+ return {
397
+ onMessagesChange: (messages) => {
398
+ this.emit("messagesChange", { messages });
399
+ },
400
+ onUserMessageAdded: () => {
401
+ const msg = this.findLastUserMessage();
402
+ if (msg)
403
+ this.emit("userMessageAdded", { message: msg });
404
+ },
405
+ onAssistantMessageAdded: (messageId) => {
406
+ const msg = this.agent?.messages.find((m) => m.id === messageId);
407
+ if (msg)
408
+ this.emit("assistantMessageAdded", { message: msg });
409
+ },
410
+ onAssistantContentUpdated: (params) => {
411
+ this.emit("assistantContentUpdated", params);
412
+ },
413
+ onAssistantReasoningUpdated: (params) => {
414
+ this.emit("assistantReasoningUpdated", params);
415
+ },
416
+ onToolBlockUpdated: (params) => {
417
+ this.emit("toolBlockUpdated", params);
418
+ },
419
+ onErrorBlockAdded: (error) => {
420
+ this.emit("errorBlockAdded", { error });
421
+ },
422
+ onLoadingChange: (loading) => {
423
+ this.emit("loadingChange", {
424
+ loading,
425
+ latestTotalTokens: this.agent?.latestTotalTokens,
426
+ });
427
+ },
428
+ onCommandRunningChange: (running) => {
429
+ this.emit("commandRunningChange", { running });
430
+ },
431
+ onQueuedMessagesChange: (messages) => {
432
+ this.emit("queuedMessagesChange", { messages });
433
+ },
434
+ onTasksChange: (tasks) => {
435
+ this.emit("tasksChange", { tasks });
436
+ },
437
+ onSessionIdChange: (sessionId) => {
438
+ this.emit("sessionIdChange", { sessionId });
439
+ },
440
+ onPermissionModeChange: (mode) => {
441
+ this.emit("permissionModeChange", { mode });
442
+ },
443
+ onMcpServersChange: (servers) => {
444
+ this.emit("mcpServersChange", { servers });
445
+ },
446
+ onAddBangMessage: () => {
447
+ this.emit("bangMessageAdded", {});
448
+ },
449
+ onUpdateBangMessage: () => {
450
+ this.emit("bangMessageUpdated", {});
451
+ },
452
+ onCompleteBangMessage: () => {
453
+ this.emit("bangMessageCompleted", {});
454
+ },
455
+ onNotificationMessageAdded: (params) => {
456
+ const msg = this.agent?.messages.find((m) => m.role === "user" &&
457
+ m.blocks.some((b) => b.type === "task_notification" &&
458
+ b.taskId === params.taskId));
459
+ this.emit("notificationMessageAdded", {
460
+ ...params,
461
+ message: msg,
462
+ });
463
+ },
464
+ };
465
+ }
466
+ findLastUserMessage() {
467
+ const userMessages = this.agent?.messages.filter((m) => m.role === "user") ?? [];
468
+ return userMessages[userMessages.length - 1];
469
+ }
470
+ // ── Utils ─────────────────────────────────────────────────────
471
+ requireAgent() {
472
+ if (!this.agent) {
473
+ throw new RpcError(PROTOCOL_INTERNAL_ERROR, "Agent not initialized");
474
+ }
475
+ }
476
+ }
477
+ // ── Error class for protocol errors ─────────────────────────────
478
+ export class RpcError extends Error {
479
+ constructor(code, message) {
480
+ super(message);
481
+ this.code = code;
482
+ }
483
+ toJsonRpcError() {
484
+ return { code: this.code, message: this.message };
485
+ }
486
+ }
@@ -0,0 +1,4 @@
1
+ export { StdioServer, type StdioServerOptions } from "./stdioServer.js";
2
+ export { AgentBridge, type AgentBridgeOptions, RpcError, } from "./agentBridge.js";
3
+ export * from "./protocol.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stdio/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAC1B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { StdioServer } from "./stdioServer.js";
2
+ export { AgentBridge, RpcError, } from "./agentBridge.js";
3
+ export * from "./protocol.js";