@canonmsg/claude-code-plugin 0.9.1 → 0.9.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.
@@ -0,0 +1,2 @@
1
+ export declare function isDirectExecution(moduleUrl: string): boolean;
2
+ export declare function runCli(moduleUrl: string, main: () => void | Promise<void>, onError: (error: unknown) => void): void;
@@ -0,0 +1,26 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ export function isDirectExecution(moduleUrl) {
5
+ const entry = process.argv[1];
6
+ if (!entry)
7
+ return false;
8
+ const abs = resolve(entry);
9
+ let real = abs;
10
+ try {
11
+ real = realpathSync(abs);
12
+ }
13
+ catch {
14
+ // argv[1] may not exist on disk in rare harnesses; fall back to abs
15
+ }
16
+ return (pathToFileURL(real).href === moduleUrl ||
17
+ pathToFileURL(abs).href === moduleUrl);
18
+ }
19
+ export function runCli(moduleUrl, main, onError) {
20
+ if (!isDirectExecution(moduleUrl)) {
21
+ return;
22
+ }
23
+ Promise.resolve()
24
+ .then(() => main())
25
+ .catch(onError);
26
+ }
package/dist/host.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export declare function main(): Promise<void>;
package/dist/host.js CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import { setDefaultResultOrder } from 'node:dns';
3
- setDefaultResultOrder('ipv4first');
4
3
  /**
5
4
  * Canon Agent SDK host wrapper — multi-session.
6
5
  *
@@ -23,15 +22,54 @@ setDefaultResultOrder('ipv4first');
23
22
  */
24
23
  import { parseArgs } from 'node:util';
25
24
  import { randomUUID } from 'node:crypto';
25
+ import { execFileSync } from 'node:child_process';
26
+ import { existsSync } from 'node:fs';
26
27
  import { query } from '@anthropic-ai/claude-agent-sdk';
27
28
  import { isAnthropicImageAttachment, materializeMessageMedia, toAnthropicImageBlock, } from '@canonmsg/agent-sdk';
28
- import { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, buildPublicWorkspaceOptions, EXECUTION_ENVIRONMENT_MODES, isEnabledFlag, CanonClient, CanonStream, clearTurnState, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, DEFAULT_RUNTIME_CAPABILITIES, ExecutionEnvironmentError, FINAL_MESSAGE_HANDOFF_MS, normalizeTurnMetadata, prepareConversationEnvironment, resolveCanonAgent, getActiveProfile, releaseLock, initRTDBAuth, rtdbRead, rtdbWrite, writeSessionState, clearSessionState, writeTurnState, releaseConversationEnvironment, } from '@canonmsg/core';
29
+ import { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, buildPublicWorkspaceOptions, EXECUTION_ENVIRONMENT_MODES, CanonClient, CanonStream, clearTurnState, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, DEFAULT_RUNTIME_CAPABILITIES, ExecutionEnvironmentError, FINAL_MESSAGE_HANDOFF_MS, normalizeTurnMetadata, prepareConversationEnvironment, resolveCanonAgent, getActiveProfile, releaseLock, initRTDBAuth, rtdbRead, rtdbWrite, writeSessionState, clearSessionState, writeTurnState, releaseConversationEnvironment, } from '@canonmsg/core';
29
30
  import { buildCanonHostPrompt, buildHydratedInboundContext, createConversationMetadataLoader, loadHostSessionConfig, publishHostAgentRuntime, renderCanonHostInboundContent, resolveHostWorkspaceCwd, } from './host-runtime.js';
30
31
  import { buildInboundContextLines, decideAutoReply, } from './inbound-policy.js';
31
32
  import { createStreamingBuffer } from './streaming-buffer.js';
33
+ import { runCli } from './cli-entry.js';
32
34
  let workingDir = process.cwd();
33
35
  let workspaceOptions = [];
34
36
  let runtimeModels = [];
37
+ let cachedClaudeCliPath;
38
+ // The SDK bundles a Bun-compiled `claude` Mach-O binary next to
39
+ // claude-agent-sdk-darwin-arm64. On some macOS setups that exact binary gets
40
+ // SIGKILL'd at launch (path-based code-sign enforcement) even though a
41
+ // byte-identical copy at ~/.local/bin/claude runs fine. Prefer whatever is on
42
+ // PATH; fall back to the bundled one.
43
+ function resolveClaudeCliPath() {
44
+ if (cachedClaudeCliPath !== undefined) {
45
+ return cachedClaudeCliPath ?? undefined;
46
+ }
47
+ const override = process.env.CANON_CLAUDE_CLI_PATH?.trim();
48
+ if (override) {
49
+ if (existsSync(override)) {
50
+ cachedClaudeCliPath = override;
51
+ console.error(`[canon-host] claude CLI override: ${override}`);
52
+ return override;
53
+ }
54
+ console.error(`[canon-host] CANON_CLAUDE_CLI_PATH=${override} not found; ignoring`);
55
+ }
56
+ try {
57
+ const resolved = execFileSync('/bin/sh', ['-c', 'command -v claude'], {
58
+ encoding: 'utf8',
59
+ }).trim();
60
+ if (resolved && existsSync(resolved)) {
61
+ cachedClaudeCliPath = resolved;
62
+ console.error(`[canon-host] claude CLI on PATH: ${resolved}`);
63
+ return resolved;
64
+ }
65
+ }
66
+ catch {
67
+ // `command -v` exits non-zero when claude isn't on PATH; fall through.
68
+ }
69
+ cachedClaudeCliPath = null;
70
+ console.error('[canon-host] claude CLI not on PATH; using SDK-bundled binary');
71
+ return undefined;
72
+ }
35
73
  function toModelOptions(models) {
36
74
  return models.map((model) => ({
37
75
  value: model.value,
@@ -52,13 +90,11 @@ async function loadSessionConfig(conversationId, agentId) {
52
90
  permissionMode: config?.permissionMode,
53
91
  };
54
92
  }
55
- const SESSION_EXECUTION_MODE_REQUIRED = 'Session execution mode required; please select a mode before starting the session.';
56
- function requireSessionExecutionMode(config) {
57
- const mode = config?.executionMode;
58
- if (!mode) {
59
- throw new ExecutionEnvironmentError(SESSION_EXECUTION_MODE_REQUIRED, SESSION_EXECUTION_MODE_REQUIRED);
60
- }
61
- return mode;
93
+ // Default to 'locked' (shared workspace) when no mode has been picked. The
94
+ // UI still lets owners flip to 'worktree'; this just stops sessions from
95
+ // failing closed when the mode has never been written.
96
+ function resolveSessionExecutionMode(config) {
97
+ return config?.executionMode ?? 'locked';
62
98
  }
63
99
  function resolveWorkspaceCwd(config) {
64
100
  return resolveHostWorkspaceCwd({
@@ -71,6 +107,7 @@ async function detectRuntimeModels(cwd) {
71
107
  const emptyPrompt = {
72
108
  async *[Symbol.asyncIterator]() { },
73
109
  };
110
+ const claudeCliPath = resolveClaudeCliPath();
74
111
  const probe = query({
75
112
  prompt: emptyPrompt,
76
113
  options: {
@@ -79,6 +116,7 @@ async function detectRuntimeModels(cwd) {
79
116
  permissionMode: 'default',
80
117
  cwd,
81
118
  settings: { forceLoginMethod: 'claudeai' },
119
+ ...(claudeCliPath ? { pathToClaudeCodeExecutable: claudeCliPath } : {}),
82
120
  },
83
121
  });
84
122
  try {
@@ -200,6 +238,7 @@ function createSession(conversationId, environment, agentId, client, onSessionEn
200
238
  };
201
239
  });
202
240
  }
241
+ const claudeCliPath = resolveClaudeCliPath();
203
242
  const queryOptions = {
204
243
  systemPrompt: { type: 'preset', preset: 'claude_code' },
205
244
  tools: { type: 'preset', preset: 'claude_code' },
@@ -208,6 +247,14 @@ function createSession(conversationId, environment, agentId, client, onSessionEn
208
247
  includePartialMessages: true,
209
248
  maxTurns: 200,
210
249
  settings: { forceLoginMethod: 'claudeai' },
250
+ settingSources: ['project', 'local'],
251
+ ...(claudeCliPath ? { pathToClaudeCodeExecutable: claudeCliPath } : {}),
252
+ stderr: (data) => {
253
+ const trimmed = data.toString().trim();
254
+ if (trimmed) {
255
+ console.error(`[claude-cli] [${conversationId.slice(0, 8)}] ${trimmed}`);
256
+ }
257
+ },
211
258
  canUseTool: async (toolName, input) => {
212
259
  if (toolName === 'AskUserQuestion') {
213
260
  try {
@@ -666,22 +713,18 @@ function createSession(conversationId, environment, agentId, client, onSessionEn
666
713
  return session;
667
714
  }
668
715
  // ── Main ────────────────────────────────────────────────────────────
669
- async function main() {
716
+ export async function main() {
717
+ setDefaultResultOrder('ipv4first');
670
718
  const { values: args } = parseArgs({
671
719
  options: {
672
720
  cwd: { type: 'string' },
673
721
  workspace: { type: 'string', multiple: true },
674
- 'enable-worktrees': { type: 'boolean' },
675
722
  },
676
723
  strict: false,
677
724
  });
678
725
  workingDir = (typeof args.cwd === 'string' ? args.cwd : null) || process.cwd();
679
726
  const configuredWorkspaces = (args.workspace ?? []).filter((value) => typeof value === 'string');
680
727
  workspaceOptions = buildConfiguredWorkspaceOptions(workingDir, configuredWorkspaces);
681
- const allowWorktrees = isEnabledFlag(args['enable-worktrees'] ?? process.env.CANON_ENABLE_WORKTREES);
682
- if (!allowWorktrees) {
683
- console.error('[canon-host] Worktree isolation is disabled; sessions will lock their selected workspace unless explicitly enabled.');
684
- }
685
728
  const { apiKey, agentId: profileAgentId, profile } = resolveCanonAgent({ logPrefix: '[canon-host]' });
686
729
  console.error(`[canon-host] Starting${profile ? ` (profile: ${profile})` : ''} in ${workingDir}`);
687
730
  // ── Canon API client + RTDB auth ──
@@ -706,9 +749,9 @@ async function main() {
706
749
  console.error(`[canon-host] Authenticated as ${agentId}`);
707
750
  }
708
751
  let streamConnected = false;
709
- const hostAvailableExecutionModes = allowWorktrees
710
- ? [...EXECUTION_ENVIRONMENT_MODES]
711
- : ['locked'];
752
+ const hostAvailableExecutionModes = [
753
+ ...EXECUTION_ENVIRONMENT_MODES,
754
+ ];
712
755
  let runtimeDescriptor = {
713
756
  defaultWorkspaceId: workspaceOptions[0]?.id,
714
757
  defaultPermissionMode: 'default',
@@ -833,10 +876,7 @@ async function main() {
833
876
  }
834
877
  const creation = (async () => {
835
878
  const config = await loadSessionConfig(conversationId, agentId);
836
- const sessionExecutionMode = requireSessionExecutionMode(config);
837
- if (sessionExecutionMode === 'worktree' && !allowWorktrees) {
838
- throw new ExecutionEnvironmentError('This host does not allow worktree sessions (launched without --enable-worktrees).', 'This Canon host was started without worktree isolation enabled. Choose "Lock the workspace" or restart the host with --enable-worktrees.');
839
- }
879
+ const sessionExecutionMode = resolveSessionExecutionMode(config);
840
880
  const workspaceCwd = resolveWorkspaceCwd(config);
841
881
  const environment = prepareConversationEnvironment({
842
882
  agentId,
@@ -1156,7 +1196,7 @@ async function main() {
1156
1196
  await new Promise(() => { });
1157
1197
  }
1158
1198
  // ── Entry ───────────────────────────────────────────────────────────
1159
- main().catch((err) => {
1199
+ runCli(import.meta.url, main, (err) => {
1160
1200
  console.error('[canon-host] Fatal error:', err);
1161
1201
  const ap = getActiveProfile();
1162
1202
  if (ap)
@@ -0,0 +1,4 @@
1
+ export { main as serverMain } from './server.js';
2
+ export { main as hostMain } from './host.js';
3
+ export { main as registerMain } from './register.js';
4
+ export { main as setupMain } from './setup.js';
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { main as serverMain } from './server.js';
2
+ export { main as hostMain } from './host.js';
3
+ export { main as registerMain } from './register.js';
4
+ export { main as setupMain } from './setup.js';
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export declare function main(): Promise<void>;
package/dist/register.js CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import { setDefaultResultOrder } from 'node:dns';
3
- setDefaultResultOrder('ipv4first');
4
3
  /**
5
4
  * CLI script for Canon agent registration.
6
5
  * Invoked by the /canon-register skill.
@@ -15,80 +14,88 @@ import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
15
14
  import { join } from 'node:path';
16
15
  import { homedir } from 'node:os';
17
16
  import { parseArgs } from 'node:util';
17
+ import { runCli } from './cli-entry.js';
18
18
  const CANON_DIR = join(homedir(), '.canon');
19
19
  const AGENTS_PATH = join(CANON_DIR, 'agents.json');
20
- const { values } = parseArgs({
21
- options: {
22
- name: { type: 'string' },
23
- description: { type: 'string' },
24
- phone: { type: 'string' },
25
- profile: { type: 'string' },
26
- 'base-url': { type: 'string' },
27
- },
28
- strict: true,
29
- });
30
- if (!values.name || !values.description || !values.phone) {
31
- console.error('Usage: node register.js --name "Agent Name" --description "Description" --phone "+15551234567" [--profile "my-agent"]');
32
- process.exit(1);
33
- }
34
- // Default profile name: sanitized agent name
35
- const profileName = values.profile || values.name.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-');
36
- let existingAgentId;
37
- try {
38
- const profiles = JSON.parse(readFileSync(AGENTS_PATH, 'utf-8'));
39
- existingAgentId = profiles[profileName]?.agentId;
40
- }
41
- catch {
42
- // File doesn't exist yet
43
- }
44
- console.log(`Registering agent "${values.name}" (profile: ${profileName})...`);
45
- const result = await registerAndWaitForApproval({
46
- name: values.name,
47
- description: values.description,
48
- ownerPhone: values.phone,
49
- developerInfo: 'Claude Code plugin',
50
- clientType: 'claude-code',
51
- baseUrl: values['base-url'],
52
- requestedAgentId: existingAgentId,
53
- }, {
54
- onSubmitted: (requestId) => {
55
- console.log(`Registration submitted (request ID: ${requestId}).`);
56
- console.log('Waiting for approval in Canon app...');
57
- },
58
- onPollUpdate: () => {
59
- process.stdout.write('.');
60
- },
61
- });
62
- console.log(''); // newline after dots
63
- switch (result.status) {
64
- case 'approved': {
65
- // Save to ~/.canon/agents.json
66
- mkdirSync(CANON_DIR, { recursive: true });
67
- let profiles = {};
68
- try {
69
- profiles = JSON.parse(readFileSync(AGENTS_PATH, 'utf-8'));
70
- }
71
- catch {
72
- // File doesn't exist yet
20
+ export async function main() {
21
+ setDefaultResultOrder('ipv4first');
22
+ const { values } = parseArgs({
23
+ options: {
24
+ name: { type: 'string' },
25
+ description: { type: 'string' },
26
+ phone: { type: 'string' },
27
+ profile: { type: 'string' },
28
+ 'base-url': { type: 'string' },
29
+ },
30
+ strict: true,
31
+ });
32
+ if (!values.name || !values.description || !values.phone) {
33
+ console.error('Usage: node register.js --name "Agent Name" --description "Description" --phone "+15551234567" [--profile "my-agent"]');
34
+ process.exit(1);
35
+ }
36
+ // Default profile name: sanitized agent name
37
+ const profileName = values.profile || values.name.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-');
38
+ let existingAgentId;
39
+ try {
40
+ const profiles = JSON.parse(readFileSync(AGENTS_PATH, 'utf-8'));
41
+ existingAgentId = profiles[profileName]?.agentId;
42
+ }
43
+ catch {
44
+ // File doesn't exist yet
45
+ }
46
+ console.log(`Registering agent "${values.name}" (profile: ${profileName})...`);
47
+ const result = await registerAndWaitForApproval({
48
+ name: values.name,
49
+ description: values.description,
50
+ ownerPhone: values.phone,
51
+ developerInfo: 'Claude Code plugin',
52
+ clientType: 'claude-code',
53
+ baseUrl: values['base-url'],
54
+ requestedAgentId: existingAgentId,
55
+ }, {
56
+ onSubmitted: (requestId) => {
57
+ console.log(`Registration submitted (request ID: ${requestId}).`);
58
+ console.log('Waiting for approval in Canon app...');
59
+ },
60
+ onPollUpdate: () => {
61
+ process.stdout.write('.');
62
+ },
63
+ });
64
+ console.log(''); // newline after dots
65
+ switch (result.status) {
66
+ case 'approved': {
67
+ // Save to ~/.canon/agents.json
68
+ mkdirSync(CANON_DIR, { recursive: true });
69
+ let profiles = {};
70
+ try {
71
+ profiles = JSON.parse(readFileSync(AGENTS_PATH, 'utf-8'));
72
+ }
73
+ catch {
74
+ // File doesn't exist yet
75
+ }
76
+ profiles[profileName] = {
77
+ apiKey: result.apiKey,
78
+ agentId: result.agentId,
79
+ agentName: result.agentName,
80
+ registeredAt: new Date().toISOString(),
81
+ };
82
+ writeFileSync(AGENTS_PATH, JSON.stringify(profiles, null, 2));
83
+ console.log(`Approved! Agent: ${result.agentName} (${result.agentId})`);
84
+ console.log(`Saved as profile "${profileName}" in ~/.canon/agents.json`);
85
+ console.log('Restart Claude Code to connect.');
86
+ break;
73
87
  }
74
- profiles[profileName] = {
75
- apiKey: result.apiKey,
76
- agentId: result.agentId,
77
- agentName: result.agentName,
78
- registeredAt: new Date().toISOString(),
79
- };
80
- writeFileSync(AGENTS_PATH, JSON.stringify(profiles, null, 2));
81
- console.log(`Approved! Agent: ${result.agentName} (${result.agentId})`);
82
- console.log(`Saved as profile "${profileName}" in ~/.canon/agents.json`);
83
- console.log('Restart Claude Code to connect.');
84
- break;
88
+ case 'rejected':
89
+ console.log('Registration was rejected.');
90
+ process.exit(1);
91
+ break;
92
+ case 'timeout':
93
+ console.log('Registration timed out (5 minutes). Try again later.');
94
+ process.exit(1);
95
+ break;
85
96
  }
86
- case 'rejected':
87
- console.log('Registration was rejected.');
88
- process.exit(1);
89
- break;
90
- case 'timeout':
91
- console.log('Registration timed out (5 minutes). Try again later.');
92
- process.exit(1);
93
- break;
94
97
  }
98
+ runCli(import.meta.url, main, (error) => {
99
+ console.error('[canon-register] Fatal error:', error);
100
+ process.exit(1);
101
+ });
package/dist/server.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export declare function main(): Promise<void>;
package/dist/server.js CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import { setDefaultResultOrder } from 'node:dns';
3
- setDefaultResultOrder('ipv4first');
4
3
  /**
5
4
  * Canon channel MCP server for Claude Code.
6
5
  *
@@ -13,6 +12,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
13
12
  import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
14
13
  import { CanonClient, CanonStream, ApprovalManager, loadProfiles, isProfileLocked, resolveCanonAgent, getActiveProfile, releaseLock, initRTDBAuth, writeSessionState, clearSessionState, } from '@canonmsg/core';
15
14
  import { ApprovalHttpServer } from './approval-server.js';
15
+ import { runCli } from './cli-entry.js';
16
16
  // ── MCP server ─────────────────────────────────────────────────────────
17
17
  const server = new Server({ name: 'canon-channel', version: '0.1.0' }, {
18
18
  capabilities: {
@@ -593,7 +593,8 @@ async function startChannel() {
593
593
  }
594
594
  }
595
595
  // ── Main ───────────────────────────────────────────────────────────────
596
- async function main() {
596
+ export async function main() {
597
+ setDefaultResultOrder('ipv4first');
597
598
  const transport = new StdioServerTransport();
598
599
  await server.connect(transport);
599
600
  // Start the Canon channel after MCP connection is established
@@ -617,7 +618,7 @@ async function main() {
617
618
  process.on('SIGINT', shutdown);
618
619
  process.on('SIGTERM', shutdown);
619
620
  }
620
- main().catch((err) => {
621
+ runCli(import.meta.url, main, (err) => {
621
622
  console.error('[canon] Fatal error:', err);
622
623
  process.exit(1);
623
624
  });
package/dist/setup.d.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  * 1. Install the /canon-register and /canon-configure skills
7
7
  * 2. Show the user how to add the MCP server to their .mcp.json
8
8
  */
9
- export {};
9
+ export declare function main(): void;
package/dist/setup.js CHANGED
@@ -9,6 +9,7 @@
9
9
  import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'node:fs';
10
10
  import { join, dirname } from 'node:path';
11
11
  import { fileURLToPath } from 'node:url';
12
+ import { runCli } from './cli-entry.js';
12
13
  const __dirname = dirname(fileURLToPath(import.meta.url));
13
14
  const home = process.env.HOME || process.env.USERPROFILE || '';
14
15
  const skillsDir = join(home, '.claude', 'skills');
@@ -55,12 +56,18 @@ Then start Claude Code with:
55
56
  `);
56
57
  }
57
58
  // ── Main ───────────────────────────────────────────────────────────────
58
- console.log('Canon Claude Code Plugin Setup');
59
- console.log('==============================\n');
60
- console.log('Installing skills...');
61
- installSkills();
62
- console.log('\nRegistering your agent...');
63
- console.log(' Run /canon-register in Claude Code to register a new agent');
64
- console.log(' Run /canon-configure if you already have an API key\n');
65
- console.log('MCP server configuration:');
66
- showMcpInstructions();
59
+ export function main() {
60
+ console.log('Canon Claude Code Plugin Setup');
61
+ console.log('==============================\n');
62
+ console.log('Installing skills...');
63
+ installSkills();
64
+ console.log('\nRegistering your agent...');
65
+ console.log(' Run /canon-register in Claude Code to register a new agent');
66
+ console.log(' Run /canon-configure if you already have an API key\n');
67
+ console.log('MCP server configuration:');
68
+ showMcpInstructions();
69
+ }
70
+ runCli(import.meta.url, main, (error) => {
71
+ console.error('[canon-setup] Fatal error:', error);
72
+ process.exit(1);
73
+ });
package/package.json CHANGED
@@ -1,9 +1,16 @@
1
1
  {
2
2
  "name": "@canonmsg/claude-code-plugin",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "Canon channel plugin for Claude Code — messaging where AI agents are first-class citizens",
5
5
  "type": "module",
6
- "main": "dist/server.js",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
7
14
  "bin": {
8
15
  "canon-channel-server": "dist/server.js",
9
16
  "canon-claude": "dist/host.js",
@@ -24,7 +31,7 @@
24
31
  "dependencies": {
25
32
  "@anthropic-ai/claude-agent-sdk": "^0.2.101",
26
33
  "@canonmsg/agent-sdk": "^0.8.1",
27
- "@canonmsg/core": "^0.7.1",
34
+ "@canonmsg/core": "^0.7.2",
28
35
  "@modelcontextprotocol/sdk": "^1.12.0"
29
36
  },
30
37
  "engines": {