@canonmsg/claude-code-plugin 0.14.11 → 0.14.12

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 (2) hide show
  1. package/dist/host.js +31 -31
  2. package/package.json +3 -3
package/dist/host.js CHANGED
@@ -26,9 +26,8 @@ import { execFileSync } from 'node:child_process';
26
26
  import { existsSync } from 'node:fs';
27
27
  import { query, } from '@anthropic-ai/claude-agent-sdk';
28
28
  import { isAnthropicImageAttachment, materializeMessageMedia, materializeReplyContextMedia, toAnthropicImageBlock, } from '@canonmsg/agent-sdk';
29
- import { CLAUDE_PERMISSION_MODE_OPTIONS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, buildCanonHostPrompt, buildConfiguredWorkspaceOptionsWithRoots, buildConversationEnvironmentKey, buildFirstPartyCodingRuntimeDescriptor, buildHydratedInboundContext, diffCanonMemberIds, buildPlanApprovalRequest, buildQuestionRequest, buildPublicWorkspaceRoots, buildPublicWorkspaceOptions, buildRuntimePresentationPolicy, DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, createConversationMetadataLoader, createRuntimeStatePublisher, EXECUTION_ENVIRONMENT_MODES, CanonClient, CanonStream, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, DEFAULT_RUNTIME_CAPABILITIES, HOST_ADMISSION_ACTIONS_DISABLED, ApprovalManager, ExecutionEnvironmentError, FINAL_MESSAGE_HANDOFF_MS, buildLocalRuntimeId, getActiveProfileLock, heartbeatLocalRuntimeEntry, normalizeTurnMetadata, prepareConversationEnvironment, resolveCanonAgent, initRTDBAuth, rtdbRead, rtdbWrite, loadHostSessionConfig, loadRuntimeSessionState, markLocalRuntimeStopped, releaseConversationEnvironment, saveRuntimeSessionState, clearRuntimeSessionState, publishHostAgentRuntime, publishHostSessionSnapshots, renderCanonHostInboundContent, resolveHostWorkspaceCwd, upsertLocalRuntimeEntry, } from '@canonmsg/core';
29
+ import { CLAUDE_PERMISSION_MODE_OPTIONS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, buildCanonHostPrompt, buildConfiguredWorkspaceOptionsWithRoots, buildConversationEnvironmentKey, buildFirstPartyCodingRuntimeDescriptor, buildHydratedInboundContext, diffCanonMemberIds, buildPlanApprovalRequest, buildQuestionRequest, buildPublicWorkspaceRoots, buildPublicWorkspaceOptions, buildRuntimePresentationPolicy, DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, createConversationMetadataLoader, createTurnOutputController, createRuntimeStatePublisher, EXECUTION_ENVIRONMENT_MODES, CanonClient, CanonStream, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, DEFAULT_RUNTIME_CAPABILITIES, HOST_ADMISSION_ACTIONS_DISABLED, ApprovalManager, ExecutionEnvironmentError, FINAL_MESSAGE_HANDOFF_MS, buildLocalRuntimeId, getActiveProfileLock, heartbeatLocalRuntimeEntry, normalizeTurnMetadata, prepareConversationEnvironment, resolveCanonAgent, initRTDBAuth, rtdbRead, rtdbWrite, loadHostSessionConfig, loadRuntimeSessionState, markLocalRuntimeStopped, releaseConversationEnvironment, saveRuntimeSessionState, clearRuntimeSessionState, publishHostAgentRuntime, publishHostSessionSnapshots, renderCanonHostInboundContent, resolveHostWorkspaceCwd, upsertLocalRuntimeEntry, } from '@canonmsg/core';
30
30
  import { buildInboundContextLines, decideAutoReply, } from './inbound-policy.js';
31
- import { createStreamingBuffer } from './streaming-buffer.js';
32
31
  import { runCli } from './cli-entry.js';
33
32
  import { decideClaudeToolPermissionForMode, parseAllowedNonOwnerClaudeTools, } from './tool-policy.js';
34
33
  import { buildClaudeFinalMessageId, createClaudeInputEnvelope, formatClaudeControlError, mergeClaudeModelOptions, resetClaudeCompletedTurnState, shouldDeliverClaudeFinal, } from './session-state.js';
@@ -923,40 +922,44 @@ function createSession(conversationId, environment, agentId, client, runtimeStat
923
922
  pendingReply: null,
924
923
  writeState: () => writeState(),
925
924
  writeTurn: () => writeTurn(),
925
+ clearStreaming: () => clearStreaming(),
926
926
  setRuntimeControlError: (controlId, value, error) => setRuntimeControlError(controlId, value, error),
927
927
  clearRuntimeControlError: (controlId) => clearRuntimeControlError(controlId),
928
928
  };
929
- const streamingBuffer = createStreamingBuffer({
929
+ const streamingOutput = createTurnOutputController({
930
+ turnId: `claude-${conversationId}`,
931
+ mode: 'delta',
930
932
  throttleMs: STREAMING_THROTTLE_MS,
931
- getText: () => session.streamingText,
932
- setText: (text) => {
933
- session.streamingText = text;
933
+ writeSnapshot: (snapshot) => {
934
+ if (session.closed)
935
+ return Promise.resolve();
936
+ const turnId = session.currentTurnId ?? snapshot.turnId;
937
+ session.streamingText = snapshot.text;
938
+ return runtimeState.writeStreaming(conversationId, {
939
+ text: snapshot.text,
940
+ status: snapshot.status,
941
+ messageId: turnId,
942
+ turnId,
943
+ });
934
944
  },
935
- getTimer: () => session.streamingTimer,
936
- setTimer: (timer) => {
937
- session.streamingTimer = timer;
938
- },
939
- onWrite: (text) => {
940
- runtimeState.writeStreaming(conversationId, {
941
- text,
942
- status: 'streaming',
943
- }).catch(() => { });
945
+ clearSnapshot: () => {
946
+ session.streamingText = '';
947
+ return runtimeState.clearStreaming(conversationId);
944
948
  },
945
949
  });
946
950
  // ── Per-session streaming helpers ──
947
951
  function flushStreaming() {
948
- streamingBuffer.flush();
952
+ streamingOutput.flush().catch(() => { });
949
953
  }
950
954
  function onStreamDelta(text) {
951
- streamingBuffer.append(text);
955
+ streamingOutput.appendDelta(text);
952
956
  }
953
957
  function isActiveTurnInterrupted() {
954
958
  const turnKey = session.activeInput?.turnKey;
955
959
  return Boolean(turnKey && session.interruptedTurnKeys.has(turnKey));
956
960
  }
957
961
  function clearStreaming() {
958
- streamingBuffer.clear();
959
- runtimeState.clearStreaming(conversationId).catch(() => { });
962
+ return streamingOutput.clear().catch(() => { });
960
963
  }
961
964
  function clearIdleResetTimer() {
962
965
  if (!session.idleResetTimer)
@@ -1004,7 +1007,7 @@ function createSession(conversationId, environment, agentId, client, runtimeStat
1004
1007
  session.state.state = 'running';
1005
1008
  session.turnState = 'streaming';
1006
1009
  stopVisibleWorkSignal();
1007
- streamingBuffer.replace(finalText);
1010
+ streamingOutput.replaceSnapshot(finalText, 'streaming').catch(() => { });
1008
1011
  writeState();
1009
1012
  writeTurn();
1010
1013
  client.setTyping(conversationId, true, 'typing').catch(() => { });
@@ -1218,6 +1221,8 @@ function createSession(conversationId, environment, agentId, client, runtimeStat
1218
1221
  session.pendingInputs.unshift(input);
1219
1222
  session.turnState = 'interrupted';
1220
1223
  stopVisibleWorkSignal();
1224
+ clearStreaming().catch(() => { });
1225
+ client.setTyping(conversationId, false).catch(() => { });
1221
1226
  writeTurn();
1222
1227
  void session.query.interrupt().catch(() => { });
1223
1228
  return;
@@ -1851,10 +1856,7 @@ export async function main() {
1851
1856
  });
1852
1857
  }
1853
1858
  }
1854
- if (session.streamingTimer)
1855
- clearTimeout(session.streamingTimer);
1856
- session.streamingText = '';
1857
- runtimeState.clearStreaming(conversationId).catch(() => { });
1859
+ session.clearStreaming().catch(() => { });
1858
1860
  if (session.idleResetTimer) {
1859
1861
  clearTimeout(session.idleResetTimer);
1860
1862
  session.idleResetTimer = null;
@@ -1883,6 +1885,8 @@ export async function main() {
1883
1885
  session.pendingFinalText = null;
1884
1886
  session.pendingFinalDelivery = null;
1885
1887
  session.turnState = 'interrupted';
1888
+ session.clearStreaming().catch(() => { });
1889
+ client.setTyping(conversationId, false).catch(() => { });
1886
1890
  if (session.state.state === 'running') {
1887
1891
  await session.query.interrupt().catch(() => { });
1888
1892
  }
@@ -1972,6 +1976,7 @@ export async function main() {
1972
1976
  });
1973
1977
  }
1974
1978
  }
1979
+ existing?.clearStreaming().catch(() => { });
1975
1980
  sessions.delete(convoId);
1976
1981
  runtimeState.clearSessionState(convoId).catch(() => { });
1977
1982
  runtimeState.clearTurnState(convoId).catch(() => { });
@@ -2426,6 +2431,8 @@ export async function main() {
2426
2431
  }
2427
2432
  session.pendingFinalText = null;
2428
2433
  session.turnState = 'interrupted';
2434
+ session.clearStreaming().catch(() => { });
2435
+ client.setTyping(convoId, false).catch(() => { });
2429
2436
  runtimeState.writeTurnState(convoId, {
2430
2437
  turnId: session.currentTurnId,
2431
2438
  state: 'interrupted',
@@ -2439,13 +2446,6 @@ export async function main() {
2439
2446
  if (isActive) {
2440
2447
  await session.query.interrupt();
2441
2448
  }
2442
- if (session.streamingTimer) {
2443
- clearTimeout(session.streamingTimer);
2444
- session.streamingTimer = null;
2445
- }
2446
- session.streamingText = '';
2447
- runtimeState.clearStreaming(convoId).catch(() => { });
2448
- client.setTyping(convoId, false).catch(() => { });
2449
2449
  await rtdbWrite(`/control/${convoId}/${agentId}/signal`, null).catch(() => { });
2450
2450
  }
2451
2451
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/claude-code-plugin",
3
- "version": "0.14.11",
3
+ "version": "0.14.12",
4
4
  "description": "Canon channel plugin for Claude Code — messaging where AI agents are first-class citizens",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,8 +31,8 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@anthropic-ai/claude-agent-sdk": "^0.2.101",
34
- "@canonmsg/agent-sdk": "^1.6.1",
35
- "@canonmsg/core": "^0.23.0",
34
+ "@canonmsg/agent-sdk": "^1.7.0",
35
+ "@canonmsg/core": "^0.24.0",
36
36
  "@modelcontextprotocol/sdk": "^1.12.0"
37
37
  },
38
38
  "engines": {