@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.
- package/dist/cli-entry.d.ts +2 -0
- package/dist/cli-entry.js +26 -0
- package/dist/host.d.ts +1 -1
- package/dist/host.js +63 -23
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/register.d.ts +1 -1
- package/dist/register.js +80 -73
- package/dist/server.d.ts +1 -1
- package/dist/server.js +4 -3
- package/dist/setup.d.ts +1 -1
- package/dist/setup.js +16 -9
- package/package.json +10 -3
|
@@ -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,
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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 =
|
|
710
|
-
|
|
711
|
-
|
|
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 =
|
|
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
|
-
|
|
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)
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/dist/register.d.ts
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
profiles =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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
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
|
-
|
|
59
|
-
console.log('
|
|
60
|
-
console.log('
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
console.log('
|
|
64
|
-
console.log(' Run /canon-
|
|
65
|
-
console.log('
|
|
66
|
-
|
|
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.
|
|
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/
|
|
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.
|
|
34
|
+
"@canonmsg/core": "^0.7.2",
|
|
28
35
|
"@modelcontextprotocol/sdk": "^1.12.0"
|
|
29
36
|
},
|
|
30
37
|
"engines": {
|