@canonmsg/core 0.7.0 → 0.7.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/dist/browser.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  export { AGENT_CAPABILITIES, } from './types.js';
2
+ export { resolveCanonBaseUrl } from './base-url.js';
3
+ export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
2
4
  export type { AgentCapabilities, AgentClientType, AgentRuntime, MediaAttachment, MediaAttachmentKind, ModelOption, SessionConfig, WorkspaceOption, } from './types.js';
5
+ export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
6
+ export type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
3
7
  export type { CanonResolvedWorkSession, CanonWorkSession, CanonWorkSessionContext, CanonWorkSessionConversationRole, CanonWorkSessionDisclosureMode, CanonWorkSessionParticipant, CanonWorkSessionStatus, CreateWorkSessionOptions, SendLinkedMessageOptions, SendLinkedMessageResult, UpdateWorkSessionConversationOptions, WorkSessionPromptRenderOptions, } from './work-session.js';
4
8
  export { buildWorkSessionPromptLines, buildWorkSessionsPromptLines, mergeWorkSessionContexts, } from './work-session.js';
5
9
  export type { AgentBehaviorSettings, ParticipationHistoryMessage, ParticipationHistorySnapshot, ParticipationStyle, ResolvedAgentBehaviorPolicy, } from './policy.js';
package/dist/browser.js CHANGED
@@ -1,4 +1,7 @@
1
1
  export { AGENT_CAPABILITIES, } from './types.js';
2
+ export { resolveCanonBaseUrl } from './base-url.js';
3
+ export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
4
+ export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
2
5
  export { buildWorkSessionPromptLines, buildWorkSessionsPromptLines, mergeWorkSessionContexts, } from './work-session.js';
3
6
  export { buildParticipationHistorySnapshot, buildParticipationHistorySnapshots, buildBehaviorPolicyLines, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, evaluateParticipationPolicy, getDefaultParticipationPolicy, resolveAgentBehaviorPolicy, } from './policy.js';
4
7
  export { DEFAULT_RUNTIME_CAPABILITIES, FINAL_MESSAGE_HANDOFF_MS, isTurnOpen, normalizeTurnMetadata, normalizeTurnState, resolveTurnMessageSemantics, shouldPromoteConversationMessage, shouldTriggerAgentTurn, } from './turn-protocol.js';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Browser-safe helpers for Canon execution modes. Separated from
3
+ * `execution-environment.ts` (which pulls in Node-only modules) so both
4
+ * Node hosts and browser/Expo clients can import these primitives.
5
+ */
6
+ export type ExecutionEnvironmentMode = 'worktree' | 'locked';
7
+ export declare const EXECUTION_ENVIRONMENT_MODES: readonly ExecutionEnvironmentMode[];
8
+ export declare function isExecutionEnvironmentMode(value: unknown): value is ExecutionEnvironmentMode;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Browser-safe helpers for Canon execution modes. Separated from
3
+ * `execution-environment.ts` (which pulls in Node-only modules) so both
4
+ * Node hosts and browser/Expo clients can import these primitives.
5
+ */
6
+ export const EXECUTION_ENVIRONMENT_MODES = [
7
+ 'worktree',
8
+ 'locked',
9
+ ];
10
+ export function isExecutionEnvironmentMode(value) {
11
+ return value === 'worktree' || value === 'locked';
12
+ }
@@ -1,5 +1,7 @@
1
1
  import type { WorkspaceOption } from './types.js';
2
- export type ExecutionEnvironmentMode = 'worktree' | 'locked';
2
+ import { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, type ExecutionEnvironmentMode } from './execution-environment-mode.js';
3
+ export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode };
4
+ export type { ExecutionEnvironmentMode };
3
5
  export interface PreparedExecutionEnvironment {
4
6
  cwd: string;
5
7
  baseCwd: string;
@@ -24,6 +26,7 @@ export interface ConfiguredWorkspaceOption extends WorkspaceResolverOption {
24
26
  export interface SessionWorkspaceConfig {
25
27
  workspaceId?: string;
26
28
  model?: string;
29
+ executionMode?: ExecutionEnvironmentMode;
27
30
  retiredWorkspaceConfig?: boolean;
28
31
  }
29
32
  export declare function normalizeOptionalString(value: unknown): string | undefined;
@@ -56,4 +59,3 @@ export declare function prepareConversationEnvironment(input: {
56
59
  allowWorktrees?: boolean;
57
60
  }): PreparedExecutionEnvironment;
58
61
  export declare function releaseConversationEnvironment(environment: Pick<PreparedExecutionEnvironment, 'lockPath'>): void;
59
- export {};
@@ -3,6 +3,8 @@ import { createHash } from 'node:crypto';
3
3
  import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync, } from 'node:fs';
4
4
  import { basename, dirname, join, relative, resolve } from 'node:path';
5
5
  import { CANON_DIR, isProcessAlive } from './agent-profiles.js';
6
+ import { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
7
+ export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode };
6
8
  export class ExecutionEnvironmentError extends Error {
7
9
  userMessage;
8
10
  constructor(message, userMessage = message) {
@@ -168,9 +170,14 @@ export function readSessionWorkspaceConfig(raw) {
168
170
  : undefined;
169
171
  const hasRetiredWorkspaceReference = (normalizeOptionalString(data.cwd) !== undefined
170
172
  || isRetiredWorkspaceId(rawWorkspaceId));
173
+ const rawExecutionMode = data.executionMode;
174
+ const executionMode = isExecutionEnvironmentMode(rawExecutionMode)
175
+ ? rawExecutionMode
176
+ : undefined;
171
177
  return {
172
178
  workspaceId: stableWorkspaceId,
173
179
  model: normalizeOptionalString(data.model),
180
+ ...(executionMode ? { executionMode } : {}),
174
181
  ...(!stableWorkspaceId && hasRetiredWorkspaceReference
175
182
  ? { retiredWorkspaceConfig: true }
176
183
  : {}),
package/dist/index.d.ts CHANGED
@@ -20,7 +20,7 @@ export { loadProfiles, isProfileLocked, acquireLock, releaseLock, isProcessAlive
20
20
  export type { AgentProfile } from './agent-profiles.js';
21
21
  export { resolveCanonAgent, resolveCanonProfile, getActiveProfile } from './agent-resolver.js';
22
22
  export type { ResolvedAgent } from './agent-resolver.js';
23
- export { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, buildConversationWorktreeSpec, buildPublicWorkspaceOptions, buildWorkspaceOptionId, isEnabledFlag, normalizeOptionalString, readSessionWorkspaceConfig, resolveConfiguredWorkspaceCwd, ExecutionEnvironmentError, prepareConversationEnvironment, releaseConversationEnvironment, } from './execution-environment.js';
23
+ export { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, buildConversationWorktreeSpec, buildPublicWorkspaceOptions, buildWorkspaceOptionId, EXECUTION_ENVIRONMENT_MODES, isEnabledFlag, isExecutionEnvironmentMode, normalizeOptionalString, readSessionWorkspaceConfig, resolveConfiguredWorkspaceCwd, ExecutionEnvironmentError, prepareConversationEnvironment, releaseConversationEnvironment, } from './execution-environment.js';
24
24
  export type { ConfiguredWorkspaceOption, ExecutionEnvironmentMode, PreparedExecutionEnvironment, SessionWorkspaceConfig, } from './execution-environment.js';
25
25
  export { initRTDBAuth, rtdbWrite, rtdbRead, writeSessionState, clearSessionState, writeTurnState, clearTurnState, } from './rtdb-rest.js';
26
26
  export type { SessionStatePayload, TurnStatePayload } from './rtdb-rest.js';
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ export { loadProfiles, isProfileLocked, acquireLock, releaseLock, isProcessAlive
21
21
  // Agent resolver
22
22
  export { resolveCanonAgent, resolveCanonProfile, getActiveProfile } from './agent-resolver.js';
23
23
  // Execution environments for host-mode coding sessions
24
- export { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, buildConversationWorktreeSpec, buildPublicWorkspaceOptions, buildWorkspaceOptionId, isEnabledFlag, normalizeOptionalString, readSessionWorkspaceConfig, resolveConfiguredWorkspaceCwd, ExecutionEnvironmentError, prepareConversationEnvironment, releaseConversationEnvironment, } from './execution-environment.js';
24
+ export { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, buildConversationWorktreeSpec, buildPublicWorkspaceOptions, buildWorkspaceOptionId, EXECUTION_ENVIRONMENT_MODES, isEnabledFlag, isExecutionEnvironmentMode, normalizeOptionalString, readSessionWorkspaceConfig, resolveConfiguredWorkspaceCwd, ExecutionEnvironmentError, prepareConversationEnvironment, releaseConversationEnvironment, } from './execution-environment.js';
25
25
  // RTDB REST helpers (token exchange, session state, generic read/write)
26
26
  export { initRTDBAuth, rtdbWrite, rtdbRead, writeSessionState, clearSessionState, writeTurnState, clearTurnState, } from './rtdb-rest.js';
27
27
  // Constants
package/dist/types.d.ts CHANGED
@@ -1,5 +1,7 @@
1
+ import type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
1
2
  import type { ResolvedAgentBehaviorPolicy } from './policy.js';
2
3
  import type { CanonWorkSessionContext } from './work-session.js';
4
+ export type { ExecutionEnvironmentMode };
3
5
  export type MediaAttachmentKind = 'image' | 'audio' | 'file';
4
6
  export interface MediaAttachment {
5
7
  kind: MediaAttachmentKind;
@@ -11,6 +13,10 @@ export interface MediaAttachment {
11
13
  height?: number;
12
14
  durationMs?: number;
13
15
  }
16
+ export interface ForwardedFrom {
17
+ sourceConversationId: string;
18
+ messageId: string;
19
+ }
14
20
  export interface CanonMessage {
15
21
  id: string;
16
22
  senderId: string;
@@ -19,13 +25,12 @@ export interface CanonMessage {
19
25
  isOwner: boolean;
20
26
  contentType: 'text' | 'image' | 'audio' | 'file' | 'contact_card';
21
27
  text: string | null;
22
- imageUrl: string | null;
23
- audioUrl: string | null;
24
- audioDurationMs: number | null;
25
- attachments?: MediaAttachment[];
28
+ attachments: MediaAttachment[];
26
29
  mentions: string[];
27
30
  replyTo: string | null;
28
31
  replyToPosition: number | null;
32
+ forwarded?: boolean;
33
+ forwardedFrom?: ForwardedFrom;
29
34
  workSession?: CanonWorkSessionContext | null;
30
35
  metadata?: Record<string, unknown>;
31
36
  status: 'sent' | 'read';
@@ -59,6 +64,12 @@ export type AgentClientType = 'claude-code' | 'openclaw' | 'codex' | 'generic';
59
64
  export interface AgentCapabilities {
60
65
  supportsModelSwitch: boolean;
61
66
  supportsPermissionMode: boolean;
67
+ /**
68
+ * Whether permissionMode can be changed mid-session. When undefined,
69
+ * defaults to `supportsPermissionMode` — keep the UI chip non-interactive
70
+ * for agents whose approval mode is locked at session creation.
71
+ */
72
+ supportsRuntimePermissionMode?: boolean;
62
73
  supportsEffort: boolean;
63
74
  supportsSessionState: boolean;
64
75
  supportsInterrupt: boolean;
@@ -101,12 +112,11 @@ export interface MessageCreatedPayload {
101
112
  isOwner?: boolean;
102
113
  text?: string;
103
114
  contentType?: 'text' | 'image' | 'audio' | 'file' | 'contact_card';
104
- imageUrl?: string;
105
- audioUrl?: string;
106
- audioDurationMs?: number;
107
115
  attachments?: MediaAttachment[];
108
116
  replyTo?: string;
109
117
  replyToPosition?: number;
118
+ forwarded?: boolean;
119
+ forwardedFrom?: ForwardedFrom;
110
120
  mentions?: string[];
111
121
  createdAt?: string;
112
122
  workSession?: CanonWorkSessionContext | null;
@@ -128,9 +138,6 @@ export interface SendMessageOptions {
128
138
  contentType?: 'text' | 'audio' | 'image' | 'file' | 'contact_card';
129
139
  replyTo?: string;
130
140
  replyToPosition?: number;
131
- audioUrl?: string;
132
- audioDurationMs?: number;
133
- imageUrl?: string;
134
141
  attachments?: MediaAttachment[];
135
142
  contactCardUserId?: string;
136
143
  mentions?: string[];
@@ -186,16 +193,39 @@ export interface SessionConfig {
186
193
  model?: string;
187
194
  permissionMode?: string;
188
195
  workspaceId?: string;
196
+ /**
197
+ * Explicitly selected execution mode. Sessions created before this field
198
+ * existed stay `undefined`; UIs must prompt for a value and plugin hosts
199
+ * fail-closed rather than inferring one.
200
+ */
201
+ executionMode?: ExecutionEnvironmentMode;
189
202
  availableModels?: ModelOption[];
190
203
  workspaceOptions?: WorkspaceOption[];
204
+ availableExecutionModes?: ExecutionEnvironmentMode[];
191
205
  updatedAt?: number;
192
206
  }
207
+ export interface PermissionModeOption {
208
+ value: string;
209
+ label: string;
210
+ }
193
211
  export interface AgentRuntime {
194
212
  clientType?: AgentClientType;
195
213
  hostMode?: boolean;
196
214
  defaultModel?: string;
197
215
  defaultPermissionMode?: string;
216
+ availablePermissionModes?: PermissionModeOption[];
198
217
  defaultWorkspaceId?: string;
218
+ /**
219
+ * Execution modes the host will accept. The runtime advertises this so the
220
+ * app can offer matching choices; it is NOT used to auto-populate missing
221
+ * session-config values.
222
+ */
223
+ availableExecutionModes?: ExecutionEnvironmentMode[];
224
+ /**
225
+ * Reference default surfaced to UI. Treated as advisory only — callers must
226
+ * still have the user confirm a selection before persisting.
227
+ */
228
+ defaultExecutionMode?: ExecutionEnvironmentMode;
199
229
  availableModels?: ModelOption[];
200
230
  availableWorkspaces?: WorkspaceOption[];
201
231
  updatedAt?: number;
package/dist/types.js CHANGED
@@ -12,6 +12,7 @@ export const AGENT_CAPABILITIES = {
12
12
  'claude-code': {
13
13
  supportsModelSwitch: true,
14
14
  supportsPermissionMode: true,
15
+ supportsRuntimePermissionMode: true,
15
16
  supportsEffort: true,
16
17
  supportsSessionState: true,
17
18
  supportsInterrupt: true,
@@ -20,7 +21,8 @@ export const AGENT_CAPABILITIES = {
20
21
  },
21
22
  'codex': {
22
23
  supportsModelSwitch: false,
23
- supportsPermissionMode: false,
24
+ supportsPermissionMode: true,
25
+ supportsRuntimePermissionMode: false,
24
26
  supportsEffort: false,
25
27
  supportsSessionState: true,
26
28
  supportsInterrupt: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/core",
3
- "version": "0.7.0",
3
+ "version": "0.7.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",