@vibearound/plugin-channel-sdk 0.3.0 → 0.4.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.
package/dist/renderer.js CHANGED
@@ -25,32 +25,26 @@
25
25
  *
26
26
  * ## Usage
27
27
  *
28
+ * Subclass and implement `sendText` + `sendBlock` (+ optionally `editBlock`):
29
+ *
28
30
  * ```ts
29
31
  * class MyRenderer extends BlockRenderer<string> {
30
- * protected async sendBlock(channelId, kind, content) {
31
- * const msg = await myApi.sendMessage(channelId, content);
32
+ * protected async sendText(chatId, text) {
33
+ * await myApi.sendMessage(chatId, text);
34
+ * }
35
+ * protected async sendBlock(chatId, kind, content) {
36
+ * const msg = await myApi.sendMessage(chatId, content);
32
37
  * return msg.id;
33
38
  * }
34
- * protected async editBlock(channelId, ref, kind, content, sealed) {
39
+ * protected async editBlock(chatId, ref, kind, content, sealed) {
35
40
  * await myApi.editMessage(ref, content);
36
41
  * }
37
42
  * }
38
- *
39
- * // In main.ts:
40
- * const renderer = new MyRenderer({ verbose: { showThinking: false } });
41
- *
42
- * // When user sends a message:
43
- * renderer.onPromptSent(channelId);
44
- * try {
45
- * await agent.prompt({ sessionId, content });
46
- * await renderer.onTurnEnd(channelId);
47
- * } catch (e) {
48
- * await renderer.onTurnError(channelId, String(e));
49
- * }
50
- *
51
- * // In the ACP client's sessionUpdate handler:
52
- * renderer.onSessionUpdate(notification);
53
43
  * ```
44
+ *
45
+ * The SDK's `runChannelPlugin` wires all ACP events to this renderer
46
+ * automatically — plugins don't call onSessionUpdate/onPromptSent/etc
47
+ * directly.
54
48
  */
55
49
  // ---------------------------------------------------------------------------
56
50
  // Constants
@@ -68,11 +62,18 @@ const DEFAULT_MIN_EDIT_INTERVAL_MS = 1000;
68
62
  * return type of `sendBlock` and the first argument of `editBlock`.
69
63
  */
70
64
  export class BlockRenderer {
65
+ /** When true, blocks are sent and edited in real-time. When false, each
66
+ * block is held until complete, then sent once (send-only mode). */
67
+ streaming;
71
68
  flushIntervalMs;
72
69
  minEditIntervalMs;
73
70
  verbose;
74
71
  states = new Map();
72
+ /** The chatId of the most recent prompt. Used as fallback target for
73
+ * notifications that arrive without an explicit chatId. */
74
+ lastActiveChatId = null;
75
75
  constructor(options = {}) {
76
+ this.streaming = options.streaming ?? true;
76
77
  this.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;
77
78
  this.minEditIntervalMs = options.minEditIntervalMs ?? DEFAULT_MIN_EDIT_INTERVAL_MS;
78
79
  this.verbose = {
@@ -99,29 +100,17 @@ export class BlockRenderer {
99
100
  }
100
101
  /**
101
102
  * Called after the last block has been flushed and the turn is complete.
102
- * Override to perform cleanup (e.g. remove a "typing" indicator, a
103
- * processing reaction, etc.).
103
+ * Override to perform cleanup (e.g. remove a "typing" indicator).
104
104
  */
105
- onAfterTurnEnd(_channelId) {
105
+ onAfterTurnEnd(_chatId) {
106
106
  return Promise.resolve();
107
107
  }
108
108
  /**
109
- * Called after a turn error, once state has been cleaned up.
110
- * Override to send an error message to the user.
109
+ * Called after a turn error. Default sends an error message via sendText.
110
+ * Override for platform-specific error rendering (e.g. error card).
111
111
  */
112
- onAfterTurnError(_channelId, _error) {
113
- return Promise.resolve();
114
- }
115
- /**
116
- * Map an ACP `sessionId` to the channel ID used internally.
117
- *
118
- * Default: identity (sessionId === channelId).
119
- *
120
- * Override if your plugin namespaces channel IDs (e.g. Feishu uses
121
- * `"feishu:<sessionId>"`, WeChat uses `"weixin-openclaw-bridge:<sessionId>"`).
122
- */
123
- sessionIdToChannelId(sessionId) {
124
- return sessionId;
112
+ async onAfterTurnError(chatId, error) {
113
+ await this.sendText(chatId, `❌ Error: ${error}`);
125
114
  }
126
115
  // ---------------------------------------------------------------------------
127
116
  // Public API
@@ -132,14 +121,12 @@ export class BlockRenderer {
132
121
  * Routes the event to the correct block based on its variant, appending
133
122
  * deltas to the current block or starting a new one when the kind changes.
134
123
  *
135
- * Call this from the ACP `Client.sessionUpdate` handler.
124
+ * Called automatically by `runChannelPlugin` — plugins don't call this directly.
136
125
  */
137
126
  onSessionUpdate(notification) {
138
- const sessionId = notification.sessionId;
139
- // Narrow through the local ConsumedSessionUpdate union see the type
140
- // declaration above this class for why we re-declare it locally instead
141
- // of importing the SDK's own union. Variants other than the four we
142
- // handle are treated as no-ops.
127
+ // sessionId from ACP = chatId (the host replaces the real agent session
128
+ // ID with the chat ID before forwarding to the plugin).
129
+ const chatId = notification.sessionId;
143
130
  const rawUpdate = notification.update;
144
131
  const variant = rawUpdate.sessionUpdate;
145
132
  if (variant !== "agent_message_chunk" &&
@@ -149,66 +136,108 @@ export class BlockRenderer {
149
136
  return;
150
137
  }
151
138
  const update = rawUpdate;
152
- const channelId = this.sessionIdToChannelId(sessionId);
153
139
  switch (update.sessionUpdate) {
154
140
  case "agent_message_chunk": {
155
141
  const delta = update.content?.text ?? "";
156
142
  if (delta)
157
- this.appendToBlock(channelId, "text", delta);
143
+ this.appendToBlock(chatId, "text", delta);
158
144
  break;
159
145
  }
160
146
  case "agent_thought_chunk": {
161
147
  if (!this.verbose.showThinking)
162
- return; // skip — no block, no boundary
148
+ return;
163
149
  const delta = update.content?.text ?? "";
164
150
  if (delta)
165
- this.appendToBlock(channelId, "thinking", delta);
151
+ this.appendToBlock(chatId, "thinking", delta);
166
152
  break;
167
153
  }
168
154
  case "tool_call": {
169
155
  if (!this.verbose.showToolUse)
170
- return; // skip
156
+ return;
171
157
  if (update.title)
172
- this.appendToBlock(channelId, "tool", `🔧 ${update.title}\n`);
158
+ this.appendToBlock(chatId, "tool", `🔧 ${update.title}\n`);
173
159
  break;
174
160
  }
175
161
  case "tool_call_update": {
176
162
  if (!this.verbose.showToolUse)
177
- return; // skip
163
+ return;
178
164
  const title = update.title ?? "tool";
179
165
  if (update.status === "completed" || update.status === "error") {
180
- this.appendToBlock(channelId, "tool", `✅ ${title}\n`);
166
+ this.appendToBlock(chatId, "tool", `✅ ${title}\n`);
181
167
  }
182
168
  break;
183
169
  }
184
- // Unknown / unconsumed variant — ignore.
185
170
  }
186
171
  }
187
172
  /**
188
- * Call this before sending a prompt to the agent.
189
- *
190
- * Clears any leftover state from a previous turn so the new turn starts
191
- * with a clean slate.
173
+ * Call before sending a prompt. Tracks the active chatId and clears
174
+ * leftover state from a previous turn.
192
175
  */
193
- onPromptSent(channelId) {
194
- const old = this.states.get(channelId);
176
+ onPromptSent(chatId) {
177
+ this.lastActiveChatId = chatId;
178
+ const old = this.states.get(chatId);
195
179
  if (old?.flushTimer)
196
180
  clearTimeout(old.flushTimer);
197
- this.states.set(channelId, {
181
+ this.states.set(chatId, {
198
182
  blocks: [],
199
183
  flushTimer: null,
200
184
  lastEditMs: 0,
201
185
  sendChain: Promise.resolve(),
202
186
  });
203
187
  }
188
+ // ---------------------------------------------------------------------------
189
+ // Host notification handlers — built-in defaults, no per-plugin duplication
190
+ // ---------------------------------------------------------------------------
191
+ /** Handle `va/system_text` from host. */
192
+ onSystemText(chatId, text) {
193
+ this.sendText(chatId, text).catch(() => { });
194
+ }
195
+ /** Handle `va/agent_ready` from host. */
196
+ onAgentReady(chatId, agent, version) {
197
+ this.sendText(chatId, `🤖 Agent: ${agent} v${version}`).catch(() => { });
198
+ }
199
+ /** Handle `va/session_ready` from host. */
200
+ onSessionReady(chatId, sessionId) {
201
+ this.sendText(chatId, `📋 Session: ${sessionId}`).catch(() => { });
202
+ }
203
+ /**
204
+ * Handle `va/command_menu` from host — display available commands.
205
+ *
206
+ * Default renders a plain-text list. Override for platform-specific
207
+ * rendering (e.g. Feishu interactive card, Slack Block Kit, Telegram
208
+ * inline keyboard).
209
+ */
210
+ onCommandMenu(chatId, systemCommands, agentCommands) {
211
+ const lines = [];
212
+ lines.push("System commands:");
213
+ for (const cmd of systemCommands) {
214
+ const usage = cmd.args ? `/${cmd.name} ${cmd.args}` : `/${cmd.name}`;
215
+ lines.push(` ${usage} — ${cmd.description}`);
216
+ }
217
+ if (agentCommands.length > 0) {
218
+ lines.push("");
219
+ lines.push("Agent commands (use /agent <command>):");
220
+ for (const cmd of agentCommands) {
221
+ const desc = cmd.description.length > 80
222
+ ? `${cmd.description.slice(0, 77)}...`
223
+ : cmd.description;
224
+ lines.push(` /${cmd.name} — ${desc}`);
225
+ }
226
+ }
227
+ else {
228
+ lines.push("");
229
+ lines.push("Agent commands will appear after sending your first message.");
230
+ }
231
+ this.sendText(chatId, lines.join("\n")).catch(() => { });
232
+ }
204
233
  /**
205
234
  * Call this after `agent.prompt()` resolves (turn complete).
206
235
  *
207
236
  * Seals and flushes the last block, then waits for all pending sends/edits
208
237
  * to complete before calling `onAfterTurnEnd`.
209
238
  */
210
- async onTurnEnd(channelId) {
211
- const state = this.states.get(channelId);
239
+ async onTurnEnd(chatId) {
240
+ const state = this.states.get(chatId);
212
241
  if (!state)
213
242
  return;
214
243
  if (state.flushTimer) {
@@ -220,33 +249,31 @@ export class BlockRenderer {
220
249
  last.sealed = true;
221
250
  this.enqueueFlush(state, last);
222
251
  }
223
- // Wait for the entire chain to drain before cleanup
224
252
  await state.sendChain;
225
- this.states.delete(channelId);
226
- await this.onAfterTurnEnd(channelId);
253
+ this.states.delete(chatId);
254
+ await this.onAfterTurnEnd(chatId);
227
255
  }
228
256
  /**
229
257
  * Call this when `agent.prompt()` throws (turn error).
230
258
  *
231
- * Discards pending state and calls `onAfterTurnError` so the subclass can
232
- * send an error message to the user.
259
+ * Discards pending state and calls `onAfterTurnError`.
233
260
  */
234
- async onTurnError(channelId, error) {
235
- const state = this.states.get(channelId);
261
+ async onTurnError(chatId, error) {
262
+ const state = this.states.get(chatId);
236
263
  if (state?.flushTimer)
237
264
  clearTimeout(state.flushTimer);
238
- this.states.delete(channelId);
239
- await this.onAfterTurnError(channelId, error);
265
+ this.states.delete(chatId);
266
+ await this.onAfterTurnError(chatId, error);
240
267
  }
241
268
  // ---------------------------------------------------------------------------
242
269
  // Internal — block management
243
270
  // ---------------------------------------------------------------------------
244
- appendToBlock(channelId, kind, delta) {
245
- let state = this.states.get(channelId);
271
+ appendToBlock(chatId, kind, delta) {
272
+ let state = this.states.get(chatId);
246
273
  if (!state) {
247
274
  // Auto-create state if onPromptSent wasn't called (e.g. host-initiated turns)
248
275
  state = { blocks: [], flushTimer: null, lastEditMs: 0, sendChain: Promise.resolve() };
249
- this.states.set(channelId, state);
276
+ this.states.set(chatId, state);
250
277
  }
251
278
  const last = state.blocks.at(-1);
252
279
  if (last && !last.sealed && last.kind === kind) {
@@ -264,30 +291,27 @@ export class BlockRenderer {
264
291
  }
265
292
  this.enqueueFlush(state, last);
266
293
  }
267
- state.blocks.push({ channelId, kind, content: delta, ref: null, creating: false, sealed: false });
294
+ state.blocks.push({ chatId, kind, content: delta, ref: null, creating: false, sealed: false });
268
295
  }
269
- this.scheduleFlush(channelId, state);
296
+ this.scheduleFlush(chatId, state);
270
297
  }
271
- scheduleFlush(channelId, state) {
298
+ scheduleFlush(chatId, state) {
272
299
  if (state.flushTimer)
273
300
  return; // already scheduled
274
301
  state.flushTimer = setTimeout(() => {
275
302
  state.flushTimer = null;
276
- this.flush(channelId, state);
303
+ this.flush(chatId, state);
277
304
  }, this.flushIntervalMs);
278
305
  }
279
- flush(channelId, state) {
306
+ flush(chatId, state) {
280
307
  const block = state.blocks.at(-1);
281
308
  if (!block || block.sealed || !block.content)
282
309
  return;
283
- // Send-only mode: subclasses that don't override `editBlock` (e.g.
284
- // QQ Bot, where the platform has no edit support) would otherwise
285
- // POST a new message for every debounced flush, so the user sees a
286
- // partial chunk followed by the full message as two separate
287
- // deliveries. Defer intermediate sends; only `onTurnEnd` and block
288
- // boundary transitions inside `appendToBlock` (which seal the block
289
- // first) will actually POST.
290
- if (!this.editBlock) {
310
+ // Send-only mode (streaming=false): defer intermediate sends.
311
+ // Only sealed blocks (from onTurnEnd or block boundary transitions)
312
+ // will actually POST. This prevents the user seeing a partial chunk
313
+ // followed by the full message as two separate messages.
314
+ if (!this.streaming) {
291
315
  return;
292
316
  }
293
317
  const now = Date.now();
@@ -297,7 +321,7 @@ export class BlockRenderer {
297
321
  if (!state.flushTimer) {
298
322
  state.flushTimer = setTimeout(() => {
299
323
  state.flushTimer = null;
300
- this.flush(channelId, state);
324
+ this.flush(chatId, state);
301
325
  }, delay);
302
326
  }
303
327
  return;
@@ -317,13 +341,13 @@ export class BlockRenderer {
317
341
  if (block.ref === null && !block.creating) {
318
342
  // First send — use sentinel to prevent concurrent creates
319
343
  block.creating = true;
320
- block.ref = await this.sendBlock(block.channelId, block.kind, content);
344
+ block.ref = await this.sendBlock(block.chatId, block.kind, content);
321
345
  block.creating = false;
322
346
  state.lastEditMs = Date.now();
323
347
  }
324
- else if (block.ref !== null && !block.creating && this.editBlock) {
325
- // Subsequent update — edit in-place
326
- await this.editBlock(block.channelId, block.ref, block.kind, content, block.sealed);
348
+ else if (block.ref !== null && !block.creating && this.streaming && this.editBlock) {
349
+ // Subsequent update — edit in-place (streaming mode only)
350
+ await this.editBlock(block.chatId, block.ref, block.kind, content, block.sealed);
327
351
  state.lastEditMs = Date.now();
328
352
  }
329
353
  // else: create is in-flight (creating === true) — skip
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -29,6 +29,13 @@ export interface PluginManifest {
29
29
  configSchema?: Record<string, unknown>;
30
30
  capabilities?: PluginCapabilities;
31
31
  }
32
+ /** A command entry from the host's command list. */
33
+ export interface CommandEntry {
34
+ name: string;
35
+ description: string;
36
+ args?: string;
37
+ aliases?: string[];
38
+ }
32
39
  /** The three kinds of content blocks a plugin renders. */
33
40
  export type BlockKind = "text" | "thinking" | "tool";
34
41
  export interface VerboseConfig {
@@ -38,6 +45,18 @@ export interface VerboseConfig {
38
45
  showToolUse: boolean;
39
46
  }
40
47
  export interface BlockRendererOptions {
48
+ /**
49
+ * Whether the IM platform supports message editing (streaming mode).
50
+ *
51
+ * - `true` (default): blocks stream in real-time — `sendBlock()` creates
52
+ * the message, `editBlock()` updates it as more content arrives.
53
+ * - `false`: each block is held until complete, then sent once via
54
+ * `sendBlock()`. `editBlock()` is never called.
55
+ *
56
+ * Set to `false` for platforms that don't support editing sent messages
57
+ * (e.g. QQ Bot, WhatsApp, WeChat, LINE).
58
+ */
59
+ streaming?: boolean;
41
60
  /**
42
61
  * Debounce interval before flushing an unsealed block (ms).
43
62
  * Controls how often in-progress blocks are sent to the platform.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,KAAK,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC/B;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAMD,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,YAAY,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAClC;AAMD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,KAAK,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC/B;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAMD,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,YAAY,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAClC;AAMD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibearound/plugin-channel-sdk",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "VibeAround Plugin SDK — base classes and utilities for building channel plugins",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,6 +14,10 @@
14
14
  ".": {
15
15
  "import": "./dist/index.js",
16
16
  "types": "./dist/index.d.ts"
17
+ },
18
+ "./advanced": {
19
+ "import": "./dist/advanced.js",
20
+ "types": "./dist/advanced.d.ts"
17
21
  }
18
22
  },
19
23
  "scripts": {
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @vibearound/plugin-channel-sdk — Advanced / low-level API
3
+ *
4
+ * For plugins that need custom ACP lifecycle control instead of
5
+ * the standard `runChannelPlugin()` flow.
6
+ *
7
+ * Normal plugins should use the main entry point instead:
8
+ * ```ts
9
+ * import { runChannelPlugin, BlockRenderer } from "@vibearound/plugin-channel-sdk";
10
+ * ```
11
+ */
12
+
13
+ // Low-level ACP connection
14
+ export { connectToHost, stripExtPrefix, redirectConsoleToStderr } from "./connection.js";
15
+ export type { PluginInfo, ConnectResult, AgentInfo } from "./connection.js";
16
+
17
+ // All types (including internal ones)
18
+ export type {
19
+ Agent,
20
+ Client,
21
+ ContentBlock,
22
+ SessionNotification,
23
+ RequestPermissionRequest,
24
+ RequestPermissionResponse,
25
+ BlockKind,
26
+ VerboseConfig,
27
+ BlockRendererOptions,
28
+ PluginCapabilities,
29
+ PluginManifest,
30
+ PluginInitMeta,
31
+ } from "./types.js";
32
+
33
+ // Re-export high-level API too (so advanced users don't need two imports)
34
+ export { runChannelPlugin } from "./plugin.js";
35
+ export { BlockRenderer } from "./renderer.js";
36
+ export { extractErrorMessage } from "./errors.js";
37
+ export type {
38
+ ChannelBot,
39
+ ChannelPluginLogger,
40
+ CreateBotContext,
41
+ RunChannelPluginSpec,
42
+ VerboseOptions,
43
+ } from "./plugin.js";
package/src/connection.ts CHANGED
@@ -111,12 +111,18 @@ export async function connectToHost(
111
111
  // ---------------------------------------------------------------------------
112
112
 
113
113
  /**
114
- * Normalize ACP ext notification method names.
114
+ * Strip the `_` prefix from ACP extension method names.
115
115
  *
116
- * The ACP SDK prepends "_" to ext method names (e.g. "_channel/system_text").
117
- * Strip the prefix to get the canonical method name used in plugin.json.
116
+ * The Rust ACP SDK adds `_` when sending ext notifications on the wire,
117
+ * but the TypeScript ACP SDK does not strip it on receipt. This function
118
+ * normalizes the received method name so handlers can match the canonical
119
+ * name (e.g. `_va/system_text` → `va/system_text`).
120
+ *
121
+ * Note: when sending ext notifications FROM TypeScript TO the Rust host,
122
+ * the method name must include the `_` prefix manually (e.g. `_va/callback`)
123
+ * because the TypeScript SDK does not add it automatically.
118
124
  */
119
- export function normalizeExtMethod(method: string): string {
125
+ export function stripExtPrefix(method: string): string {
120
126
  return method.startsWith("_") ? method.slice(1) : method;
121
127
  }
122
128