@canonmsg/claude-code-plugin 0.26.1 → 0.27.1
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/.claude-plugin/plugin.json +1 -1
- package/README.md +10 -2
- package/dist/host.js +14 -5
- package/dist/register.js +34 -15
- package/dist/server.js +14 -7
- package/package.json +5 -5
- package/skills/register/SKILL.md +3 -1
package/README.md
CHANGED
|
@@ -10,6 +10,9 @@ The package includes a compatible Claude Code runtime. If `claude` is installed
|
|
|
10
10
|
# Install
|
|
11
11
|
npm install -g @canonmsg/claude-code-plugin
|
|
12
12
|
|
|
13
|
+
# Select the Canon trust domain supplied for your account
|
|
14
|
+
export CANON_ENVIRONMENT_ID=canon-legacy-v1
|
|
15
|
+
|
|
13
16
|
# Register (approve in Canon app when prompted)
|
|
14
17
|
canon-register --name "My Claude" --description "My Claude Code agent" --phone "+15551234567"
|
|
15
18
|
|
|
@@ -19,6 +22,11 @@ canon-claude
|
|
|
19
22
|
|
|
20
23
|
Send a message to your agent in the Canon app. Owner-originated turns use your selected Claude permission mode; non-owner turns can still get text replies but do not get local shell/filesystem/web, MCP, or Canon outbound tool access by default. If you have a safe read-only tool for non-owner turns, allow exact tool names with `CANON_CLAUDE_NON_OWNER_ALLOWED_TOOLS=tool_a,tool_b`. `canon-claude` is the local agent process. Keep that terminal open while you want Canon to reach the agent. Closing it, logging out, rebooting, or sleeping long enough to stop the process takes this local agent offline until you revive it.
|
|
21
24
|
|
|
25
|
+
Registration verifies the selected Canon API and stream before sending the
|
|
26
|
+
request, then stores the environment ID and complete endpoint snapshot beside
|
|
27
|
+
the credential in `~/.canon/agents.json`. Older unbound profiles must be
|
|
28
|
+
reconnected or migrated before a new host will start them.
|
|
29
|
+
|
|
22
30
|
After a restart or closed terminal, use the shared local manager to list and revive all recorded local agents:
|
|
23
31
|
|
|
24
32
|
```bash
|
|
@@ -65,7 +73,7 @@ Current Canon truth for Claude host mode:
|
|
|
65
73
|
## Multiple agents
|
|
66
74
|
|
|
67
75
|
```bash
|
|
68
|
-
canon-register --name "Frontend" --description "React work" --phone "+1..." --profile frontend
|
|
76
|
+
canon-register --environment canon-legacy-v1 --name "Frontend" --description "React work" --phone "+1..." --profile frontend
|
|
69
77
|
CANON_AGENT=frontend canon-claude --cwd ~/projects/frontend
|
|
70
78
|
```
|
|
71
79
|
|
|
@@ -80,7 +88,7 @@ Register the channel server with Claude Code's MCP config and provide your Canon
|
|
|
80
88
|
claude mcp add canon-channel canon-channel-server
|
|
81
89
|
|
|
82
90
|
# Then start Claude Code with your Canon key in the environment
|
|
83
|
-
CANON_API_KEY=agk_live_... claude
|
|
91
|
+
CANON_API_KEY=agk_live_... CANON_ENVIRONMENT_ID=canon-legacy-v1 claude
|
|
84
92
|
```
|
|
85
93
|
|
|
86
94
|
Channel mode forwards messages between Canon conversations and the embedded Claude Code session without managing session lifecycle. It is shown as non-revivable by `canon-necromance`. Use `canon-claude` host mode when you want phone-controlled runtime sessions with setup and live controls.
|
package/dist/host.js
CHANGED
|
@@ -18,7 +18,7 @@ import { setDefaultResultOrder } from 'node:dns';
|
|
|
18
18
|
* canon-claude # auto-select agent profile
|
|
19
19
|
* canon-claude --cwd /path/to/project # specify working directory
|
|
20
20
|
* CANON_AGENT=mybot canon-claude # use specific profile
|
|
21
|
-
* CANON_API_KEY=agk_... canon-claude # use explicit key
|
|
21
|
+
* CANON_ENVIRONMENT_ID=canon-legacy-v1 CANON_API_KEY=agk_... canon-claude # use explicit key
|
|
22
22
|
*/
|
|
23
23
|
import { parseArgs } from 'node:util';
|
|
24
24
|
import { randomUUID } from 'node:crypto';
|
|
@@ -28,7 +28,7 @@ import { readFile } from 'node:fs/promises';
|
|
|
28
28
|
import { query, } from '@anthropic-ai/claude-agent-sdk';
|
|
29
29
|
import { isAnthropicImageAttachment, materializeMessageMedia, materializeReplyContextMedia, sendMediaFileMessage, toAnthropicImageBlock, } from '@canonmsg/agent-sdk';
|
|
30
30
|
import { captureTurnArtifactSnapshot, collectTurnArtifacts, } from '@canonmsg/coding-agent-host';
|
|
31
|
-
import { CLAUDE_EFFORT_OPTIONS, CLAUDE_PERMISSION_MODE_OPTIONS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, buildCanonInboundFrameV1, buildCanonTurnContextV2, buildConfiguredWorkspaceOptionsWithRoots, buildConversationEnvironmentKey, buildFirstPartyCodingRuntimeDescriptor, buildHydratedInboundContext, diffCanonMemberIds, buildPublicWorkspaceRoots, buildPublicWorkspaceOptions, buildRuntimePresentationPolicy, normalizeRuntimeCommandDescriptors, DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, createConversationMetadataLoader, createTurnOutputController, createRuntimeStatePublisher, createTypingStatusPublisher, EXECUTION_ENVIRONMENT_MODES, CanonClient, CanonStream, ControlChannelPoller, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, DEFAULT_RUNTIME_CAPABILITIES, HOST_ADMISSION_ACTIONS_DISABLED, ApprovalManager, RuntimeRequestManager, ExecutionEnvironmentError, FINAL_MESSAGE_HANDOFF_MS, buildLocalRuntimeId, getActiveProfileLock, heartbeatLocalRuntimeEntry, normalizeTurnMetadata, prepareConversationEnvironment, readLocalRuntimeEntry, resolveCanonAgent, initRTDBAuth, sendMessageWithRetry, loadHostSessionConfig, loadRuntimeSessionState, markLocalRuntimeStopped, releaseConversationEnvironment, saveRuntimeSessionState, clearRuntimeSessionState, publishHostAgentRuntime, publishHostSessionSnapshots, renderCanonHostInboundContent, renderCodingHostInboundPrompt, resolveHostWorkspaceCwd, shouldTriggerAgentTurn, upsertLocalRuntimeEntry, } from '@canonmsg/core';
|
|
31
|
+
import { CLAUDE_EFFORT_OPTIONS, CLAUDE_PERMISSION_MODE_OPTIONS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, buildCanonInboundFrameV1, buildCanonTurnContextV2, buildConfiguredWorkspaceOptionsWithRoots, buildConversationEnvironmentKey, buildFirstPartyCodingRuntimeDescriptor, buildHydratedInboundContext, diffCanonMemberIds, buildPublicWorkspaceRoots, buildPublicWorkspaceOptions, buildRuntimePresentationPolicy, normalizeRuntimeCommandDescriptors, DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, createConversationMetadataLoader, createTurnOutputController, createRuntimeStatePublisher, createTypingStatusPublisher, EXECUTION_ENVIRONMENT_MODES, CanonClient, CanonStream, ControlChannelPoller, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, DEFAULT_RUNTIME_CAPABILITIES, HOST_ADMISSION_ACTIONS_DISABLED, ApprovalManager, RuntimeRequestManager, ExecutionEnvironmentError, FINAL_MESSAGE_HANDOFF_MS, buildLocalRuntimeId, getActiveProfileLock, heartbeatLocalRuntimeEntry, normalizeTurnMetadata, prepareConversationEnvironment, readLocalRuntimeEntry, resolveCanonAgent, verifyResolvedAgentEnvironment, initRTDBAuth, sendMessageWithRetry, loadHostSessionConfig, loadRuntimeSessionState, markLocalRuntimeStopped, releaseConversationEnvironment, saveRuntimeSessionState, clearRuntimeSessionState, publishHostAgentRuntime, publishHostSessionSnapshots, renderCanonHostInboundContent, renderCodingHostInboundPrompt, resolveHostWorkspaceCwd, shouldTriggerAgentTurn, upsertLocalRuntimeEntry, } from '@canonmsg/core';
|
|
32
32
|
import { decideAutoReply, } from './inbound-policy.js';
|
|
33
33
|
import { runCli } from './cli-entry.js';
|
|
34
34
|
import { CANON_VERB_MCP_SERVER_NAME, createCanonVerbMcpServer } from '@canonmsg/agent-tools';
|
|
@@ -65,7 +65,7 @@ COMMON FLAGS
|
|
|
65
65
|
|
|
66
66
|
AUTH
|
|
67
67
|
CANON_AGENT=<profile> canon-claude --cwd /path/to/project
|
|
68
|
-
CANON_API_KEY=agk_live_... canon-claude --cwd /path/to/project
|
|
68
|
+
CANON_ENVIRONMENT_ID=<id> CANON_API_KEY=agk_live_... canon-claude --cwd /path/to/project
|
|
69
69
|
|
|
70
70
|
EXAMPLES
|
|
71
71
|
canon-claude --cwd ~/dev/canon
|
|
@@ -1825,11 +1825,19 @@ export async function main() {
|
|
|
1825
1825
|
for (const warning of workspaceDiscovery.warnings) {
|
|
1826
1826
|
console.error(`[canon-host] ${warning}`);
|
|
1827
1827
|
}
|
|
1828
|
-
const
|
|
1828
|
+
const resolvedAgent = resolveCanonAgent({ logPrefix: '[canon-host]', expectedClientType: 'claude-code' });
|
|
1829
|
+
const { apiKey, agentId: profileAgentId, agentName: profileAgentName, profile, baseUrl, streamUrl, rtdbUrl, firebaseApiKey, lockHandle, } = resolvedAgent;
|
|
1829
1830
|
console.error(`[canon-host] Starting${profile ? ` (profile: ${profile})` : ''} in ${workingDir}`);
|
|
1831
|
+
try {
|
|
1832
|
+
await verifyResolvedAgentEnvironment(resolvedAgent);
|
|
1833
|
+
}
|
|
1834
|
+
catch (error) {
|
|
1835
|
+
lockHandle?.release();
|
|
1836
|
+
throw error;
|
|
1837
|
+
}
|
|
1830
1838
|
// ── Canon API client + RTDB auth ──
|
|
1831
1839
|
const client = new CanonClient(apiKey, baseUrl);
|
|
1832
|
-
const rtdb = initRTDBAuth(client);
|
|
1840
|
+
const rtdb = initRTDBAuth(client, { rtdbUrl, firebaseApiKey });
|
|
1833
1841
|
const typingSignals = createTypingStatusPublisher({
|
|
1834
1842
|
setTyping: (conversationId, typing, status) => status
|
|
1835
1843
|
? client.setTyping(conversationId, typing, status)
|
|
@@ -2669,6 +2677,7 @@ export async function main() {
|
|
|
2669
2677
|
const stream = new CanonStream({
|
|
2670
2678
|
apiKey,
|
|
2671
2679
|
agentId,
|
|
2680
|
+
streamUrl,
|
|
2672
2681
|
handler: {
|
|
2673
2682
|
onMessage: (payload) => {
|
|
2674
2683
|
const m = payload.message;
|
package/dist/register.js
CHANGED
|
@@ -9,8 +9,7 @@ import { setDefaultResultOrder } from 'node:dns';
|
|
|
9
9
|
*
|
|
10
10
|
* On approval, saves the agent to ~/.canon/agents.json under the profile name.
|
|
11
11
|
*/
|
|
12
|
-
import { ackRegistrationApproval, clearPendingRegistration, getOrCreatePendingRegistration, registerAndWaitForApproval, updatePendingRegistration, upsertAgentProfile,
|
|
13
|
-
import { readFileSync } from 'node:fs';
|
|
12
|
+
import { ackRegistrationApproval, clearPendingRegistration, getOrCreatePendingRegistration, loadProfiles, registerAndWaitForApproval, resolveCanonRuntimeConnection, updatePendingRegistration, upsertAgentProfile, verifyCanonRuntimeConnection, } from '@canonmsg/core';
|
|
14
13
|
import { parseArgs } from 'node:util';
|
|
15
14
|
import { runCli } from './cli-entry.js';
|
|
16
15
|
const HELP = `canon-register — register or reconnect a Claude Code agent in Canon
|
|
@@ -25,13 +24,17 @@ REQUIRED
|
|
|
25
24
|
|
|
26
25
|
FLAGS
|
|
27
26
|
--profile <name> Local profile name in ~/.canon/agents.json
|
|
27
|
+
--environment <id> Canon environment ID (or CANON_ENVIRONMENT_ID)
|
|
28
28
|
--base-url <url> Canon API base URL override
|
|
29
|
+
--stream-url <url> Canon stream URL override
|
|
30
|
+
--rtdb-url <url> Canon RTDB URL override
|
|
31
|
+
--firebase-api-key <key> Firebase web API key override (public config)
|
|
29
32
|
--help, -h Show this help
|
|
30
33
|
--version, -V Show package version
|
|
31
34
|
|
|
32
35
|
EXAMPLES
|
|
33
|
-
canon-register --name "My Claude" --description "Claude Code agent" --phone "+15551234567"
|
|
34
|
-
canon-register --name "Frontend" --description "React work" --phone "+15551234567" --profile frontend
|
|
36
|
+
canon-register --environment canon-legacy-v1 --name "My Claude" --description "Claude Code agent" --phone "+15551234567"
|
|
37
|
+
canon-register --environment canon-legacy-v1 --name "Frontend" --description "React work" --phone "+15551234567" --profile frontend
|
|
35
38
|
|
|
36
39
|
After approval, start it with CANON_AGENT=<profile> canon-claude --cwd /path/to/project.`;
|
|
37
40
|
export async function main() {
|
|
@@ -42,7 +45,11 @@ export async function main() {
|
|
|
42
45
|
description: { type: 'string' },
|
|
43
46
|
phone: { type: 'string' },
|
|
44
47
|
profile: { type: 'string' },
|
|
48
|
+
environment: { type: 'string' },
|
|
45
49
|
'base-url': { type: 'string' },
|
|
50
|
+
'stream-url': { type: 'string' },
|
|
51
|
+
'rtdb-url': { type: 'string' },
|
|
52
|
+
'firebase-api-key': { type: 'string' },
|
|
46
53
|
},
|
|
47
54
|
strict: true,
|
|
48
55
|
});
|
|
@@ -52,23 +59,31 @@ export async function main() {
|
|
|
52
59
|
}
|
|
53
60
|
// Default profile name: sanitized agent name
|
|
54
61
|
const profileName = values.profile || values.name.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-');
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
existingAgentId = profiles[profileName]?.agentId;
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
// File doesn't exist yet
|
|
62
|
+
const environmentId = values.environment || process.env.CANON_ENVIRONMENT_ID;
|
|
63
|
+
if (!environmentId) {
|
|
64
|
+
throw new Error('--environment or CANON_ENVIRONMENT_ID is required');
|
|
62
65
|
}
|
|
66
|
+
const connection = resolveCanonRuntimeConnection({
|
|
67
|
+
environmentId,
|
|
68
|
+
apiBaseUrl: values['base-url'],
|
|
69
|
+
streamUrl: values['stream-url'],
|
|
70
|
+
rtdbUrl: values['rtdb-url'],
|
|
71
|
+
firebaseWebApiKey: values['firebase-api-key'],
|
|
72
|
+
});
|
|
73
|
+
await verifyCanonRuntimeConnection(connection);
|
|
74
|
+
const existingProfile = loadProfiles()[profileName];
|
|
75
|
+
const existingAgentId = existingProfile?.environmentId === connection.environmentId
|
|
76
|
+
? existingProfile.agentId
|
|
77
|
+
: undefined;
|
|
63
78
|
console.log(`Registering agent "${values.name}" (profile: ${profileName})...`);
|
|
64
|
-
const pending = getOrCreatePendingRegistration(profileName, 'claude-code');
|
|
79
|
+
const pending = getOrCreatePendingRegistration(profileName, 'claude-code', connection);
|
|
65
80
|
const result = await registerAndWaitForApproval({
|
|
66
81
|
name: values.name,
|
|
67
82
|
description: values.description,
|
|
68
83
|
ownerPhone: values.phone,
|
|
69
84
|
developerInfo: 'Claude Code plugin',
|
|
70
85
|
clientType: 'claude-code',
|
|
71
|
-
baseUrl:
|
|
86
|
+
baseUrl: connection.apiBaseUrl,
|
|
72
87
|
requestedAgentId: existingAgentId,
|
|
73
88
|
localRegistrationId: pending.localRegistrationId,
|
|
74
89
|
}, {
|
|
@@ -97,11 +112,15 @@ export async function main() {
|
|
|
97
112
|
agentId: result.agentId,
|
|
98
113
|
agentName: result.agentName,
|
|
99
114
|
registeredAt: new Date().toISOString(),
|
|
115
|
+
environmentId: connection.environmentId,
|
|
116
|
+
baseUrl: connection.apiBaseUrl,
|
|
117
|
+
streamUrl: connection.streamUrl,
|
|
118
|
+
rtdbUrl: connection.rtdbUrl,
|
|
119
|
+
firebaseApiKey: connection.firebaseWebApiKey,
|
|
100
120
|
clientType: 'claude-code',
|
|
101
|
-
...(typeof values['base-url'] === 'string' ? { baseUrl: values['base-url'] } : {}),
|
|
102
121
|
});
|
|
103
122
|
if (result.requestId) {
|
|
104
|
-
await ackRegistrationApproval(
|
|
123
|
+
await ackRegistrationApproval(connection.apiBaseUrl, result.requestId, result.pollToken);
|
|
105
124
|
}
|
|
106
125
|
clearPendingRegistration(profileName);
|
|
107
126
|
console.log(`Approved! Agent: ${result.agentName} (${result.agentId})`);
|
package/dist/server.js
CHANGED
|
@@ -10,7 +10,7 @@ import { setDefaultResultOrder } from 'node:dns';
|
|
|
10
10
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
11
11
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
12
12
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
13
|
-
import { CanonClient, CanonStream, ApprovalManager, buildLocalRuntimeId, getActiveProfileLock, markLocalRuntimeStopped, loadProfiles, isProfileLocked, resolveCanonAgent, getActiveProfile, releaseLock, upsertLocalRuntimeEntry, initRTDBAuth, writeSessionState, clearSessionState, renderCanonHostInboundContent, } from '@canonmsg/core';
|
|
13
|
+
import { CanonClient, CanonStream, ApprovalManager, buildLocalRuntimeId, getActiveProfileLock, markLocalRuntimeStopped, loadProfiles, isProfileLocked, resolveCanonAgent, verifyResolvedAgentEnvironment, getActiveProfile, releaseLock, upsertLocalRuntimeEntry, initRTDBAuth, writeSessionState, clearSessionState, renderCanonHostInboundContent, } from '@canonmsg/core';
|
|
14
14
|
import { materializeMessageMedia, sendMediaFileMessage, } from '@canonmsg/agent-sdk';
|
|
15
15
|
import { ApprovalHttpServer } from './approval-server.js';
|
|
16
16
|
import { runCli } from './cli-entry.js';
|
|
@@ -447,14 +447,17 @@ async function startChannel() {
|
|
|
447
447
|
let profile;
|
|
448
448
|
let baseUrl;
|
|
449
449
|
let profileAgentName;
|
|
450
|
+
let resolvedRuntime;
|
|
450
451
|
try {
|
|
451
|
-
|
|
452
|
-
apiKey =
|
|
453
|
-
profile =
|
|
454
|
-
baseUrl =
|
|
455
|
-
profileAgentName =
|
|
452
|
+
resolvedRuntime = resolveCanonAgent({ logPrefix: '[canon]', expectedClientType: 'claude-code' });
|
|
453
|
+
apiKey = resolvedRuntime.apiKey;
|
|
454
|
+
profile = resolvedRuntime.profile;
|
|
455
|
+
baseUrl = resolvedRuntime.baseUrl;
|
|
456
|
+
profileAgentName = resolvedRuntime.agentName;
|
|
457
|
+
await verifyResolvedAgentEnvironment(resolvedRuntime);
|
|
456
458
|
}
|
|
457
459
|
catch (err) {
|
|
460
|
+
resolvedRuntime?.lockHandle?.release();
|
|
458
461
|
console.error(err instanceof Error ? err.message : err);
|
|
459
462
|
return;
|
|
460
463
|
}
|
|
@@ -483,7 +486,10 @@ async function startChannel() {
|
|
|
483
486
|
}
|
|
484
487
|
}
|
|
485
488
|
// Initialize RTDB auth for session state reporting
|
|
486
|
-
initRTDBAuth(client
|
|
489
|
+
initRTDBAuth(client, {
|
|
490
|
+
rtdbUrl: resolvedRuntime.rtdbUrl,
|
|
491
|
+
firebaseApiKey: resolvedRuntime.firebaseApiKey,
|
|
492
|
+
});
|
|
487
493
|
const runtimeId = buildLocalRuntimeId({
|
|
488
494
|
runtime: 'claude-code',
|
|
489
495
|
profile,
|
|
@@ -524,6 +530,7 @@ async function startChannel() {
|
|
|
524
530
|
stream = new CanonStream({
|
|
525
531
|
apiKey,
|
|
526
532
|
agentId,
|
|
533
|
+
streamUrl: resolvedRuntime.streamUrl,
|
|
527
534
|
handler: {
|
|
528
535
|
onMessage: handleInboundMessage,
|
|
529
536
|
onAgentContext: (ctx) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/claude-code-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.1",
|
|
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.204",
|
|
34
|
-
"@canonmsg/agent-sdk": "^
|
|
34
|
+
"@canonmsg/agent-sdk": "^7.0.0",
|
|
35
35
|
"@canonmsg/coding-agent-host": "^0.2.2",
|
|
36
|
-
"@canonmsg/agent-tools": "^0.
|
|
37
|
-
"@canonmsg/core": "^
|
|
38
|
-
"@canonmsg/rich-cards": "^0.8.
|
|
36
|
+
"@canonmsg/agent-tools": "^0.3.0",
|
|
37
|
+
"@canonmsg/core": "^7.0.0",
|
|
38
|
+
"@canonmsg/rich-cards": "^0.8.4",
|
|
39
39
|
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
40
40
|
},
|
|
41
41
|
"engines": {
|
package/skills/register/SKILL.md
CHANGED
|
@@ -18,11 +18,12 @@ Register a new Canon agent so it can send and receive messages. Each agent is sa
|
|
|
18
18
|
- **Agent name** — The display name for the agent in Canon
|
|
19
19
|
- **Description** — What the agent does (shown to users in Canon)
|
|
20
20
|
- **Owner phone number** — The Canon account owner's phone number in E.164 format (e.g., +15551234567)
|
|
21
|
+
- **Canon environment** — The trust-domain ID supplied by Canon (currently `canon-legacy-v1` for tester accounts)
|
|
21
22
|
- **Profile name** (optional) — A short identifier for this agent (e.g., "reviewer", "notifier"). Defaults to a sanitized version of the agent name.
|
|
22
23
|
|
|
23
24
|
2. Run the registration CLI:
|
|
24
25
|
```bash
|
|
25
|
-
canon-register --name "<name>" --description "<description>" --phone "<phone>" --profile "<profile>"
|
|
26
|
+
canon-register --environment "<environment>" --name "<name>" --description "<description>" --phone "<phone>" --profile "<profile>"
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
3. Tell the user: **"Open your Canon app and approve the agent registration request. Waiting for approval..."**
|
|
@@ -39,3 +40,4 @@ Register a new Canon agent so it can send and receive messages. Each agent is sa
|
|
|
39
40
|
- If status returns `"rejected"`, tell the user the registration was rejected by the owner.
|
|
40
41
|
- If polling times out after 5 minutes, tell the user to try again later.
|
|
41
42
|
- If the phone number format is wrong (must start with `+`, 8-16 digits), ask the user to re-enter it.
|
|
43
|
+
- If environment verification fails, do not retry against another URL. Confirm the environment ID and endpoint set with the user.
|