@canonmsg/core 0.15.0 → 0.15.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.
@@ -31,7 +31,9 @@ function buildWorkSessionSummary(workSession, workSessions) {
31
31
  };
32
32
  }
33
33
  export function buildAgentSessionSnapshot(input) {
34
- const modelOptions = descriptorOptions(input.runtime, 'model');
34
+ const modelOptions = input.sessionState?.availableModels?.length
35
+ ? input.sessionState.availableModels
36
+ : descriptorOptions(input.runtime, 'model');
35
37
  const workspaceOptions = descriptorOptions(input.runtime, 'workspace')
36
38
  .map((option) => ({ id: option.value, label: option.label }));
37
39
  const availableExecutionModes = descriptorOptions(input.runtime, 'executionMode')
@@ -57,6 +59,7 @@ export function buildAgentSessionSnapshot(input) {
57
59
  effort: input.sessionState?.effort ?? input.sessionConfig?.effort,
58
60
  runtimeControlValues: input.sessionState?.runtimeControlValues
59
61
  ?? input.sessionConfig?.runtimeControlValues,
62
+ runtimeControlErrors: input.sessionState?.runtimeControlErrors ?? undefined,
60
63
  workspaceId: input.sessionConfig?.workspaceId
61
64
  ?? descriptorDefaultValue(input.runtime, 'workspace'),
62
65
  workspaceOptions,
package/dist/browser.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
2
2
  export { resolveCanonBaseUrl } from './base-url.js';
3
3
  export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
4
- export type { AddMemberResult, AgentCapabilities, AgentClientType, AgentSessionSnapshot, AgentSessionWorkSessionSummary, AgentRuntime, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonStreamEvent, CreateContactRequestResult, MediaAttachment, MediaAttachmentKind, ModelOption, PermissionModeOption, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, ResolvedAdmission, SessionConfig, TurnUpdatedPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
4
+ export type { AddMemberResult, AgentCapabilities, AgentClientType, AgentSessionSnapshot, AgentSessionWorkSessionSummary, AgentRuntime, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonStreamEvent, CreateContactRequestResult, MediaAttachment, MediaAttachmentKind, ModelOption, PermissionModeOption, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, RuntimeControlError, ResolvedAdmission, SessionConfig, TurnUpdatedPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
5
5
  export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
6
6
  export type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
7
7
  export type { CanonResolvedWorkSession, CanonWorkSession, CanonWorkSessionContext, CanonWorkSessionConversationRole, CanonWorkSessionDisclosureMode, CanonWorkSessionParticipant, CanonWorkSessionStatus, CreateWorkSessionOptions, SendLinkedMessageOptions, SendLinkedMessageResult, UpdateWorkSessionConversationOptions, WorkSessionPromptRenderOptions, } from './work-session.js';
@@ -0,0 +1,13 @@
1
+ export interface CliMetadata {
2
+ name: string;
3
+ description?: string;
4
+ help: string;
5
+ version?: string;
6
+ }
7
+ export interface RunCliMetadataOptions extends CliMetadata {
8
+ argv?: string[];
9
+ }
10
+ export declare function isDirectExecution(moduleUrl: string): boolean;
11
+ export declare function readCliPackageVersion(moduleUrl: string): string | null;
12
+ export declare function handleCliMetadataRequest(moduleUrl: string, metadata: RunCliMetadataOptions): boolean;
13
+ export declare function runCli(moduleUrl: string, main: () => void | Promise<void>, onError: (error: unknown) => void, metadata?: RunCliMetadataOptions): void;
@@ -0,0 +1,60 @@
1
+ import { readFileSync, realpathSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath, 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 readCliPackageVersion(moduleUrl) {
20
+ let current = dirname(fileURLToPath(moduleUrl));
21
+ while (true) {
22
+ try {
23
+ const manifest = JSON.parse(readFileSync(resolve(current, 'package.json'), 'utf8'));
24
+ return typeof manifest.version === 'string' ? manifest.version : null;
25
+ }
26
+ catch {
27
+ const parent = dirname(current);
28
+ if (parent === current)
29
+ return null;
30
+ current = parent;
31
+ }
32
+ }
33
+ }
34
+ function hasArg(argv, long, short) {
35
+ return argv.includes(long) || argv.includes(short);
36
+ }
37
+ export function handleCliMetadataRequest(moduleUrl, metadata) {
38
+ const argv = metadata.argv ?? process.argv.slice(2);
39
+ if (hasArg(argv, '--help', '-h')) {
40
+ process.stdout.write(`${metadata.help.trimEnd()}\n`);
41
+ return true;
42
+ }
43
+ if (hasArg(argv, '--version', '-V')) {
44
+ const version = metadata.version ?? readCliPackageVersion(moduleUrl) ?? 'unknown';
45
+ process.stdout.write(`${metadata.name} ${version}\n`);
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ export function runCli(moduleUrl, main, onError, metadata) {
51
+ if (!isDirectExecution(moduleUrl)) {
52
+ return;
53
+ }
54
+ if (metadata && handleCliMetadataRequest(moduleUrl, metadata)) {
55
+ return;
56
+ }
57
+ Promise.resolve()
58
+ .then(() => main())
59
+ .catch(onError);
60
+ }
@@ -36,6 +36,7 @@ export declare function buildCanonHostPrompt(input: {
36
36
  workSession?: MessageCreatedPayload['message']['workSession'];
37
37
  workSessions?: MessageCreatedPayload['workSessions'];
38
38
  buildInboundContextLines: (context: HostInboundParticipantContext) => string[];
39
+ sessionContextLines?: string[];
39
40
  }): string;
40
41
  /**
41
42
  * Render the **text portion** of an inbound Canon message. Images are
@@ -24,6 +24,9 @@ export function buildCanonHostPrompt(input) {
24
24
  ...(resolvedWorkSessions.length > 0
25
25
  ? ['Honor the Canon work-session context above within its stated disclosure limits.']
26
26
  : []),
27
+ ...(input.sessionContextLines?.length
28
+ ? ['Canon session state:', ...input.sessionContextLines]
29
+ : []),
27
30
  `Conversation ID: ${input.conversationId}`,
28
31
  '',
29
32
  'New Canon message:',
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
2
- export type { AddMemberResult, AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, CanonConversation, CanonMessagesPage, CreateContactRequestResult, AgentContext, CanonStreamEvent, AgentSessionSnapshot, AgentSessionWorkSessionSummary, ResolvedAdmission, MediaAttachment, MediaAttachmentKind, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload, SendMessageOptions, CreateConversationOptions, RegistrationInput, RegistrationResult, RegistrationStatus, StreamingStatus, SetStreamingOptions, SessionControl, SessionState, SessionConfig, AgentRuntime, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
2
+ export type { AddMemberResult, AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, CanonConversation, CanonMessagesPage, CreateContactRequestResult, AgentContext, CanonStreamEvent, AgentSessionSnapshot, AgentSessionWorkSessionSummary, ResolvedAdmission, MediaAttachment, MediaAttachmentKind, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload, SendMessageOptions, CreateConversationOptions, RegistrationInput, RegistrationResult, RegistrationStatus, StreamingStatus, SetStreamingOptions, SessionControl, SessionState, SessionConfig, AgentRuntime, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, RuntimeControlError, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
3
3
  export type { CanonResolvedWorkSession, CanonWorkSession, CanonWorkSessionContext, CanonWorkSessionConversationRole, CreateWorkSessionOptions, CanonWorkSessionDisclosureMode, CanonWorkSessionParticipant, CanonWorkSessionStatus, SendLinkedMessageOptions, SendLinkedMessageResult, UpdateWorkSessionConversationOptions, WorkSessionPromptRenderOptions, } from './work-session.js';
4
4
  export { buildWorkSessionPromptLines, buildWorkSessionsPromptLines, mergeWorkSessionContexts, } from './work-session.js';
5
5
  export { buildConfiguredWorkspaceOptionsWithRoots, buildPublicWorkspaceRoots, buildWorkspaceRootId, discoverWorkspaceProjects, } from './workspace-discovery.js';
@@ -39,3 +39,5 @@ export type { RuntimeStatePublisher, RuntimeStatePublisherOptions, RuntimeStream
39
39
  export { formatCanonMessageAsText } from './message-format.js';
40
40
  export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
41
41
  export { resolveCanonBaseUrl } from './base-url.js';
42
+ export { handleCliMetadataRequest, isDirectExecution, readCliPackageVersion, runCli, } from './cli-metadata.js';
43
+ export type { CliMetadata, RunCliMetadataOptions, } from './cli-metadata.js';
package/dist/index.js CHANGED
@@ -39,3 +39,5 @@ export { formatCanonMessageAsText } from './message-format.js';
39
39
  export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
40
40
  // Base URL resolver
41
41
  export { resolveCanonBaseUrl } from './base-url.js';
42
+ // CLI metadata helpers for Node entrypoints
43
+ export { handleCliMetadataRequest, isDirectExecution, readCliPackageVersion, runCli, } from './cli-metadata.js';
@@ -7,6 +7,7 @@ export interface LocalRuntimeSessionState {
7
7
  workspaceId?: string;
8
8
  baseCwd: string;
9
9
  executionMode?: ExecutionEnvironmentMode;
10
+ codexPolicyFingerprint?: string;
10
11
  threadId?: string;
11
12
  claudeSessionId?: string;
12
13
  lastInboundMessageId?: string;
@@ -165,7 +165,7 @@ export function clearRuntimeSessionState(runtimeId, input) {
165
165
  delete sessions[key];
166
166
  }
167
167
  }
168
- upsertLocalRuntimeEntry({ ...entry, sessions });
168
+ writeJsonAtomic(runtimePath(entry.id), { ...entry, sessions });
169
169
  }
170
170
  function migrateLegacyCodexSessions(runtimeId) {
171
171
  if (!existsSync(LEGACY_CODEX_SESSIONS_PATH))
@@ -7,13 +7,14 @@
7
7
  */
8
8
  import type { CanonClient } from './client.js';
9
9
  import type { DeliveryIntent, RuntimeCapabilities, TurnLifecycleState } from './turn-protocol.js';
10
- import type { CanonControlValue, RuntimeInfoPayload } from './types.js';
10
+ import type { CanonControlValue, ModelOption, RuntimeControlError, RuntimeInfoPayload } from './types.js';
11
11
  export interface SessionStatePayload {
12
12
  lastError?: string;
13
13
  model?: string;
14
14
  permissionMode?: string;
15
15
  effort?: string;
16
16
  runtimeControlValues?: Record<string, CanonControlValue>;
17
+ runtimeControlErrors?: Record<string, RuntimeControlError> | null;
17
18
  cwd?: string;
18
19
  executionMode?: 'worktree' | 'locked';
19
20
  executionBranch?: string;
@@ -27,6 +28,7 @@ export interface SessionStatePayload {
27
28
  totalTokens: number;
28
29
  maxTokens: number;
29
30
  };
31
+ availableModels?: ModelOption[];
30
32
  updatedAt: {
31
33
  '.sv': 'timestamp';
32
34
  };
@@ -53,10 +55,7 @@ export interface AgentSessionSnapshotPatch {
53
55
  clientType?: string;
54
56
  hostMode?: boolean;
55
57
  model?: string | null;
56
- modelOptions?: Array<{
57
- value: string;
58
- label: string;
59
- }> | null;
58
+ modelOptions?: ModelOption[] | null;
60
59
  permissionMode?: string | null;
61
60
  permissionModeOptions?: Array<{
62
61
  value: string;
@@ -64,6 +63,7 @@ export interface AgentSessionSnapshotPatch {
64
63
  }> | null;
65
64
  effort?: string | null;
66
65
  runtimeControlValues?: Record<string, CanonControlValue> | null;
66
+ runtimeControlErrors?: Record<string, RuntimeControlError> | null;
67
67
  workspaceId?: string | null;
68
68
  workspaceOptions?: Array<{
69
69
  id: string;
package/dist/rtdb-rest.js CHANGED
@@ -144,6 +144,9 @@ function createRTDBClientHandle(client, options) {
144
144
  ...(state.runtimeControlValues !== undefined
145
145
  ? { runtimeControlValues: state.runtimeControlValues }
146
146
  : {}),
147
+ ...(state.runtimeControlErrors !== undefined
148
+ ? { runtimeControlErrors: state.runtimeControlErrors }
149
+ : {}),
147
150
  ...(state.cwd !== undefined ? { resolvedCwd: state.cwd } : {}),
148
151
  ...(state.executionMode !== undefined ? { executionMode: state.executionMode } : {}),
149
152
  ...(state.executionBranch !== undefined ? { executionBranch: state.executionBranch } : {}),
@@ -154,6 +157,7 @@ function createRTDBClientHandle(client, options) {
154
157
  state: null,
155
158
  waitingForInput: false,
156
159
  ...(state.contextUsage !== undefined ? { contextUsage: state.contextUsage } : {}),
160
+ ...(state.availableModels !== undefined ? { modelOptions: state.availableModels } : {}),
157
161
  ...(state.lastError !== undefined ? { lastError: state.lastError } : {}),
158
162
  lastHeartbeatAt: { '.sv': 'timestamp' },
159
163
  updatedAt: { '.sv': 'timestamp' },
package/dist/types.d.ts CHANGED
@@ -434,6 +434,7 @@ export type CanonStreamEvent = {
434
434
  };
435
435
  };
436
436
  export interface SendMessageOptions {
437
+ messageId?: string;
437
438
  contentType?: 'text' | 'audio' | 'image' | 'file' | 'contact_card';
438
439
  replyTo?: string;
439
440
  replyToPosition?: number;
@@ -466,6 +467,11 @@ export interface SessionControl {
466
467
  updatedAt: number;
467
468
  updatedBy: string;
468
469
  }
470
+ export interface RuntimeControlError {
471
+ value: string;
472
+ message: string;
473
+ updatedAt: number;
474
+ }
469
475
  /** Written by agent to /session-state/{convoId}/{agentId} in RTDB */
470
476
  export interface SessionState {
471
477
  lastError?: string;
@@ -473,6 +479,7 @@ export interface SessionState {
473
479
  permissionMode?: string;
474
480
  effort?: string;
475
481
  runtimeControlValues?: Record<string, CanonControlValue>;
482
+ runtimeControlErrors?: Record<string, RuntimeControlError> | null;
476
483
  cwd?: string;
477
484
  executionMode?: 'worktree' | 'locked';
478
485
  executionBranch?: string;
@@ -573,6 +580,7 @@ export interface AgentSessionSnapshot {
573
580
  permissionModeOptions?: PermissionModeOption[];
574
581
  effort?: string;
575
582
  runtimeControlValues?: Record<string, CanonControlValue>;
583
+ runtimeControlErrors?: Record<string, RuntimeControlError> | null;
576
584
  runtimeDescriptor?: CanonRuntimeDescriptor | null;
577
585
  runtimeInfo?: RuntimeInfoPayload | null;
578
586
  workspaceId?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/core",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "description": "Canon core — shared types, REST client, SSE stream, and registration for Canon messaging",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",