@canonmsg/claude-code-plugin 0.33.0 → 0.34.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.
@@ -1,5 +1,6 @@
1
- import type { PermissionMode, SDKMessageOrigin, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
1
+ import type { SDKMessageOrigin, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
2
2
  import type { DeliveryIntent, ModelOption, RuntimeStreamingPayload, TurnLifecycleState, TurnOutputBlock, TurnOutputSnapshot, TurnVerbosity } from '@canonmsg/core';
3
+ import type { AgentReplyAuthorityV1 } from '@canonmsg/backend-contracts';
3
4
  import type { TurnArtifactRoutingDecision, TurnArtifactSnapshot } from '@canonmsg/coding-agent-host';
4
5
  export type ClaudeInputKind = 'seed' | 'canon';
5
6
  export type ClaudeArtifactRoutingMode = 'workspace-generated' | 'disabled';
@@ -23,6 +24,8 @@ export interface ClaudeInputEnvelope {
23
24
  turnKey: string;
24
25
  isOwnerTurn: boolean;
25
26
  requestingUserId: string | null;
27
+ /** Opaque server capability; never rendered into the Claude prompt. */
28
+ replyAuthority: AgentReplyAuthorityV1 | null;
26
29
  }
27
30
  /**
28
31
  * The per-turn modes an inbound message resolves from its participant context,
@@ -31,6 +34,7 @@ export interface ClaudeInputEnvelope {
31
34
  export interface ClaudeTurnModes {
32
35
  artifactRoutingMode?: ClaudeArtifactRoutingMode;
33
36
  turnVerbosity?: TurnVerbosity;
37
+ replyAuthority?: AgentReplyAuthorityV1 | null;
34
38
  }
35
39
  export interface ClaudeRuntimeControlError {
36
40
  value: string;
@@ -102,6 +106,7 @@ export declare function createClaudeInputEnvelope(input: {
102
106
  artifactBaseline?: TurnArtifactSnapshot | null;
103
107
  isOwnerTurn?: boolean;
104
108
  requestingUserId?: string | null;
109
+ replyAuthority?: AgentReplyAuthorityV1 | null;
105
110
  }): ClaudeInputEnvelope;
106
111
  export declare function resolveClaudeTurnResponseRouting(turn: Pick<ClaudeInputEnvelope, 'kind' | 'isOwnerTurn' | 'requestingUserId'> | null | undefined, ownerId: string | null | undefined, ownerOnly?: boolean): {
107
112
  isOwnerTurn: boolean;
@@ -815,44 +820,3 @@ export declare function confirmClaudeInterrupt(input: {
815
820
  active: boolean;
816
821
  interrupt: () => Promise<unknown>;
817
822
  }): Promise<'confirmed' | 'defer'>;
818
- /** Requested session-control values from the control plane (raw, pre-validation). */
819
- export interface ClaudeSessionControlInput {
820
- model?: string;
821
- permissionMode?: string;
822
- effort?: string;
823
- ultracode?: string;
824
- }
825
- /** Mutable mirror of the live session's control state — mutated in place on success. */
826
- export interface ClaudeSessionControlState {
827
- model?: string;
828
- permissionMode?: string;
829
- effort?: string;
830
- ultracode?: string;
831
- }
832
- /**
833
- * Injected validators + side effects so the apply logic stays host-agnostic and
834
- * unit-testable. The host wires these to the live SDK query and its runtime
835
- * control-error bookkeeping; tests inject fakes.
836
- */
837
- export interface ClaudeSessionControlDeps {
838
- state: ClaudeSessionControlState;
839
- parsePermissionMode: (value: unknown) => PermissionMode | null;
840
- normalizeEffort: (value: unknown) => string | undefined;
841
- parseUltracode: (value: unknown) => string | undefined;
842
- setModel: (model: string) => Promise<void>;
843
- setPermissionMode: (mode: PermissionMode) => Promise<void>;
844
- applyEffort: (level: string) => Promise<void>;
845
- applyUltracode: (enabled: boolean) => Promise<void>;
846
- setRuntimeControlError: (controlId: string, value: string, error: unknown) => void;
847
- clearRuntimeControlError: (controlId: string) => void;
848
- publishSnapshot: () => void;
849
- }
850
- /**
851
- * Apply a session-control request to the live Claude session. Mirrors the host's
852
- * control semantics (validation, only-if-different checks, error recording,
853
- * clear-on-success). Whenever a live op is invoked — on success OR caught
854
- * failure — publishSnapshot() is called exactly once so the app-subscribed
855
- * /agent-session snapshot converges immediately instead of waiting for the next
856
- * heartbeat. If nothing changed, publishSnapshot() is not called.
857
- */
858
- export declare function applyClaudeSessionControl(control: ClaudeSessionControlInput, deps: ClaudeSessionControlDeps): Promise<void>;
@@ -28,6 +28,7 @@ export function createClaudeInputEnvelope(input) {
28
28
  requestingUserId: input.kind === 'canon' && input.requestingUserId
29
29
  ? input.requestingUserId
30
30
  : null,
31
+ replyAuthority: input.kind === 'canon' ? input.replyAuthority ?? null : null,
31
32
  turnKey: input.kind === 'canon' && sourceMessageId
32
33
  ? `canon:${sourceMessageId}`
33
34
  : `${input.kind}:${fallbackId}`,
@@ -1313,74 +1314,3 @@ export async function confirmClaudeInterrupt(input) {
1313
1314
  return 'defer';
1314
1315
  }
1315
1316
  }
1316
- /**
1317
- * Apply a session-control request to the live Claude session. Mirrors the host's
1318
- * control semantics (validation, only-if-different checks, error recording,
1319
- * clear-on-success). Whenever a live op is invoked — on success OR caught
1320
- * failure — publishSnapshot() is called exactly once so the app-subscribed
1321
- * /agent-session snapshot converges immediately instead of waiting for the next
1322
- * heartbeat. If nothing changed, publishSnapshot() is not called.
1323
- */
1324
- export async function applyClaudeSessionControl(control, deps) {
1325
- const { state } = deps;
1326
- let liveOpInvoked = false;
1327
- if (control.model && control.model !== state.model) {
1328
- liveOpInvoked = true;
1329
- try {
1330
- await deps.setModel(control.model);
1331
- state.model = control.model;
1332
- deps.clearRuntimeControlError('model');
1333
- }
1334
- catch (err) {
1335
- deps.setRuntimeControlError('model', control.model, err);
1336
- }
1337
- }
1338
- const nextPermissionMode = deps.parsePermissionMode(control.permissionMode);
1339
- if (control.permissionMode && !nextPermissionMode) {
1340
- deps.setRuntimeControlError('permissionMode', control.permissionMode, new Error(`Unsupported Claude permission mode: ${control.permissionMode}`));
1341
- }
1342
- else if (nextPermissionMode && nextPermissionMode !== state.permissionMode) {
1343
- liveOpInvoked = true;
1344
- try {
1345
- await deps.setPermissionMode(nextPermissionMode);
1346
- state.permissionMode = nextPermissionMode;
1347
- deps.clearRuntimeControlError('permissionMode');
1348
- }
1349
- catch (err) {
1350
- deps.setRuntimeControlError('permissionMode', nextPermissionMode, err);
1351
- }
1352
- }
1353
- const nextEffort = deps.normalizeEffort(control.effort);
1354
- if (nextEffort && nextEffort !== state.effort) {
1355
- liveOpInvoked = true;
1356
- try {
1357
- await deps.applyEffort(nextEffort);
1358
- state.effort = nextEffort;
1359
- deps.clearRuntimeControlError('effort');
1360
- }
1361
- catch (err) {
1362
- deps.setRuntimeControlError('effort', nextEffort, err);
1363
- }
1364
- }
1365
- else if (control.effort && !nextEffort) {
1366
- deps.setRuntimeControlError('effort', String(control.effort), new Error('Unsupported Claude thinking level.'));
1367
- }
1368
- const nextUltracode = deps.parseUltracode(control.ultracode);
1369
- if (control.ultracode && !nextUltracode) {
1370
- deps.setRuntimeControlError('ultracode', String(control.ultracode), new Error('Unsupported Claude ultracode mode.'));
1371
- }
1372
- else if (nextUltracode && nextUltracode !== state.ultracode) {
1373
- liveOpInvoked = true;
1374
- try {
1375
- await deps.applyUltracode(nextUltracode === 'on');
1376
- state.ultracode = nextUltracode;
1377
- deps.clearRuntimeControlError('ultracode');
1378
- }
1379
- catch (err) {
1380
- deps.setRuntimeControlError('ultracode', nextUltracode, err);
1381
- }
1382
- }
1383
- if (liveOpInvoked) {
1384
- deps.publishSnapshot();
1385
- }
1386
- }
@@ -57,7 +57,6 @@ const CANON_HITL_OR_READ_VERBS = new Set([
57
57
  'send_card',
58
58
  'request_card',
59
59
  'list_contacts',
60
- 'list_contact_requests',
61
60
  'list_conversations',
62
61
  // Staying quiet posts nothing; an approval card asking permission for
63
62
  // silence would gate a no-op behind a human decision.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/claude-code-plugin",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
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,11 +31,11 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@anthropic-ai/claude-agent-sdk": "0.3.228",
34
- "@canonmsg/agent-sdk": "^9.0.0",
35
- "@canonmsg/agent-tools": "^0.7.0",
34
+ "@canonmsg/agent-sdk": "^10.0.0",
35
+ "@canonmsg/agent-tools": "^0.8.0",
36
36
  "@canonmsg/coding-agent-host": "^0.7.0",
37
- "@canonmsg/core": "^11.0.0",
38
- "@canonmsg/rich-cards": "^0.10.3",
37
+ "@canonmsg/core": "^12.0.0",
38
+ "@canonmsg/rich-cards": "^0.10.4",
39
39
  "@modelcontextprotocol/sdk": "^1.30.0"
40
40
  },
41
41
  "engines": {