@canonmsg/core 0.7.5 → 0.10.0
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/agent-session.js +8 -0
- package/dist/approval-manager.js +14 -4
- package/dist/approval-types.d.ts +6 -0
- package/dist/browser.d.ts +2 -2
- package/dist/execution-environment.d.ts +6 -2
- package/dist/execution-environment.js +10 -2
- package/dist/index.d.ts +6 -4
- package/dist/index.js +2 -1
- package/dist/rtdb-rest.d.ts +21 -0
- package/dist/rtdb-rest.js +44 -0
- package/dist/runtime-cards.d.ts +8 -1
- package/dist/runtime-cards.js +2 -1
- package/dist/types.d.ts +142 -2
- package/dist/types.js +1 -0
- package/dist/workspace-discovery.d.ts +18 -0
- package/dist/workspace-discovery.js +193 -0
- package/package.json +2 -1
package/dist/agent-session.js
CHANGED
|
@@ -39,6 +39,9 @@ export function buildAgentSessionSnapshot(input) {
|
|
|
39
39
|
?? input.sessionConfig?.permissionMode
|
|
40
40
|
?? input.runtime?.defaultPermissionMode,
|
|
41
41
|
permissionModeOptions: input.runtime?.availablePermissionModes ?? [],
|
|
42
|
+
effort: input.sessionState?.effort ?? input.sessionConfig?.effort,
|
|
43
|
+
runtimeControlValues: input.sessionState?.runtimeControlValues
|
|
44
|
+
?? input.sessionConfig?.runtimeControlValues,
|
|
42
45
|
workspaceId: input.sessionConfig?.workspaceId
|
|
43
46
|
?? input.runtime?.defaultWorkspaceId
|
|
44
47
|
?? workspaceOptions[0]?.id,
|
|
@@ -49,8 +52,13 @@ export function buildAgentSessionSnapshot(input) {
|
|
|
49
52
|
?? input.runtime?.availableExecutionModes
|
|
50
53
|
?? [],
|
|
51
54
|
executionBranch: input.sessionState?.executionBranch,
|
|
55
|
+
resolvedWorkspaceLabel: undefined,
|
|
56
|
+
resolvedCwd: input.sessionState?.cwd,
|
|
57
|
+
worktreePath: input.sessionState?.worktreePath,
|
|
58
|
+
executionFallbackReason: input.sessionState?.executionFallbackReason,
|
|
52
59
|
state: input.sessionState?.state,
|
|
53
60
|
turnState: input.turnState?.state,
|
|
61
|
+
supportsQueue: input.turnState?.capabilities?.supportsQueue,
|
|
54
62
|
queueDepth: input.turnState?.queueDepth ?? 0,
|
|
55
63
|
waitingForInput: input.turnState?.state === 'waiting_input'
|
|
56
64
|
|| input.sessionState?.state === 'requires_action',
|
package/dist/approval-manager.js
CHANGED
|
@@ -41,7 +41,7 @@ export class ApprovalManager {
|
|
|
41
41
|
const summary = this.summarizeTool(toolName, toolInput);
|
|
42
42
|
const logMsg = buildApprovalOutcome('', toolName, summary, decision, 'session-rule');
|
|
43
43
|
this.client.sendMessage(conversationId, logMsg, {
|
|
44
|
-
metadata: { type: 'approval_outcome' },
|
|
44
|
+
metadata: { type: 'approval_outcome', decision, reason: 'session-rule' },
|
|
45
45
|
}).catch(() => { });
|
|
46
46
|
return { decision };
|
|
47
47
|
}
|
|
@@ -64,7 +64,12 @@ export class ApprovalManager {
|
|
|
64
64
|
const summary = this.summarizeTool(toolName, toolInput);
|
|
65
65
|
const msg = buildApprovalOutcome(approvalId, toolName, summary, 'deny', 'timeout');
|
|
66
66
|
this.client.sendMessage(conversationId, msg, {
|
|
67
|
-
metadata: {
|
|
67
|
+
metadata: {
|
|
68
|
+
type: 'approval_outcome',
|
|
69
|
+
approvalId,
|
|
70
|
+
decision: 'deny',
|
|
71
|
+
reason: 'timeout',
|
|
72
|
+
},
|
|
68
73
|
}).catch(() => { });
|
|
69
74
|
resolve({ decision: 'deny' });
|
|
70
75
|
}, this.config.timeoutSeconds * 1000);
|
|
@@ -164,14 +169,19 @@ export class ApprovalManager {
|
|
|
164
169
|
// Send confirmation (fire-and-forget)
|
|
165
170
|
const msg = buildApprovalOutcome(approvalId, entry.toolName, entry.toolSummary, decision, 'replied');
|
|
166
171
|
this.client.sendMessage(conversationId, msg, {
|
|
167
|
-
metadata: {
|
|
172
|
+
metadata: {
|
|
173
|
+
type: 'approval_outcome',
|
|
174
|
+
approvalId,
|
|
175
|
+
decision,
|
|
176
|
+
reason: 'replied',
|
|
177
|
+
},
|
|
168
178
|
}).catch(() => { });
|
|
169
179
|
// If session rule was set, log that too
|
|
170
180
|
if (sessionRule) {
|
|
171
181
|
const ruleDesc = this.describeRule(sessionRule);
|
|
172
182
|
this.client
|
|
173
183
|
.sendMessage(conversationId, `Session rule set: ${ruleDesc}`, {
|
|
174
|
-
metadata: { type: 'approval_outcome' },
|
|
184
|
+
metadata: { type: 'approval_outcome', decision, reason: 'session-rule' },
|
|
175
185
|
})
|
|
176
186
|
.catch(() => { });
|
|
177
187
|
}
|
package/dist/approval-types.d.ts
CHANGED
|
@@ -7,6 +7,12 @@ export interface ApprovalRequestMetadata {
|
|
|
7
7
|
riskLevel?: 'normal' | 'destructive';
|
|
8
8
|
expiresAt: string;
|
|
9
9
|
}
|
|
10
|
+
export interface ApprovalOutcomeMetadata {
|
|
11
|
+
type: 'approval_outcome';
|
|
12
|
+
approvalId?: string;
|
|
13
|
+
decision?: 'allow' | 'deny';
|
|
14
|
+
reason?: 'replied' | 'timeout' | 'session-rule';
|
|
15
|
+
}
|
|
10
16
|
export interface ApprovalReplyMetadata {
|
|
11
17
|
type: 'approval_reply';
|
|
12
18
|
approvalId: string;
|
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 { AgentCapabilities, AgentClientType, AgentSessionSnapshot, AgentSessionWorkSessionSummary, AgentRuntime, CanonContactRequest, CanonContactRequestStatus, ContactApprovedPayload, ContactRequestPayload, CanonStreamEvent, CreateContactRequestResult, MediaAttachment, MediaAttachmentKind, ModelOption, PermissionModeOption, RuntimeUpdatedPayload, ResolvedAdmission, SessionConfig, TurnUpdatedPayload, WorkspaceOption, } from './types.js';
|
|
4
|
+
export type { AgentCapabilities, AgentClientType, AgentSessionSnapshot, AgentSessionWorkSessionSummary, AgentRuntime, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContactRequest, CanonContactRequestStatus, ContactApprovedPayload, ContactRequestPayload, 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';
|
|
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';
|
|
@@ -12,6 +12,6 @@ export { buildParticipationHistorySnapshot, buildParticipationHistorySnapshots,
|
|
|
12
12
|
export { DEFAULT_RUNTIME_CAPABILITIES, FINAL_MESSAGE_HANDOFF_MS, isTurnOpen, normalizeTurnMetadata, normalizeTurnState, resolveTurnMessageSemantics, shouldPromoteConversationMessage, shouldTriggerAgentTurn, } from './turn-protocol.js';
|
|
13
13
|
export type { DeliveryIntent, InboundDisposition, RuntimeCapabilities, TriggerDecision, TurnLifecycleState, TurnMessageSemantics, TurnMetadata, TurnState, } from './turn-protocol.js';
|
|
14
14
|
export { buildApprovalReply, buildApprovalRequest, buildApprovalOutcome, generateApprovalId, parseTextApprovalReply, redactSecrets, } from './approval-format.js';
|
|
15
|
-
export type { ApprovalRequestMetadata, ApprovalReplyMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
|
|
15
|
+
export type { ApprovalRequestMetadata, ApprovalReplyMetadata, ApprovalOutcomeMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
|
|
16
16
|
export { buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, } from './runtime-cards.js';
|
|
17
17
|
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WorkspaceOption } from './types.js';
|
|
1
|
+
import type { WorkspaceOption, WorkspaceOptionSource } from './types.js';
|
|
2
2
|
import { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, type ExecutionEnvironmentMode } from './execution-environment-mode.js';
|
|
3
3
|
export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode };
|
|
4
4
|
export type { ExecutionEnvironmentMode };
|
|
@@ -22,6 +22,10 @@ interface WorkspaceResolverOption {
|
|
|
22
22
|
}
|
|
23
23
|
export interface ConfiguredWorkspaceOption extends WorkspaceResolverOption {
|
|
24
24
|
label: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
workspaceRootId?: string;
|
|
27
|
+
workspaceRelativePath?: string;
|
|
28
|
+
source?: WorkspaceOptionSource;
|
|
25
29
|
}
|
|
26
30
|
export interface SessionWorkspaceConfig {
|
|
27
31
|
workspaceId?: string;
|
|
@@ -34,7 +38,7 @@ export declare function isEnabledFlag(value: unknown): boolean;
|
|
|
34
38
|
export declare function buildConversationEnvironmentKey(conversationId: string, workspaceCwd: string): string;
|
|
35
39
|
export declare function buildWorkspaceOptionId(workspaceCwd: string): string;
|
|
36
40
|
export declare function buildConfiguredWorkspaceOptions(primaryCwd: string, configured: string[]): ConfiguredWorkspaceOption[];
|
|
37
|
-
export declare function buildPublicWorkspaceOptions(workspaceOptions: Array<Pick<ConfiguredWorkspaceOption, 'id' | 'label'
|
|
41
|
+
export declare function buildPublicWorkspaceOptions(workspaceOptions: Array<Pick<ConfiguredWorkspaceOption, 'id' | 'label'> & Partial<Pick<ConfiguredWorkspaceOption, 'description' | 'workspaceRootId' | 'workspaceRelativePath' | 'source'>>>): WorkspaceOption[];
|
|
38
42
|
export declare function readSessionWorkspaceConfig(raw: unknown): SessionWorkspaceConfig | null;
|
|
39
43
|
export declare function resolveConfiguredWorkspaceCwd(input: {
|
|
40
44
|
workspaceOptions: WorkspaceResolverOption[];
|
|
@@ -93,7 +93,7 @@ export function buildWorkspaceOptionId(workspaceCwd) {
|
|
|
93
93
|
export function buildConfiguredWorkspaceOptions(primaryCwd, configured) {
|
|
94
94
|
const uniqueDirs = Array.from(new Set([primaryCwd, ...configured].map((dir) => resolve(dir))));
|
|
95
95
|
const seenLabels = new Map();
|
|
96
|
-
return uniqueDirs.map((cwd) => {
|
|
96
|
+
return uniqueDirs.map((cwd, index) => {
|
|
97
97
|
const baseLabel = basename(cwd) || cwd;
|
|
98
98
|
const seenCount = (seenLabels.get(baseLabel) ?? 0) + 1;
|
|
99
99
|
seenLabels.set(baseLabel, seenCount);
|
|
@@ -101,11 +101,19 @@ export function buildConfiguredWorkspaceOptions(primaryCwd, configured) {
|
|
|
101
101
|
id: buildWorkspaceOptionId(cwd),
|
|
102
102
|
label: seenCount === 1 ? baseLabel : `${baseLabel} (${seenCount})`,
|
|
103
103
|
cwd,
|
|
104
|
+
source: index === 0 ? 'default' : 'explicit',
|
|
104
105
|
};
|
|
105
106
|
});
|
|
106
107
|
}
|
|
107
108
|
export function buildPublicWorkspaceOptions(workspaceOptions) {
|
|
108
|
-
return workspaceOptions.map((
|
|
109
|
+
return workspaceOptions.map((workspace) => ({
|
|
110
|
+
id: workspace.id,
|
|
111
|
+
label: workspace.label,
|
|
112
|
+
...(workspace.description ? { description: workspace.description } : {}),
|
|
113
|
+
...(workspace.workspaceRootId ? { workspaceRootId: workspace.workspaceRootId } : {}),
|
|
114
|
+
...(workspace.workspaceRelativePath ? { workspaceRelativePath: workspace.workspaceRelativePath } : {}),
|
|
115
|
+
...(workspace.source ? { source: workspace.source } : {}),
|
|
116
|
+
}));
|
|
109
117
|
}
|
|
110
118
|
function isRetiredWorkspaceId(value) {
|
|
111
119
|
if (!value)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
|
|
2
|
-
export type { AgentCapabilities, AgentClientType, CanonContactRequest, CanonContactRequestStatus, ContactApprovedPayload, ContactRequestPayload, 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, ModelOption, PermissionModeOption, WorkspaceOption, } from './types.js';
|
|
2
|
+
export type { AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContactRequest, CanonContactRequestStatus, ContactApprovedPayload, ContactRequestPayload, 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';
|
|
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
|
+
export { buildConfiguredWorkspaceOptionsWithRoots, buildPublicWorkspaceRoots, buildWorkspaceRootId, discoverWorkspaceProjects, } from './workspace-discovery.js';
|
|
6
|
+
export type { ConfiguredWorkspaceRoot, WorkspaceDiscoveryResult, } from './workspace-discovery.js';
|
|
5
7
|
export { CanonClient, CanonApiError } from './client.js';
|
|
6
8
|
export { buildAgentSessionSnapshot } from './agent-session.js';
|
|
7
9
|
export { CanonStream } from './stream.js';
|
|
@@ -14,7 +16,7 @@ export { registerAndWaitForApproval } from './registration.js';
|
|
|
14
16
|
export { ApprovalManager } from './approval-manager.js';
|
|
15
17
|
export { generateApprovalId, buildApprovalRequest, buildApprovalReply, buildApprovalOutcome, parseTextApprovalReply, redactSecrets, } from './approval-format.js';
|
|
16
18
|
export { DEFAULT_APPROVAL_CONFIG, } from './approval-types.js';
|
|
17
|
-
export type { ApprovalRequestMetadata, ApprovalReplyMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
|
|
19
|
+
export type { ApprovalRequestMetadata, ApprovalReplyMetadata, ApprovalOutcomeMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
|
|
18
20
|
export { buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, } from './runtime-cards.js';
|
|
19
21
|
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
20
22
|
export { createStreamingHelper } from './streaming.js';
|
|
@@ -25,7 +27,7 @@ export { resolveCanonAgent, resolveCanonProfile, getActiveProfile } from './agen
|
|
|
25
27
|
export type { ResolvedAgent } from './agent-resolver.js';
|
|
26
28
|
export { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, buildConversationWorktreeSpec, buildPublicWorkspaceOptions, buildWorkspaceOptionId, EXECUTION_ENVIRONMENT_MODES, isEnabledFlag, isExecutionEnvironmentMode, normalizeOptionalString, readSessionWorkspaceConfig, resolveConfiguredWorkspaceCwd, ExecutionEnvironmentError, prepareConversationEnvironment, releaseConversationEnvironment, } from './execution-environment.js';
|
|
27
29
|
export type { ConfiguredWorkspaceOption, ExecutionEnvironmentMode, PreparedExecutionEnvironment, SessionWorkspaceConfig, } from './execution-environment.js';
|
|
28
|
-
export { initRTDBAuth, rtdbWrite, rtdbRead, patchAgentSessionSnapshot, writeSessionState, clearSessionState, writeTurnState, clearTurnState, } from './rtdb-rest.js';
|
|
29
|
-
export type { AgentSessionSnapshotPatch, SessionStatePayload, TurnStatePayload, } from './rtdb-rest.js';
|
|
30
|
+
export { initRTDBAuth, rtdbWrite, rtdbRead, patchAgentSessionSnapshot, patchRuntimeInfo, writeRuntimeInfo, clearRuntimeInfo, writeSessionState, clearSessionState, writeTurnState, clearTurnState, } from './rtdb-rest.js';
|
|
31
|
+
export type { AgentSessionSnapshotPatch, RuntimeInfoPayloadData, SessionStatePayload, TurnStatePayload, } from './rtdb-rest.js';
|
|
30
32
|
export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
|
|
31
33
|
export { resolveCanonBaseUrl } from './base-url.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Types
|
|
2
2
|
export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
|
|
3
3
|
export { buildWorkSessionPromptLines, buildWorkSessionsPromptLines, mergeWorkSessionContexts, } from './work-session.js';
|
|
4
|
+
export { buildConfiguredWorkspaceOptionsWithRoots, buildPublicWorkspaceRoots, buildWorkspaceRootId, discoverWorkspaceProjects, } from './workspace-discovery.js';
|
|
4
5
|
// Client
|
|
5
6
|
export { CanonClient, CanonApiError } from './client.js';
|
|
6
7
|
export { buildAgentSessionSnapshot } from './agent-session.js';
|
|
@@ -25,7 +26,7 @@ export { resolveCanonAgent, resolveCanonProfile, getActiveProfile } from './agen
|
|
|
25
26
|
// Execution environments for host-mode coding sessions
|
|
26
27
|
export { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, buildConversationWorktreeSpec, buildPublicWorkspaceOptions, buildWorkspaceOptionId, EXECUTION_ENVIRONMENT_MODES, isEnabledFlag, isExecutionEnvironmentMode, normalizeOptionalString, readSessionWorkspaceConfig, resolveConfiguredWorkspaceCwd, ExecutionEnvironmentError, prepareConversationEnvironment, releaseConversationEnvironment, } from './execution-environment.js';
|
|
27
28
|
// RTDB REST helpers (token exchange, session state, generic read/write)
|
|
28
|
-
export { initRTDBAuth, rtdbWrite, rtdbRead, patchAgentSessionSnapshot, writeSessionState, clearSessionState, writeTurnState, clearTurnState, } from './rtdb-rest.js';
|
|
29
|
+
export { initRTDBAuth, rtdbWrite, rtdbRead, patchAgentSessionSnapshot, patchRuntimeInfo, writeRuntimeInfo, clearRuntimeInfo, writeSessionState, clearSessionState, writeTurnState, clearTurnState, } from './rtdb-rest.js';
|
|
29
30
|
// Constants
|
|
30
31
|
export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
|
|
31
32
|
// Base URL resolver
|
package/dist/rtdb-rest.d.ts
CHANGED
|
@@ -7,14 +7,18 @@
|
|
|
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
11
|
export interface SessionStatePayload {
|
|
11
12
|
lastError?: string;
|
|
12
13
|
model?: string;
|
|
13
14
|
permissionMode?: string;
|
|
14
15
|
effort?: string;
|
|
16
|
+
runtimeControlValues?: Record<string, CanonControlValue>;
|
|
15
17
|
cwd?: string;
|
|
16
18
|
executionMode?: 'worktree' | 'locked';
|
|
17
19
|
executionBranch?: string;
|
|
20
|
+
worktreePath?: string;
|
|
21
|
+
executionFallbackReason?: string;
|
|
18
22
|
hostMode?: boolean;
|
|
19
23
|
clientType?: string;
|
|
20
24
|
isActive: boolean;
|
|
@@ -63,6 +67,8 @@ export interface AgentSessionSnapshotPatch {
|
|
|
63
67
|
value: string;
|
|
64
68
|
label: string;
|
|
65
69
|
}> | null;
|
|
70
|
+
effort?: string | null;
|
|
71
|
+
runtimeControlValues?: Record<string, CanonControlValue> | null;
|
|
66
72
|
workspaceId?: string | null;
|
|
67
73
|
workspaceOptions?: Array<{
|
|
68
74
|
id: string;
|
|
@@ -71,8 +77,12 @@ export interface AgentSessionSnapshotPatch {
|
|
|
71
77
|
executionMode?: 'worktree' | 'locked' | null;
|
|
72
78
|
availableExecutionModes?: Array<'worktree' | 'locked'> | null;
|
|
73
79
|
executionBranch?: string | null;
|
|
80
|
+
resolvedCwd?: string | null;
|
|
81
|
+
worktreePath?: string | null;
|
|
82
|
+
executionFallbackReason?: string | null;
|
|
74
83
|
state?: 'idle' | 'running' | 'requires_action' | null;
|
|
75
84
|
turnState?: TurnLifecycleState | null;
|
|
85
|
+
supportsQueue?: boolean | null;
|
|
76
86
|
queueDepth?: number;
|
|
77
87
|
waitingForInput?: boolean;
|
|
78
88
|
contextUsage?: {
|
|
@@ -95,6 +105,11 @@ export interface AgentSessionSnapshotPatch {
|
|
|
95
105
|
'.sv': 'timestamp';
|
|
96
106
|
};
|
|
97
107
|
}
|
|
108
|
+
export interface RuntimeInfoPayloadData extends Omit<RuntimeInfoPayload, 'updatedAt'> {
|
|
109
|
+
updatedAt: {
|
|
110
|
+
'.sv': 'timestamp';
|
|
111
|
+
};
|
|
112
|
+
}
|
|
98
113
|
interface RTDBAuthOptions {
|
|
99
114
|
rtdbUrl?: string;
|
|
100
115
|
firebaseApiKey?: string;
|
|
@@ -109,6 +124,9 @@ interface RTDBClientHandle {
|
|
|
109
124
|
writeTurnState(conversationId: string, agentId: string, state: Omit<TurnStatePayload, 'updatedAt'>): Promise<void>;
|
|
110
125
|
clearTurnState(conversationId: string, agentId: string): Promise<void>;
|
|
111
126
|
patchAgentSessionSnapshot(conversationId: string, agentId: string, snapshot: Omit<AgentSessionSnapshotPatch, 'updatedAt'>): Promise<void>;
|
|
127
|
+
writeRuntimeInfo(conversationId: string, agentId: string, payload: Omit<RuntimeInfoPayload, 'updatedAt'>): Promise<void>;
|
|
128
|
+
patchRuntimeInfo(conversationId: string, agentId: string, payload: Partial<Omit<RuntimeInfoPayload, 'updatedAt'>>): Promise<void>;
|
|
129
|
+
clearRuntimeInfo(conversationId: string, agentId: string): Promise<void>;
|
|
112
130
|
}
|
|
113
131
|
/**
|
|
114
132
|
* Initializes the default RTDB helper and returns a scoped client for callers
|
|
@@ -131,4 +149,7 @@ export declare function clearSessionState(conversationId: string, agentId: strin
|
|
|
131
149
|
export declare function writeTurnState(conversationId: string, agentId: string, state: Omit<TurnStatePayload, 'updatedAt'>): Promise<void>;
|
|
132
150
|
export declare function clearTurnState(conversationId: string, agentId: string): Promise<void>;
|
|
133
151
|
export declare function patchAgentSessionSnapshot(conversationId: string, agentId: string, snapshot: Omit<AgentSessionSnapshotPatch, 'updatedAt'>): Promise<void>;
|
|
152
|
+
export declare function writeRuntimeInfo(conversationId: string, agentId: string, payload: Omit<RuntimeInfoPayload, 'updatedAt'>): Promise<void>;
|
|
153
|
+
export declare function patchRuntimeInfo(conversationId: string, agentId: string, payload: Partial<Omit<RuntimeInfoPayload, 'updatedAt'>>): Promise<void>;
|
|
154
|
+
export declare function clearRuntimeInfo(conversationId: string, agentId: string): Promise<void>;
|
|
134
155
|
export {};
|
package/dist/rtdb-rest.js
CHANGED
|
@@ -18,6 +18,9 @@ function normalizeRTDBPath(path) {
|
|
|
18
18
|
function buildAgentSessionPath(conversationId, agentId) {
|
|
19
19
|
return `/agent-session/${conversationId}/${agentId}`;
|
|
20
20
|
}
|
|
21
|
+
function buildRuntimeInfoPath(conversationId, agentId) {
|
|
22
|
+
return `/runtime-info/${conversationId}/${agentId}`;
|
|
23
|
+
}
|
|
21
24
|
function createRTDBClientHandle(client, options) {
|
|
22
25
|
const rtdbBase = normalizeRTDBBase(options?.rtdbUrl || DEFAULT_RTDB_BASE);
|
|
23
26
|
const firebaseApiKey = options?.firebaseApiKey || DEFAULT_FIREBASE_API_KEY;
|
|
@@ -137,9 +140,18 @@ function createRTDBClientHandle(client, options) {
|
|
|
137
140
|
...(typeof state.hostMode === 'boolean' ? { hostMode: state.hostMode } : {}),
|
|
138
141
|
...(state.model !== undefined ? { model: state.model } : {}),
|
|
139
142
|
...(state.permissionMode !== undefined ? { permissionMode: state.permissionMode } : {}),
|
|
143
|
+
...(state.effort !== undefined ? { effort: state.effort } : {}),
|
|
144
|
+
...(state.runtimeControlValues !== undefined
|
|
145
|
+
? { runtimeControlValues: state.runtimeControlValues }
|
|
146
|
+
: {}),
|
|
140
147
|
...(state.availableModels !== undefined ? { modelOptions: state.availableModels } : {}),
|
|
148
|
+
...(state.cwd !== undefined ? { resolvedCwd: state.cwd } : {}),
|
|
141
149
|
...(state.executionMode !== undefined ? { executionMode: state.executionMode } : {}),
|
|
142
150
|
...(state.executionBranch !== undefined ? { executionBranch: state.executionBranch } : {}),
|
|
151
|
+
...(state.worktreePath !== undefined ? { worktreePath: state.worktreePath } : {}),
|
|
152
|
+
...(state.executionFallbackReason !== undefined
|
|
153
|
+
? { executionFallbackReason: state.executionFallbackReason }
|
|
154
|
+
: {}),
|
|
143
155
|
...(state.state !== undefined ? { state: state.state } : {}),
|
|
144
156
|
waitingForInput: state.state === 'requires_action',
|
|
145
157
|
...(state.contextUsage !== undefined ? { contextUsage: state.contextUsage } : {}),
|
|
@@ -160,6 +172,8 @@ function createRTDBClientHandle(client, options) {
|
|
|
160
172
|
lastError: null,
|
|
161
173
|
executionBranch: null,
|
|
162
174
|
contextUsage: null,
|
|
175
|
+
worktreePath: null,
|
|
176
|
+
executionFallbackReason: null,
|
|
163
177
|
updatedAt: { '.sv': 'timestamp' },
|
|
164
178
|
});
|
|
165
179
|
}
|
|
@@ -174,6 +188,9 @@ function createRTDBClientHandle(client, options) {
|
|
|
174
188
|
});
|
|
175
189
|
await patch(buildAgentSessionPath(conversationId, agentId), {
|
|
176
190
|
turnState: state.state,
|
|
191
|
+
...(state.capabilities?.supportsQueue !== undefined
|
|
192
|
+
? { supportsQueue: state.capabilities.supportsQueue }
|
|
193
|
+
: {}),
|
|
177
194
|
queueDepth: state.queueDepth,
|
|
178
195
|
waitingForInput: state.state === 'waiting_input',
|
|
179
196
|
lastHeartbeatAt: { '.sv': 'timestamp' },
|
|
@@ -205,6 +222,21 @@ function createRTDBClientHandle(client, options) {
|
|
|
205
222
|
updatedAt: { '.sv': 'timestamp' },
|
|
206
223
|
});
|
|
207
224
|
}
|
|
225
|
+
async function writeRuntimeInfoImpl(conversationId, agentId, payload) {
|
|
226
|
+
await write(buildRuntimeInfoPath(conversationId, agentId), {
|
|
227
|
+
...payload,
|
|
228
|
+
updatedAt: { '.sv': 'timestamp' },
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
async function patchRuntimeInfoImpl(conversationId, agentId, payload) {
|
|
232
|
+
await patch(buildRuntimeInfoPath(conversationId, agentId), {
|
|
233
|
+
...payload,
|
|
234
|
+
updatedAt: { '.sv': 'timestamp' },
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
async function clearRuntimeInfoImpl(conversationId, agentId) {
|
|
238
|
+
await remove(buildRuntimeInfoPath(conversationId, agentId));
|
|
239
|
+
}
|
|
208
240
|
return {
|
|
209
241
|
read,
|
|
210
242
|
write,
|
|
@@ -215,6 +247,9 @@ function createRTDBClientHandle(client, options) {
|
|
|
215
247
|
writeTurnState: writeTurnStateImpl,
|
|
216
248
|
clearTurnState: clearTurnStateImpl,
|
|
217
249
|
patchAgentSessionSnapshot: patchAgentSessionSnapshotImpl,
|
|
250
|
+
writeRuntimeInfo: writeRuntimeInfoImpl,
|
|
251
|
+
patchRuntimeInfo: patchRuntimeInfoImpl,
|
|
252
|
+
clearRuntimeInfo: clearRuntimeInfoImpl,
|
|
218
253
|
};
|
|
219
254
|
}
|
|
220
255
|
/**
|
|
@@ -260,3 +295,12 @@ export async function clearTurnState(conversationId, agentId) {
|
|
|
260
295
|
export async function patchAgentSessionSnapshot(conversationId, agentId, snapshot) {
|
|
261
296
|
await getDefaultRTDBClient()?.patchAgentSessionSnapshot(conversationId, agentId, snapshot);
|
|
262
297
|
}
|
|
298
|
+
export async function writeRuntimeInfo(conversationId, agentId, payload) {
|
|
299
|
+
await getDefaultRTDBClient()?.writeRuntimeInfo(conversationId, agentId, payload);
|
|
300
|
+
}
|
|
301
|
+
export async function patchRuntimeInfo(conversationId, agentId, payload) {
|
|
302
|
+
await getDefaultRTDBClient()?.patchRuntimeInfo(conversationId, agentId, payload);
|
|
303
|
+
}
|
|
304
|
+
export async function clearRuntimeInfo(conversationId, agentId) {
|
|
305
|
+
await getDefaultRTDBClient()?.clearRuntimeInfo(conversationId, agentId);
|
|
306
|
+
}
|
package/dist/runtime-cards.d.ts
CHANGED
|
@@ -21,6 +21,13 @@ export interface ClaudeQuestionReplyMetadata {
|
|
|
21
21
|
export interface PlanApprovalMetadata {
|
|
22
22
|
type: 'plan_approval';
|
|
23
23
|
planId: string;
|
|
24
|
+
title?: string;
|
|
25
|
+
summary?: string;
|
|
26
|
+
body?: string;
|
|
27
|
+
allowedPrompts?: ReadonlyArray<{
|
|
28
|
+
tool: string;
|
|
29
|
+
prompt: string;
|
|
30
|
+
}>;
|
|
24
31
|
}
|
|
25
32
|
export interface PlanApprovalReplyMetadata {
|
|
26
33
|
type: 'plan_approval_reply';
|
|
@@ -36,7 +43,7 @@ export declare function buildQuestionReply(questionId: string, answers: Record<s
|
|
|
36
43
|
text: string;
|
|
37
44
|
metadata: ClaudeQuestionReplyMetadata;
|
|
38
45
|
};
|
|
39
|
-
export declare function buildPlanApprovalRequest(planId: string, text?: string): {
|
|
46
|
+
export declare function buildPlanApprovalRequest(planId: string, text?: string, details?: Omit<PlanApprovalMetadata, 'type' | 'planId'>): {
|
|
40
47
|
text: string;
|
|
41
48
|
metadata: PlanApprovalMetadata;
|
|
42
49
|
};
|
package/dist/runtime-cards.js
CHANGED
|
@@ -22,12 +22,13 @@ export function buildQuestionReply(questionId, answers) {
|
|
|
22
22
|
},
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
export function buildPlanApprovalRequest(planId, text = 'Plan ready for review.') {
|
|
25
|
+
export function buildPlanApprovalRequest(planId, text = 'Plan ready for review.', details) {
|
|
26
26
|
return {
|
|
27
27
|
text,
|
|
28
28
|
metadata: {
|
|
29
29
|
type: 'plan_approval',
|
|
30
30
|
planId,
|
|
31
|
+
...(details ?? {}),
|
|
31
32
|
},
|
|
32
33
|
};
|
|
33
34
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -132,10 +132,130 @@ export interface AgentCapabilities {
|
|
|
132
132
|
export interface ModelOption {
|
|
133
133
|
value: string;
|
|
134
134
|
label: string;
|
|
135
|
+
description?: string;
|
|
136
|
+
workspaceRootId?: string;
|
|
137
|
+
workspaceRelativePath?: string;
|
|
138
|
+
source?: WorkspaceOptionSource;
|
|
135
139
|
}
|
|
140
|
+
export type WorkspaceOptionSource = 'default' | 'explicit' | 'discovered';
|
|
136
141
|
export interface WorkspaceOption {
|
|
137
142
|
id: string;
|
|
138
143
|
label: string;
|
|
144
|
+
description?: string;
|
|
145
|
+
workspaceRootId?: string;
|
|
146
|
+
workspaceRelativePath?: string;
|
|
147
|
+
source?: WorkspaceOptionSource;
|
|
148
|
+
}
|
|
149
|
+
export interface CanonWorkspaceRootMetadata {
|
|
150
|
+
id: string;
|
|
151
|
+
label: string;
|
|
152
|
+
description?: string;
|
|
153
|
+
defaultRelativePath?: string | null;
|
|
154
|
+
}
|
|
155
|
+
export type CanonControlValue = string;
|
|
156
|
+
export type CanonControlAvailability = 'setup' | 'live' | 'setup_and_live';
|
|
157
|
+
export type CanonControlLiveBehavior = 'immediate' | 'next_turn' | 'none';
|
|
158
|
+
export type CanonControlSelectionPolicy = 'inherit' | 'required_explicit';
|
|
159
|
+
export type CanonRuntimeStreamingMode = 'none' | 'status' | 'snapshot' | 'block' | 'delta';
|
|
160
|
+
export type CanonRuntimeSurfaceMode = 'host' | 'channel' | 'limited_channel' | 'operator';
|
|
161
|
+
export type CanonRuntimeInventoryStatus = 'ready' | 'auth_needed' | 'unknown' | 'configured' | 'running' | 'error';
|
|
162
|
+
export type CanonRuntimeStatusTone = 'default' | 'success' | 'warning' | 'danger';
|
|
163
|
+
export type CanonRuntimeActionAvailability = 'idle' | 'busy' | 'busy_with_queue' | 'waiting_input' | 'always';
|
|
164
|
+
export type CanonRuntimeActionPlacement = 'composer_slash' | 'command_palette' | 'session_strip';
|
|
165
|
+
export type CanonRuntimeActionCategory = 'plan' | 'turn' | 'session' | 'details' | 'custom';
|
|
166
|
+
export type CanonRuntimeActionDispatch = {
|
|
167
|
+
kind: 'control';
|
|
168
|
+
controlId: string;
|
|
169
|
+
value: CanonControlValue;
|
|
170
|
+
} | {
|
|
171
|
+
kind: 'signal';
|
|
172
|
+
signal: 'interrupt' | 'stop_and_drop';
|
|
173
|
+
} | {
|
|
174
|
+
kind: 'compose';
|
|
175
|
+
text: string;
|
|
176
|
+
} | {
|
|
177
|
+
kind: 'open_details';
|
|
178
|
+
target?: string;
|
|
179
|
+
};
|
|
180
|
+
export interface CanonRuntimeActionDescriptor {
|
|
181
|
+
id: string;
|
|
182
|
+
label: string;
|
|
183
|
+
description?: string;
|
|
184
|
+
aliases?: ReadonlyArray<string>;
|
|
185
|
+
category?: CanonRuntimeActionCategory;
|
|
186
|
+
placements?: ReadonlyArray<CanonRuntimeActionPlacement>;
|
|
187
|
+
availability?: ReadonlyArray<CanonRuntimeActionAvailability>;
|
|
188
|
+
ownerOnly?: boolean;
|
|
189
|
+
disabledReason?: string | null;
|
|
190
|
+
trailingTextBehavior?: 'ignore' | 'send_as_prompt';
|
|
191
|
+
dispatch: CanonRuntimeActionDispatch;
|
|
192
|
+
}
|
|
193
|
+
export interface CanonControlDescriptor {
|
|
194
|
+
id: string;
|
|
195
|
+
label: string;
|
|
196
|
+
options?: ReadonlyArray<ModelOption>;
|
|
197
|
+
defaultValue?: CanonControlValue | null;
|
|
198
|
+
availability: CanonControlAvailability;
|
|
199
|
+
liveBehavior: CanonControlLiveBehavior;
|
|
200
|
+
selectionPolicy: CanonControlSelectionPolicy;
|
|
201
|
+
description?: string;
|
|
202
|
+
}
|
|
203
|
+
export interface CanonRuntimeDescriptor {
|
|
204
|
+
coreControls: ReadonlyArray<CanonControlDescriptor>;
|
|
205
|
+
runtimeControls?: ReadonlyArray<CanonControlDescriptor>;
|
|
206
|
+
actions?: ReadonlyArray<CanonRuntimeActionDescriptor>;
|
|
207
|
+
/**
|
|
208
|
+
* Optional setup-time local roots advertised by a runtime. These are
|
|
209
|
+
* metadata only for now; existing session config still selects concrete
|
|
210
|
+
* workspace IDs until root-relative directory selection lands.
|
|
211
|
+
*/
|
|
212
|
+
workspaceRoots?: ReadonlyArray<CanonWorkspaceRootMetadata>;
|
|
213
|
+
writableRoots?: ReadonlyArray<CanonWorkspaceRootMetadata>;
|
|
214
|
+
supportsInterrupt?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Fidelity of live text exposed through Canon's streaming bubble path.
|
|
217
|
+
* `delta` means token/content deltas, `block` means chunked live previews,
|
|
218
|
+
* `snapshot` means completed assistant-message snapshots, and `status`
|
|
219
|
+
* means activity/tool state without live assistant text.
|
|
220
|
+
*/
|
|
221
|
+
streamingTextMode?: CanonRuntimeStreamingMode;
|
|
222
|
+
}
|
|
223
|
+
export interface CanonRuntimeExecutionMetadata {
|
|
224
|
+
resolvedWorkspaceLabel?: string | null;
|
|
225
|
+
resolvedCwd?: string | null;
|
|
226
|
+
workspaceRootId?: string | null;
|
|
227
|
+
workspaceRelativePath?: string | null;
|
|
228
|
+
executionMode?: ExecutionEnvironmentMode | null;
|
|
229
|
+
executionBranch?: string | null;
|
|
230
|
+
worktreePath?: string | null;
|
|
231
|
+
fallbackReason?: string | null;
|
|
232
|
+
}
|
|
233
|
+
export interface CanonRuntimeStatusItem {
|
|
234
|
+
id: string;
|
|
235
|
+
label: string;
|
|
236
|
+
value: string;
|
|
237
|
+
tone?: CanonRuntimeStatusTone;
|
|
238
|
+
}
|
|
239
|
+
export interface CanonRuntimeInventoryEntry {
|
|
240
|
+
id: string;
|
|
241
|
+
label: string;
|
|
242
|
+
status?: CanonRuntimeInventoryStatus;
|
|
243
|
+
description?: string;
|
|
244
|
+
}
|
|
245
|
+
export interface CanonRuntimeInventory {
|
|
246
|
+
id: string;
|
|
247
|
+
label: string;
|
|
248
|
+
entries: ReadonlyArray<CanonRuntimeInventoryEntry>;
|
|
249
|
+
}
|
|
250
|
+
export interface RuntimeInfoPayload {
|
|
251
|
+
descriptor: CanonRuntimeDescriptor;
|
|
252
|
+
surfaceMode?: CanonRuntimeSurfaceMode;
|
|
253
|
+
surfaceLabel?: string;
|
|
254
|
+
statusItems?: ReadonlyArray<CanonRuntimeStatusItem>;
|
|
255
|
+
inventories?: ReadonlyArray<CanonRuntimeInventory>;
|
|
256
|
+
execution?: CanonRuntimeExecutionMetadata | null;
|
|
257
|
+
notes?: ReadonlyArray<string>;
|
|
258
|
+
updatedAt?: number;
|
|
139
259
|
}
|
|
140
260
|
/** Capability map keyed by clientType. Add new agent types here. */
|
|
141
261
|
export declare const AGENT_CAPABILITIES: Record<AgentClientType, AgentCapabilities>;
|
|
@@ -193,6 +313,7 @@ export interface RuntimeUpdatedPayload {
|
|
|
193
313
|
conversationId: string;
|
|
194
314
|
agentId: string;
|
|
195
315
|
runtime: AgentRuntime | null;
|
|
316
|
+
runtimeInfo?: RuntimeInfoPayload | null;
|
|
196
317
|
sessionState: SessionState | null;
|
|
197
318
|
sessionConfig: SessionConfig | null;
|
|
198
319
|
}
|
|
@@ -265,8 +386,9 @@ export interface SetStreamingOptions {
|
|
|
265
386
|
/** Written by Canon app to /control/{convoId}/{agentId}/session in RTDB */
|
|
266
387
|
export interface SessionControl {
|
|
267
388
|
model?: string;
|
|
268
|
-
permissionMode?:
|
|
269
|
-
effort?:
|
|
389
|
+
permissionMode?: string;
|
|
390
|
+
effort?: string;
|
|
391
|
+
runtimeControlValues?: Record<string, CanonControlValue>;
|
|
270
392
|
updatedAt: number;
|
|
271
393
|
updatedBy: string;
|
|
272
394
|
}
|
|
@@ -276,9 +398,12 @@ export interface SessionState {
|
|
|
276
398
|
model?: string;
|
|
277
399
|
permissionMode?: string;
|
|
278
400
|
effort?: string;
|
|
401
|
+
runtimeControlValues?: Record<string, CanonControlValue>;
|
|
279
402
|
cwd?: string;
|
|
280
403
|
executionMode?: 'worktree' | 'locked';
|
|
281
404
|
executionBranch?: string;
|
|
405
|
+
worktreePath?: string;
|
|
406
|
+
executionFallbackReason?: string;
|
|
282
407
|
clientType?: AgentClientType;
|
|
283
408
|
/** True when the agent is running under the host wrapper (host.ts) which can apply control signals */
|
|
284
409
|
hostMode?: boolean;
|
|
@@ -297,6 +422,8 @@ export interface SessionConfig {
|
|
|
297
422
|
hostMode?: boolean;
|
|
298
423
|
model?: string;
|
|
299
424
|
permissionMode?: string;
|
|
425
|
+
effort?: string;
|
|
426
|
+
runtimeControlValues?: Record<string, CanonControlValue>;
|
|
300
427
|
workspaceId?: string;
|
|
301
428
|
/**
|
|
302
429
|
* Explicitly selected execution mode. Sessions created before this field
|
|
@@ -322,6 +449,9 @@ export declare const CLAUDE_PERMISSION_MODE_OPTIONS: readonly [{
|
|
|
322
449
|
}, {
|
|
323
450
|
readonly value: "plan";
|
|
324
451
|
readonly label: "Plan";
|
|
452
|
+
}, {
|
|
453
|
+
readonly value: "dontAsk";
|
|
454
|
+
readonly label: "Don't ask";
|
|
325
455
|
}, {
|
|
326
456
|
readonly value: "bypassPermissions";
|
|
327
457
|
readonly label: "Bypass";
|
|
@@ -335,6 +465,7 @@ export interface AgentRuntime {
|
|
|
335
465
|
defaultModel?: string;
|
|
336
466
|
defaultPermissionMode?: string;
|
|
337
467
|
availablePermissionModes?: PermissionModeOption[];
|
|
468
|
+
runtimeDescriptor?: CanonRuntimeDescriptor;
|
|
338
469
|
defaultWorkspaceId?: string;
|
|
339
470
|
/**
|
|
340
471
|
* Execution modes the host will accept. The runtime advertises this so the
|
|
@@ -367,13 +498,22 @@ export interface AgentSessionSnapshot {
|
|
|
367
498
|
modelOptions?: ModelOption[];
|
|
368
499
|
permissionMode?: string;
|
|
369
500
|
permissionModeOptions?: PermissionModeOption[];
|
|
501
|
+
effort?: string;
|
|
502
|
+
runtimeControlValues?: Record<string, CanonControlValue>;
|
|
503
|
+
runtimeDescriptor?: CanonRuntimeDescriptor | null;
|
|
504
|
+
runtimeInfo?: RuntimeInfoPayload | null;
|
|
370
505
|
workspaceId?: string;
|
|
371
506
|
workspaceOptions?: WorkspaceOption[];
|
|
372
507
|
executionMode?: ExecutionEnvironmentMode;
|
|
373
508
|
availableExecutionModes?: ExecutionEnvironmentMode[];
|
|
374
509
|
executionBranch?: string;
|
|
510
|
+
resolvedWorkspaceLabel?: string | null;
|
|
511
|
+
resolvedCwd?: string | null;
|
|
512
|
+
worktreePath?: string | null;
|
|
513
|
+
executionFallbackReason?: string | null;
|
|
375
514
|
state?: SessionState['state'];
|
|
376
515
|
turnState?: TurnLifecycleState;
|
|
516
|
+
supportsQueue?: boolean;
|
|
377
517
|
queueDepth: number;
|
|
378
518
|
waitingForInput: boolean;
|
|
379
519
|
contextUsage?: SessionState['contextUsage'];
|
package/dist/types.js
CHANGED
|
@@ -36,6 +36,7 @@ export const CLAUDE_PERMISSION_MODE_OPTIONS = [
|
|
|
36
36
|
{ value: 'default', label: 'Default' },
|
|
37
37
|
{ value: 'acceptEdits', label: 'Auto-edit' },
|
|
38
38
|
{ value: 'plan', label: 'Plan' },
|
|
39
|
+
{ value: 'dontAsk', label: "Don't ask" },
|
|
39
40
|
{ value: 'bypassPermissions', label: 'Bypass' },
|
|
40
41
|
{ value: 'auto', label: 'Auto' },
|
|
41
42
|
];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ConfiguredWorkspaceOption } from './execution-environment.js';
|
|
2
|
+
import type { CanonWorkspaceRootMetadata } from './types.js';
|
|
3
|
+
export interface ConfiguredWorkspaceRoot extends CanonWorkspaceRootMetadata {
|
|
4
|
+
cwd: string;
|
|
5
|
+
}
|
|
6
|
+
export interface WorkspaceDiscoveryResult {
|
|
7
|
+
workspaceOptions: ConfiguredWorkspaceOption[];
|
|
8
|
+
workspaceRoots: ConfiguredWorkspaceRoot[];
|
|
9
|
+
warnings: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function buildWorkspaceRootId(workspaceRoot: string): string;
|
|
12
|
+
export declare function discoverWorkspaceProjects(root: ConfiguredWorkspaceRoot, warnings?: string[]): ConfiguredWorkspaceOption[];
|
|
13
|
+
export declare function buildPublicWorkspaceRoots(roots: ReadonlyArray<ConfiguredWorkspaceRoot>): CanonWorkspaceRootMetadata[];
|
|
14
|
+
export declare function buildConfiguredWorkspaceOptionsWithRoots(input: {
|
|
15
|
+
primaryCwd: string;
|
|
16
|
+
configuredWorkspaces?: string[];
|
|
17
|
+
workspaceRoots?: string[];
|
|
18
|
+
}): WorkspaceDiscoveryResult;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, readdirSync, realpathSync, statSync } from 'node:fs';
|
|
3
|
+
import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import { buildConfiguredWorkspaceOptions, buildWorkspaceOptionId, } from './execution-environment.js';
|
|
5
|
+
const PROJECT_MARKERS = [
|
|
6
|
+
'.git',
|
|
7
|
+
'package.json',
|
|
8
|
+
'pyproject.toml',
|
|
9
|
+
'Cargo.toml',
|
|
10
|
+
'go.mod',
|
|
11
|
+
];
|
|
12
|
+
const IGNORED_PROJECT_DIRS = new Set([
|
|
13
|
+
'.cache',
|
|
14
|
+
'.git',
|
|
15
|
+
'.hg',
|
|
16
|
+
'.svn',
|
|
17
|
+
'.turbo',
|
|
18
|
+
'.yarn',
|
|
19
|
+
'build',
|
|
20
|
+
'coverage',
|
|
21
|
+
'dist',
|
|
22
|
+
'node_modules',
|
|
23
|
+
'target',
|
|
24
|
+
'vendor',
|
|
25
|
+
]);
|
|
26
|
+
function shortHash(value) {
|
|
27
|
+
return createHash('sha256').update(value).digest('hex').slice(0, 12);
|
|
28
|
+
}
|
|
29
|
+
export function buildWorkspaceRootId(workspaceRoot) {
|
|
30
|
+
let stablePath = resolve(workspaceRoot);
|
|
31
|
+
try {
|
|
32
|
+
stablePath = realpathSync(stablePath);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Nonexistent roots are validated elsewhere; keep deterministic IDs.
|
|
36
|
+
}
|
|
37
|
+
return `workspace-root-${shortHash(stablePath)}`;
|
|
38
|
+
}
|
|
39
|
+
function realDirectory(path) {
|
|
40
|
+
try {
|
|
41
|
+
const resolved = resolve(path);
|
|
42
|
+
if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return realpathSync(resolved);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function isWithin(parent, child) {
|
|
52
|
+
const rel = relative(parent, child);
|
|
53
|
+
return rel === '' || (rel.length > 0 && !rel.startsWith('..') && !isAbsolute(rel));
|
|
54
|
+
}
|
|
55
|
+
function toRelativeProjectPath(rootCwd, projectCwd) {
|
|
56
|
+
const rel = relative(rootCwd, projectCwd).split(sep).join('/');
|
|
57
|
+
return rel || '.';
|
|
58
|
+
}
|
|
59
|
+
function hasProjectMarker(cwd) {
|
|
60
|
+
return PROJECT_MARKERS.some((marker) => existsSync(join(cwd, marker)));
|
|
61
|
+
}
|
|
62
|
+
function normalizeWorkspaceRoots(workspaceRoots) {
|
|
63
|
+
const roots = [];
|
|
64
|
+
const warnings = [];
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
const seenLabels = new Map();
|
|
67
|
+
for (const rawRoot of workspaceRoots) {
|
|
68
|
+
const cwd = realDirectory(rawRoot);
|
|
69
|
+
if (!cwd) {
|
|
70
|
+
warnings.push(`Workspace root is not a readable directory: ${rawRoot}`);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (seen.has(cwd)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
seen.add(cwd);
|
|
77
|
+
const baseLabel = basename(cwd) || cwd;
|
|
78
|
+
const seenLabelCount = (seenLabels.get(baseLabel) ?? 0) + 1;
|
|
79
|
+
seenLabels.set(baseLabel, seenLabelCount);
|
|
80
|
+
roots.push({
|
|
81
|
+
id: buildWorkspaceRootId(cwd),
|
|
82
|
+
label: seenLabelCount === 1 ? baseLabel : `${baseLabel} (${seenLabelCount})`,
|
|
83
|
+
cwd,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return { roots, warnings };
|
|
87
|
+
}
|
|
88
|
+
function findWorkspaceRoot(roots, cwd) {
|
|
89
|
+
const resolved = realDirectory(cwd) ?? resolve(cwd);
|
|
90
|
+
return [...roots]
|
|
91
|
+
.sort((a, b) => b.cwd.length - a.cwd.length)
|
|
92
|
+
.find((root) => isWithin(root.cwd, resolved)) ?? null;
|
|
93
|
+
}
|
|
94
|
+
function annotateWorkspaceOption(option, roots) {
|
|
95
|
+
const root = findWorkspaceRoot(roots, option.cwd);
|
|
96
|
+
if (!root) {
|
|
97
|
+
return option;
|
|
98
|
+
}
|
|
99
|
+
const stableCwd = realDirectory(option.cwd) ?? resolve(option.cwd);
|
|
100
|
+
const relativePath = toRelativeProjectPath(root.cwd, stableCwd);
|
|
101
|
+
return {
|
|
102
|
+
...option,
|
|
103
|
+
workspaceRootId: root.id,
|
|
104
|
+
workspaceRelativePath: relativePath,
|
|
105
|
+
description: relativePath === '.'
|
|
106
|
+
? `${root.label} root`
|
|
107
|
+
: `${root.label}/${relativePath}`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export function discoverWorkspaceProjects(root, warnings) {
|
|
111
|
+
const projects = [];
|
|
112
|
+
if (hasProjectMarker(root.cwd)) {
|
|
113
|
+
projects.push({
|
|
114
|
+
id: buildWorkspaceOptionId(root.cwd),
|
|
115
|
+
label: root.label,
|
|
116
|
+
cwd: root.cwd,
|
|
117
|
+
workspaceRootId: root.id,
|
|
118
|
+
workspaceRelativePath: '.',
|
|
119
|
+
description: `${root.label} root`,
|
|
120
|
+
source: 'discovered',
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
let entries;
|
|
124
|
+
try {
|
|
125
|
+
entries = readdirSync(root.cwd, { withFileTypes: true });
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
warnings?.push(`Workspace root could not be scanned: ${root.cwd}`);
|
|
129
|
+
return projects;
|
|
130
|
+
}
|
|
131
|
+
for (const entry of entries) {
|
|
132
|
+
if (!entry.isDirectory() || IGNORED_PROJECT_DIRS.has(entry.name)) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const cwd = realDirectory(join(root.cwd, entry.name));
|
|
136
|
+
if (!cwd || !isWithin(root.cwd, cwd) || !hasProjectMarker(cwd)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const relativePath = toRelativeProjectPath(root.cwd, cwd);
|
|
140
|
+
projects.push({
|
|
141
|
+
id: buildWorkspaceOptionId(cwd),
|
|
142
|
+
label: basename(cwd) || relativePath,
|
|
143
|
+
cwd,
|
|
144
|
+
workspaceRootId: root.id,
|
|
145
|
+
workspaceRelativePath: relativePath,
|
|
146
|
+
description: `${root.label}/${relativePath}`,
|
|
147
|
+
source: 'discovered',
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return projects;
|
|
151
|
+
}
|
|
152
|
+
export function buildPublicWorkspaceRoots(roots) {
|
|
153
|
+
return roots.map((root) => ({
|
|
154
|
+
id: root.id,
|
|
155
|
+
label: root.label,
|
|
156
|
+
...(root.description ? { description: root.description } : {}),
|
|
157
|
+
...(root.defaultRelativePath !== undefined
|
|
158
|
+
? { defaultRelativePath: root.defaultRelativePath }
|
|
159
|
+
: {}),
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
function relabelWorkspaceOptions(options) {
|
|
163
|
+
const seenLabels = new Map();
|
|
164
|
+
return options.map((option) => {
|
|
165
|
+
const seenCount = (seenLabels.get(option.label) ?? 0) + 1;
|
|
166
|
+
seenLabels.set(option.label, seenCount);
|
|
167
|
+
return seenCount === 1
|
|
168
|
+
? option
|
|
169
|
+
: { ...option, label: `${option.label} (${seenCount})` };
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
export function buildConfiguredWorkspaceOptionsWithRoots(input) {
|
|
173
|
+
const normalizedRoots = normalizeWorkspaceRoots(input.workspaceRoots ?? []);
|
|
174
|
+
const explicitOptions = buildConfiguredWorkspaceOptions(input.primaryCwd, input.configuredWorkspaces ?? []).map((option) => annotateWorkspaceOption(option, normalizedRoots.roots));
|
|
175
|
+
const discoveryWarnings = [];
|
|
176
|
+
const discoveredOptions = normalizedRoots.roots.flatMap((root) => (discoverWorkspaceProjects(root, discoveryWarnings)));
|
|
177
|
+
const byCwd = new Map();
|
|
178
|
+
for (const option of discoveredOptions) {
|
|
179
|
+
byCwd.set(resolve(option.cwd), option);
|
|
180
|
+
}
|
|
181
|
+
for (const option of explicitOptions) {
|
|
182
|
+
byCwd.set(resolve(option.cwd), option);
|
|
183
|
+
}
|
|
184
|
+
const ordered = [
|
|
185
|
+
...explicitOptions,
|
|
186
|
+
...discoveredOptions.filter((option) => !explicitOptions.some((explicit) => resolve(explicit.cwd) === resolve(option.cwd))),
|
|
187
|
+
].filter((option, index, options) => (options.findIndex((candidate) => resolve(candidate.cwd) === resolve(option.cwd)) === index)).map((option) => byCwd.get(resolve(option.cwd)) ?? option);
|
|
188
|
+
return {
|
|
189
|
+
workspaceOptions: relabelWorkspaceOptions(ordered),
|
|
190
|
+
workspaceRoots: normalizedRoots.roots,
|
|
191
|
+
warnings: [...normalizedRoots.warnings, ...discoveryWarnings],
|
|
192
|
+
};
|
|
193
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
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",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc",
|
|
25
25
|
"dev": "tsc --watch",
|
|
26
|
+
"test": "vitest run",
|
|
26
27
|
"prepack": "npm run build"
|
|
27
28
|
},
|
|
28
29
|
"engines": {
|