@skrr-ai/cli 0.1.113 → 0.1.115
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/bin/update-npm-runner.cjs +4 -1
- package/bin/update-worker.cjs +6 -3
- package/dist/commands/agents/chat.js +10 -1
- package/dist/commands/computer-use/audio.d.ts +6 -0
- package/dist/commands/computer-use/audio.js +9 -0
- package/dist/commands/computer-use/browser.d.ts +7 -0
- package/dist/commands/computer-use/browser.js +16 -0
- package/dist/commands/computer-use/disable.d.ts +6 -0
- package/dist/commands/computer-use/disable.js +9 -0
- package/dist/commands/computer-use/enable.d.ts +6 -0
- package/dist/commands/computer-use/enable.js +9 -0
- package/dist/commands/computer-use/index.d.ts +6 -0
- package/dist/commands/computer-use/index.js +9 -0
- package/dist/commands/computer-use/install.d.ts +6 -0
- package/dist/commands/computer-use/install.js +9 -0
- package/dist/commands/computer-use/recover.d.ts +6 -0
- package/dist/commands/computer-use/recover.js +9 -0
- package/dist/commands/computer-use/status.d.ts +6 -0
- package/dist/commands/computer-use/status.js +9 -0
- package/dist/commands/computer-use/stop.d.ts +6 -0
- package/dist/commands/computer-use/stop.js +9 -0
- package/dist/commands/daemon/login.js +1 -1
- package/dist/commands/followups/plans/cancel.js +10 -3
- package/dist/commands/followups/plans/capacity.d.ts +9 -0
- package/dist/commands/followups/plans/capacity.js +42 -0
- package/dist/commands/followups/plans/create.js +3 -0
- package/dist/commands/followups/plans/revise.js +13 -6
- package/dist/commands/followups/remind.js +13 -5
- package/dist/commands/followups/watch.js +2 -2
- package/dist/lib/agentic-stream.d.ts +5 -1
- package/dist/lib/agentic-stream.js +25 -9
- package/dist/lib/computer-use.d.ts +9 -0
- package/dist/lib/computer-use.js +41 -0
- package/dist/lib/lookbackPlans.d.ts +20 -6
- package/dist/lib/lookbackPlans.js +19 -5
- package/dist/lib/update-check.d.ts +11 -10
- package/dist/lib/update-check.js +41 -23
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerUse.d.ts +228 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerUse.js +375 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.d.ts +4 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.js +6 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.js +40 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/desktopWire.d.ts +140 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/desktopWire.js +46 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +8 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerUse.d.ts +228 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerUse.js +358 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.d.ts +4 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.js +5 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.js +40 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/desktopWire.d.ts +140 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/desktopWire.js +42 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/package.json +21 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +23687 -23456
- package/oclif.manifest.json +306 -26
- package/package.json +2 -2
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computer Use v1 is a host-to-host protocol, never a model tool schema.
|
|
3
|
+
* Models see exactly the runtime's js/js_reset surface. In particular, script
|
|
4
|
+
* contents cannot prove that a call is read-only or supply execution identity.
|
|
5
|
+
* Kept dependency-free so daemon, API, browser and native clients agree.
|
|
6
|
+
*/
|
|
7
|
+
export declare const COMPUTER_USE_TOOL: "ComputerUse";
|
|
8
|
+
export declare const COMPUTER_USE_PROVIDER: "lcu";
|
|
9
|
+
export declare const COMPUTER_USE_PROTOCOL: "computer_use_mcp_v1";
|
|
10
|
+
export declare const COMPUTER_USE_ROTATE_CREDENTIAL_EVENT: "daemon:computer-use:rotate-credential";
|
|
11
|
+
/** Owner-approved hosted credential upgrade; no bearer secret travels in this request. */
|
|
12
|
+
export interface ComputerUseRotateCredentialRequest {
|
|
13
|
+
requestId: string;
|
|
14
|
+
ownerUserId: string;
|
|
15
|
+
machineUuid: string;
|
|
16
|
+
leaseId: string;
|
|
17
|
+
generation: number;
|
|
18
|
+
}
|
|
19
|
+
export declare const COMPUTER_USE_EXECUTION_CAPABILITY: "computer_use";
|
|
20
|
+
export declare const COMPUTER_USE_CLOUD_CONSENT: "computer_use_cloud_agents_v1";
|
|
21
|
+
export declare const COMPUTER_USE_PUBLIC_TOOLS: readonly ["js", "js_reset"];
|
|
22
|
+
export type ComputerUsePublicTool = (typeof COMPUTER_USE_PUBLIC_TOOLS)[number];
|
|
23
|
+
export declare const COMPUTER_USE_OPERATIONS: readonly ["describe", "call", "end_turn", "close", "status", "control_stop"];
|
|
24
|
+
export type ComputerUseOperation = (typeof COMPUTER_USE_OPERATIONS)[number];
|
|
25
|
+
export type ComputerUseSurfaceMode = 'computer' | 'browser' | 'all';
|
|
26
|
+
export type ComputerUseEndReason = 'Stop' | 'Interrupt';
|
|
27
|
+
/** Identity is derived from authenticated execution, never tool arguments. */
|
|
28
|
+
export interface ComputerUseHostContext {
|
|
29
|
+
principalId: string;
|
|
30
|
+
machineId: string;
|
|
31
|
+
sessionId: string;
|
|
32
|
+
turnId: string;
|
|
33
|
+
generation: number;
|
|
34
|
+
toolCallId?: string;
|
|
35
|
+
agentId?: string;
|
|
36
|
+
engine?: string;
|
|
37
|
+
conversationId?: string;
|
|
38
|
+
contextKey?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface ComputerUseBudgets {
|
|
41
|
+
activeExecutionMs: number;
|
|
42
|
+
humanResponseMs: number;
|
|
43
|
+
totalLifetimeMs: number;
|
|
44
|
+
cleanupGraceMs: number;
|
|
45
|
+
}
|
|
46
|
+
export declare const COMPUTER_USE_DEFAULT_BUDGETS: Readonly<ComputerUseBudgets>;
|
|
47
|
+
/** Negotiated ceilings; exceeding a limit is an error, never silent clipping. */
|
|
48
|
+
export declare const COMPUTER_USE_LIMITS: Readonly<{
|
|
49
|
+
maxEnvelopeBytes: number;
|
|
50
|
+
maxInstructionsBytes: number;
|
|
51
|
+
maxSchemaBytes: number;
|
|
52
|
+
maxContentBlocks: 512;
|
|
53
|
+
maxIdentityChars: 512;
|
|
54
|
+
maxActiveExecutionMs: 900000;
|
|
55
|
+
maxHumanResponseMs: 900000;
|
|
56
|
+
maxTotalLifetimeMs: 1800000;
|
|
57
|
+
maxCleanupGraceMs: 60000;
|
|
58
|
+
}>;
|
|
59
|
+
/** Preserve upstream fields and schemas, including annotations and extensions. */
|
|
60
|
+
export interface ComputerUseToolDescriptor {
|
|
61
|
+
name: ComputerUsePublicTool;
|
|
62
|
+
description?: string;
|
|
63
|
+
inputSchema: Record<string, unknown>;
|
|
64
|
+
[key: string]: unknown;
|
|
65
|
+
}
|
|
66
|
+
export interface ComputerUseMcpContent {
|
|
67
|
+
type: string;
|
|
68
|
+
[key: string]: unknown;
|
|
69
|
+
}
|
|
70
|
+
export interface ComputerUseMcpResult {
|
|
71
|
+
content: ComputerUseMcpContent[];
|
|
72
|
+
isError?: boolean;
|
|
73
|
+
structuredContent?: Record<string, unknown>;
|
|
74
|
+
[key: string]: unknown;
|
|
75
|
+
}
|
|
76
|
+
export interface ComputerUseVersions {
|
|
77
|
+
lcu: string;
|
|
78
|
+
adapter?: string;
|
|
79
|
+
app?: string;
|
|
80
|
+
runtime?: string;
|
|
81
|
+
[key: string]: string | undefined;
|
|
82
|
+
}
|
|
83
|
+
export interface ComputerUseRuntimePolicy {
|
|
84
|
+
replPersistence: 'turn';
|
|
85
|
+
audioCleanup: 'retire-runtime';
|
|
86
|
+
}
|
|
87
|
+
export interface ComputerUseSurface {
|
|
88
|
+
protocol: typeof COMPUTER_USE_PROTOCOL;
|
|
89
|
+
provider: typeof COMPUTER_USE_PROVIDER;
|
|
90
|
+
instructions: string;
|
|
91
|
+
tools: ComputerUseToolDescriptor[];
|
|
92
|
+
versions: ComputerUseVersions;
|
|
93
|
+
/** Digest of the actual instructions and full descriptors, not a version label. */
|
|
94
|
+
digest: string;
|
|
95
|
+
surfaceMode: ComputerUseSurfaceMode;
|
|
96
|
+
/** Host-observed lifecycle constraints, separate from original runtime instructions. */
|
|
97
|
+
runtimePolicy?: ComputerUseRuntimePolicy;
|
|
98
|
+
}
|
|
99
|
+
/** Preserve original documentation while explaining the host's narrower lifecycle. */
|
|
100
|
+
export declare function computerUseModelInstructions(surface: ComputerUseSurface): string;
|
|
101
|
+
export declare const COMPUTER_USE_RUNTIME_STATES: readonly ["disabled", "starting", "ready", "executing", "awaiting_approval", "ending_turn", "unavailable", "closed"];
|
|
102
|
+
export type ComputerUseRuntimeState = (typeof COMPUTER_USE_RUNTIME_STATES)[number];
|
|
103
|
+
export interface ComputerUseReadiness {
|
|
104
|
+
provider: typeof COMPUTER_USE_PROVIDER;
|
|
105
|
+
protocol: typeof COMPUTER_USE_PROTOCOL;
|
|
106
|
+
state: ComputerUseRuntimeState;
|
|
107
|
+
available: boolean;
|
|
108
|
+
enabled: boolean;
|
|
109
|
+
cloudAgentsAllowed: boolean;
|
|
110
|
+
reason?: string;
|
|
111
|
+
versions?: ComputerUseVersions;
|
|
112
|
+
surfaceDigest?: string;
|
|
113
|
+
/** Capability readiness is independent of whether a person granted consent. */
|
|
114
|
+
browserReady?: boolean;
|
|
115
|
+
audioReady?: boolean;
|
|
116
|
+
}
|
|
117
|
+
export interface ComputerUseStatus extends ComputerUseReadiness {
|
|
118
|
+
controller?: Pick<ComputerUseHostContext, 'sessionId' | 'turnId' | 'generation' | 'agentId' | 'conversationId'>;
|
|
119
|
+
pendingApprovalId?: string;
|
|
120
|
+
cleanupConfirmed?: boolean;
|
|
121
|
+
}
|
|
122
|
+
export type ComputerUseInput = {
|
|
123
|
+
operation: 'describe';
|
|
124
|
+
surfaceMode?: ComputerUseSurfaceMode;
|
|
125
|
+
} | {
|
|
126
|
+
operation: 'call';
|
|
127
|
+
tool: ComputerUsePublicTool;
|
|
128
|
+
arguments: Record<string, unknown>;
|
|
129
|
+
surfaceDigest?: string;
|
|
130
|
+
budgets?: Partial<ComputerUseBudgets>;
|
|
131
|
+
} | {
|
|
132
|
+
operation: 'end_turn';
|
|
133
|
+
reason: ComputerUseEndReason;
|
|
134
|
+
} | {
|
|
135
|
+
operation: 'close';
|
|
136
|
+
reason?: string;
|
|
137
|
+
} | {
|
|
138
|
+
operation: 'status';
|
|
139
|
+
} | {
|
|
140
|
+
operation: 'control_stop';
|
|
141
|
+
reason?: string;
|
|
142
|
+
};
|
|
143
|
+
export type ComputerUseRequest = ComputerUseInput & {
|
|
144
|
+
protocol: typeof COMPUTER_USE_PROTOCOL;
|
|
145
|
+
provider: typeof COMPUTER_USE_PROVIDER;
|
|
146
|
+
context: ComputerUseHostContext;
|
|
147
|
+
};
|
|
148
|
+
export interface ComputerUseCleanupResult {
|
|
149
|
+
/** True only after the runtime confirms execution can no longer produce input. */
|
|
150
|
+
cleanupConfirmed: boolean;
|
|
151
|
+
closed: boolean;
|
|
152
|
+
generation: number;
|
|
153
|
+
}
|
|
154
|
+
export type ComputerUseResponse = {
|
|
155
|
+
operation: 'describe';
|
|
156
|
+
surface: ComputerUseSurface;
|
|
157
|
+
} | {
|
|
158
|
+
operation: 'call';
|
|
159
|
+
mcpResult: ComputerUseMcpResult;
|
|
160
|
+
} | {
|
|
161
|
+
operation: 'status';
|
|
162
|
+
status: ComputerUseStatus;
|
|
163
|
+
} | {
|
|
164
|
+
operation: 'end_turn' | 'close' | 'control_stop';
|
|
165
|
+
cleanup: ComputerUseCleanupResult;
|
|
166
|
+
};
|
|
167
|
+
export declare const COMPUTER_USE_ELICITATION_CHOICES: readonly ["once", "session", "always", "decline"];
|
|
168
|
+
export type ComputerUseElicitationChoice = (typeof COMPUTER_USE_ELICITATION_CHOICES)[number];
|
|
169
|
+
export interface ComputerUseElicitationOption {
|
|
170
|
+
value: ComputerUseElicitationChoice;
|
|
171
|
+
label: string;
|
|
172
|
+
description?: string;
|
|
173
|
+
}
|
|
174
|
+
/** This is a dedicated permission request, not AskUserQuestion or sticky tool approval. */
|
|
175
|
+
export interface ComputerUseElicitationRequest {
|
|
176
|
+
kind: 'computer_use_runtime';
|
|
177
|
+
requestId: string;
|
|
178
|
+
context: ComputerUseHostContext & {
|
|
179
|
+
toolCallId: string;
|
|
180
|
+
};
|
|
181
|
+
message: string;
|
|
182
|
+
resource?: Record<string, unknown>;
|
|
183
|
+
options: ComputerUseElicitationOption[];
|
|
184
|
+
expiresAt: number;
|
|
185
|
+
}
|
|
186
|
+
export interface ComputerUseElicitationResponse {
|
|
187
|
+
requestId: string;
|
|
188
|
+
context: ComputerUseHostContext & {
|
|
189
|
+
toolCallId: string;
|
|
190
|
+
};
|
|
191
|
+
choice: ComputerUseElicitationChoice;
|
|
192
|
+
}
|
|
193
|
+
export declare class ComputerUseContractError extends Error {
|
|
194
|
+
readonly code: string;
|
|
195
|
+
constructor(code: string, message: string);
|
|
196
|
+
}
|
|
197
|
+
/** Validate the hosted rotation envelope before changing runtime admission. */
|
|
198
|
+
export declare function assertComputerUseRotateCredentialRequest(value: unknown): asserts value is ComputerUseRotateCredentialRequest;
|
|
199
|
+
export declare function assertComputerUseHostContext(value: unknown): asserts value is ComputerUseHostContext;
|
|
200
|
+
export declare function computerUseBudgets(value?: unknown): ComputerUseBudgets;
|
|
201
|
+
export declare function assertComputerUseInput(value: unknown): asserts value is ComputerUseInput;
|
|
202
|
+
export declare function assertComputerUseRequest(value: unknown): asserts value is ComputerUseRequest;
|
|
203
|
+
export declare function assertComputerUseSurface(value: unknown): asserts value is ComputerUseSurface;
|
|
204
|
+
/** Validate the envelope without rewriting blocks or discarding upstream extensions. */
|
|
205
|
+
export declare function assertComputerUseMcpResult(value: unknown): asserts value is ComputerUseMcpResult;
|
|
206
|
+
/** Compare full execution identity; a matching conversation alone never grants access. */
|
|
207
|
+
export declare function sameComputerUseContext(left: ComputerUseHostContext, right: ComputerUseHostContext): boolean;
|
|
208
|
+
export declare function assertComputerUseElicitationRequest(value: unknown): asserts value is ComputerUseElicitationRequest;
|
|
209
|
+
export declare function assertComputerUseElicitationResponse(value: unknown): asserts value is ComputerUseElicitationResponse;
|
|
210
|
+
/** A human answer can only satisfy this exact pending request and offered scope.
|
|
211
|
+
* This matcher is not authentication: the caller must verify the human responder.
|
|
212
|
+
*/
|
|
213
|
+
export declare function acceptsComputerUseElicitationResponse(request: ComputerUseElicitationRequest, response: ComputerUseElicitationResponse, now?: number): boolean;
|
|
214
|
+
export type ComputerUseModelProjectionOptions = {
|
|
215
|
+
audio: 'inline';
|
|
216
|
+
} | {
|
|
217
|
+
audio: 'artifact-reference';
|
|
218
|
+
principalId: string;
|
|
219
|
+
sessionId: string;
|
|
220
|
+
consumer?: string;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Consumer capability projection, never a rewrite of the canonical daemon
|
|
224
|
+
* result. Some model hosts accept MCP AudioContent but silently omit its bytes.
|
|
225
|
+
* Those hosts receive explicit references to already-persisted owned audio.
|
|
226
|
+
* This function never uploads, transcribes, invents a path or grants access.
|
|
227
|
+
*/
|
|
228
|
+
export declare function projectComputerUseResultForModel(result: ComputerUseMcpResult, options: ComputerUseModelProjectionOptions): ComputerUseMcpResult;
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComputerUseContractError = exports.COMPUTER_USE_ELICITATION_CHOICES = exports.COMPUTER_USE_RUNTIME_STATES = exports.COMPUTER_USE_LIMITS = exports.COMPUTER_USE_DEFAULT_BUDGETS = exports.COMPUTER_USE_OPERATIONS = exports.COMPUTER_USE_PUBLIC_TOOLS = exports.COMPUTER_USE_CLOUD_CONSENT = exports.COMPUTER_USE_EXECUTION_CAPABILITY = exports.COMPUTER_USE_ROTATE_CREDENTIAL_EVENT = exports.COMPUTER_USE_PROTOCOL = exports.COMPUTER_USE_PROVIDER = exports.COMPUTER_USE_TOOL = void 0;
|
|
4
|
+
exports.computerUseModelInstructions = computerUseModelInstructions;
|
|
5
|
+
exports.assertComputerUseRotateCredentialRequest = assertComputerUseRotateCredentialRequest;
|
|
6
|
+
exports.assertComputerUseHostContext = assertComputerUseHostContext;
|
|
7
|
+
exports.computerUseBudgets = computerUseBudgets;
|
|
8
|
+
exports.assertComputerUseInput = assertComputerUseInput;
|
|
9
|
+
exports.assertComputerUseRequest = assertComputerUseRequest;
|
|
10
|
+
exports.assertComputerUseSurface = assertComputerUseSurface;
|
|
11
|
+
exports.assertComputerUseMcpResult = assertComputerUseMcpResult;
|
|
12
|
+
exports.sameComputerUseContext = sameComputerUseContext;
|
|
13
|
+
exports.assertComputerUseElicitationRequest = assertComputerUseElicitationRequest;
|
|
14
|
+
exports.assertComputerUseElicitationResponse = assertComputerUseElicitationResponse;
|
|
15
|
+
exports.acceptsComputerUseElicitationResponse = acceptsComputerUseElicitationResponse;
|
|
16
|
+
exports.projectComputerUseResultForModel = projectComputerUseResultForModel;
|
|
17
|
+
/**
|
|
18
|
+
* Computer Use v1 is a host-to-host protocol, never a model tool schema.
|
|
19
|
+
* Models see exactly the runtime's js/js_reset surface. In particular, script
|
|
20
|
+
* contents cannot prove that a call is read-only or supply execution identity.
|
|
21
|
+
* Kept dependency-free so daemon, API, browser and native clients agree.
|
|
22
|
+
*/
|
|
23
|
+
exports.COMPUTER_USE_TOOL = 'ComputerUse';
|
|
24
|
+
exports.COMPUTER_USE_PROVIDER = 'lcu';
|
|
25
|
+
exports.COMPUTER_USE_PROTOCOL = 'computer_use_mcp_v1';
|
|
26
|
+
exports.COMPUTER_USE_ROTATE_CREDENTIAL_EVENT = 'daemon:computer-use:rotate-credential';
|
|
27
|
+
exports.COMPUTER_USE_EXECUTION_CAPABILITY = 'computer_use';
|
|
28
|
+
exports.COMPUTER_USE_CLOUD_CONSENT = 'computer_use_cloud_agents_v1';
|
|
29
|
+
exports.COMPUTER_USE_PUBLIC_TOOLS = ['js', 'js_reset'];
|
|
30
|
+
exports.COMPUTER_USE_OPERATIONS = ['describe', 'call', 'end_turn', 'close', 'status', 'control_stop'];
|
|
31
|
+
exports.COMPUTER_USE_DEFAULT_BUDGETS = Object.freeze({
|
|
32
|
+
activeExecutionMs: 120_000,
|
|
33
|
+
humanResponseMs: 300_000,
|
|
34
|
+
totalLifetimeMs: 900_000,
|
|
35
|
+
cleanupGraceMs: 10_000,
|
|
36
|
+
});
|
|
37
|
+
/** Negotiated ceilings; exceeding a limit is an error, never silent clipping. */
|
|
38
|
+
exports.COMPUTER_USE_LIMITS = Object.freeze({
|
|
39
|
+
maxEnvelopeBytes: 32 * 1024 * 1024,
|
|
40
|
+
maxInstructionsBytes: 1024 * 1024,
|
|
41
|
+
maxSchemaBytes: 1024 * 1024,
|
|
42
|
+
maxContentBlocks: 512,
|
|
43
|
+
maxIdentityChars: 512,
|
|
44
|
+
maxActiveExecutionMs: 900_000,
|
|
45
|
+
maxHumanResponseMs: 900_000,
|
|
46
|
+
maxTotalLifetimeMs: 1_800_000,
|
|
47
|
+
maxCleanupGraceMs: 60_000,
|
|
48
|
+
});
|
|
49
|
+
/** Preserve original documentation while explaining the host's narrower lifecycle. */
|
|
50
|
+
function computerUseModelInstructions(surface) {
|
|
51
|
+
assertComputerUseSurface(surface);
|
|
52
|
+
if (!surface.runtimePolicy)
|
|
53
|
+
return surface.instructions;
|
|
54
|
+
return surface.instructions + '\n\nOverSky host policy\n' +
|
|
55
|
+
'Audio cleanup retires the complete runtime after js_reset and at the end of each host turn. ' +
|
|
56
|
+
'JavaScript variables and application handles persist only within the current turn. ' +
|
|
57
|
+
'Initialize fresh handles in the next turn; do not reuse handles from an earlier runtime.';
|
|
58
|
+
}
|
|
59
|
+
exports.COMPUTER_USE_RUNTIME_STATES = [
|
|
60
|
+
'disabled', 'starting', 'ready', 'executing', 'awaiting_approval',
|
|
61
|
+
'ending_turn', 'unavailable', 'closed',
|
|
62
|
+
];
|
|
63
|
+
exports.COMPUTER_USE_ELICITATION_CHOICES = ['once', 'session', 'always', 'decline'];
|
|
64
|
+
class ComputerUseContractError extends Error {
|
|
65
|
+
code;
|
|
66
|
+
constructor(code, message) {
|
|
67
|
+
super(message);
|
|
68
|
+
this.code = code;
|
|
69
|
+
this.name = 'ComputerUseContractError';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.ComputerUseContractError = ComputerUseContractError;
|
|
73
|
+
function fail(message) {
|
|
74
|
+
throw new ComputerUseContractError('invalid_computer_use_contract', message);
|
|
75
|
+
}
|
|
76
|
+
function record(value) {
|
|
77
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
78
|
+
}
|
|
79
|
+
function exactKeys(value, keys, name) {
|
|
80
|
+
if (Object.keys(value).some((key) => !keys.includes(key)))
|
|
81
|
+
fail(`Unsupported ${name} field`);
|
|
82
|
+
}
|
|
83
|
+
function identifier(value, name) {
|
|
84
|
+
if (typeof value !== 'string' || value.trim().length === 0 || value.length > exports.COMPUTER_USE_LIMITS.maxIdentityChars)
|
|
85
|
+
fail(`Invalid ${name}`);
|
|
86
|
+
}
|
|
87
|
+
/** Reject non-JSON data before transport, including lossy NaN/undefined values. */
|
|
88
|
+
function jsonSize(value) {
|
|
89
|
+
const seen = new Set();
|
|
90
|
+
const visit = (item) => {
|
|
91
|
+
if (item === null || typeof item === 'string' || typeof item === 'boolean')
|
|
92
|
+
return;
|
|
93
|
+
if (typeof item === 'number' && Number.isFinite(item))
|
|
94
|
+
return;
|
|
95
|
+
if (typeof item !== 'object' || !item || seen.has(item))
|
|
96
|
+
fail('Expected acyclic JSON data');
|
|
97
|
+
if (!Array.isArray(item) && Object.getPrototypeOf(item) !== Object.prototype && Object.getPrototypeOf(item) !== null)
|
|
98
|
+
fail('Expected plain JSON object');
|
|
99
|
+
seen.add(item);
|
|
100
|
+
for (const child of Array.isArray(item) ? item : Object.values(item))
|
|
101
|
+
visit(child);
|
|
102
|
+
seen.delete(item);
|
|
103
|
+
};
|
|
104
|
+
visit(value);
|
|
105
|
+
return new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
106
|
+
}
|
|
107
|
+
function boundedJson(value, max, name) {
|
|
108
|
+
if (jsonSize(value) > max)
|
|
109
|
+
fail(`${name} exceeds negotiated byte limit`);
|
|
110
|
+
}
|
|
111
|
+
/** Validate the hosted rotation envelope before changing runtime admission. */
|
|
112
|
+
function assertComputerUseRotateCredentialRequest(value) {
|
|
113
|
+
if (!record(value))
|
|
114
|
+
fail('Expected credential rotation request');
|
|
115
|
+
const ids = ['requestId', 'ownerUserId', 'machineUuid', 'leaseId'];
|
|
116
|
+
exactKeys(value, [...ids, 'generation'], 'credential rotation');
|
|
117
|
+
for (const key of ids) {
|
|
118
|
+
identifier(value[key], key);
|
|
119
|
+
if (value[key].length > 160)
|
|
120
|
+
fail(`Invalid ${key}`);
|
|
121
|
+
}
|
|
122
|
+
if (!Number.isSafeInteger(value.generation) || value.generation < 1)
|
|
123
|
+
fail('Invalid hosted desktop generation');
|
|
124
|
+
}
|
|
125
|
+
function assertComputerUseHostContext(value) {
|
|
126
|
+
if (!record(value))
|
|
127
|
+
fail('Expected host context');
|
|
128
|
+
const required = ['principalId', 'machineId', 'sessionId', 'turnId'];
|
|
129
|
+
const optional = ['toolCallId', 'agentId', 'engine', 'conversationId', 'contextKey'];
|
|
130
|
+
exactKeys(value, [...required, ...optional, 'generation'], 'host context');
|
|
131
|
+
for (const key of required)
|
|
132
|
+
identifier(value[key], key);
|
|
133
|
+
for (const key of optional)
|
|
134
|
+
if (value[key] !== undefined)
|
|
135
|
+
identifier(value[key], key);
|
|
136
|
+
if (!Number.isSafeInteger(value.generation) || value.generation < 0)
|
|
137
|
+
fail('Invalid generation');
|
|
138
|
+
}
|
|
139
|
+
function computerUseBudgets(value = {}) {
|
|
140
|
+
if (!record(value))
|
|
141
|
+
fail('Expected execution budgets');
|
|
142
|
+
const ceilings = {
|
|
143
|
+
activeExecutionMs: exports.COMPUTER_USE_LIMITS.maxActiveExecutionMs,
|
|
144
|
+
humanResponseMs: exports.COMPUTER_USE_LIMITS.maxHumanResponseMs,
|
|
145
|
+
totalLifetimeMs: exports.COMPUTER_USE_LIMITS.maxTotalLifetimeMs,
|
|
146
|
+
cleanupGraceMs: exports.COMPUTER_USE_LIMITS.maxCleanupGraceMs,
|
|
147
|
+
};
|
|
148
|
+
exactKeys(value, Object.keys(ceilings), 'budget');
|
|
149
|
+
const result = { ...exports.COMPUTER_USE_DEFAULT_BUDGETS };
|
|
150
|
+
for (const key of Object.keys(ceilings)) {
|
|
151
|
+
if (value[key] === undefined)
|
|
152
|
+
continue;
|
|
153
|
+
if (!Number.isSafeInteger(value[key]) || value[key] <= 0 || value[key] > ceilings[key])
|
|
154
|
+
fail(`Invalid ${key}`);
|
|
155
|
+
result[key] = value[key];
|
|
156
|
+
}
|
|
157
|
+
if (result.totalLifetimeMs < result.activeExecutionMs || result.totalLifetimeMs < result.cleanupGraceMs)
|
|
158
|
+
fail('Total lifetime is shorter than execution or cleanup budget');
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
function assertComputerUseInput(value) {
|
|
162
|
+
if (!record(value))
|
|
163
|
+
fail('Expected Computer Use operation');
|
|
164
|
+
switch (value.operation) {
|
|
165
|
+
case 'describe':
|
|
166
|
+
exactKeys(value, ['operation', 'surfaceMode'], 'describe');
|
|
167
|
+
if (value.surfaceMode !== undefined && !['computer', 'browser', 'all'].includes(value.surfaceMode))
|
|
168
|
+
fail('Unsupported surface mode');
|
|
169
|
+
break;
|
|
170
|
+
case 'call':
|
|
171
|
+
exactKeys(value, ['operation', 'tool', 'arguments', 'surfaceDigest', 'budgets'], 'call');
|
|
172
|
+
if (!exports.COMPUTER_USE_PUBLIC_TOOLS.includes(value.tool))
|
|
173
|
+
fail('Unsupported public tool');
|
|
174
|
+
if (!record(value.arguments))
|
|
175
|
+
fail('Expected original tool arguments');
|
|
176
|
+
if (value.surfaceDigest !== undefined)
|
|
177
|
+
identifier(value.surfaceDigest, 'surfaceDigest');
|
|
178
|
+
if (value.budgets !== undefined)
|
|
179
|
+
computerUseBudgets(value.budgets);
|
|
180
|
+
break;
|
|
181
|
+
case 'end_turn':
|
|
182
|
+
exactKeys(value, ['operation', 'reason'], 'end_turn');
|
|
183
|
+
if (value.reason !== 'Stop' && value.reason !== 'Interrupt')
|
|
184
|
+
fail('Unsupported end reason');
|
|
185
|
+
break;
|
|
186
|
+
case 'close':
|
|
187
|
+
case 'control_stop':
|
|
188
|
+
exactKeys(value, ['operation', 'reason'], value.operation);
|
|
189
|
+
if (value.reason !== undefined)
|
|
190
|
+
identifier(value.reason, 'reason');
|
|
191
|
+
break;
|
|
192
|
+
case 'status':
|
|
193
|
+
exactKeys(value, ['operation'], 'status');
|
|
194
|
+
break;
|
|
195
|
+
default: fail('Unsupported Computer Use operation');
|
|
196
|
+
}
|
|
197
|
+
boundedJson(value, exports.COMPUTER_USE_LIMITS.maxEnvelopeBytes, 'Request');
|
|
198
|
+
}
|
|
199
|
+
function assertComputerUseRequest(value) {
|
|
200
|
+
if (!record(value) || value.protocol !== exports.COMPUTER_USE_PROTOCOL || value.provider !== exports.COMPUTER_USE_PROVIDER)
|
|
201
|
+
fail('Unsupported Computer Use protocol/provider');
|
|
202
|
+
assertComputerUseHostContext(value.context);
|
|
203
|
+
const { protocol: _protocol, provider: _provider, context, ...input } = value;
|
|
204
|
+
assertComputerUseInput(input);
|
|
205
|
+
if (input.operation === 'call' && !context.toolCallId)
|
|
206
|
+
fail('Calls require exact host toolCallId');
|
|
207
|
+
boundedJson(value, exports.COMPUTER_USE_LIMITS.maxEnvelopeBytes, 'Request');
|
|
208
|
+
}
|
|
209
|
+
function assertComputerUseSurface(value) {
|
|
210
|
+
if (!record(value) || value.protocol !== exports.COMPUTER_USE_PROTOCOL || value.provider !== exports.COMPUTER_USE_PROVIDER)
|
|
211
|
+
fail('Unsupported Computer Use surface');
|
|
212
|
+
if (typeof value.instructions !== 'string')
|
|
213
|
+
fail('Expected original runtime instructions');
|
|
214
|
+
if (new TextEncoder().encode(value.instructions).byteLength > exports.COMPUTER_USE_LIMITS.maxInstructionsBytes)
|
|
215
|
+
fail('Instructions exceed negotiated byte limit');
|
|
216
|
+
identifier(value.digest, 'surface digest');
|
|
217
|
+
if (!['computer', 'browser', 'all'].includes(value.surfaceMode))
|
|
218
|
+
fail('Unsupported surface mode');
|
|
219
|
+
if (value.runtimePolicy !== undefined) {
|
|
220
|
+
if (!record(value.runtimePolicy))
|
|
221
|
+
fail('Invalid host runtime policy');
|
|
222
|
+
exactKeys(value.runtimePolicy, ['replPersistence', 'audioCleanup'], 'host runtime policy');
|
|
223
|
+
if (value.runtimePolicy.replPersistence !== 'turn' || value.runtimePolicy.audioCleanup !== 'retire-runtime')
|
|
224
|
+
fail('Unsupported host runtime policy');
|
|
225
|
+
}
|
|
226
|
+
if (!record(value.versions) || typeof value.versions.lcu !== 'string' || !value.versions.lcu)
|
|
227
|
+
fail('Missing LCU version');
|
|
228
|
+
if (Object.values(value.versions).some((v) => typeof v !== 'string'))
|
|
229
|
+
fail('Invalid runtime version');
|
|
230
|
+
if (!Array.isArray(value.tools) || value.tools.length !== 2)
|
|
231
|
+
fail('Expected js and js_reset descriptors');
|
|
232
|
+
const names = new Set();
|
|
233
|
+
for (const tool of value.tools) {
|
|
234
|
+
if (!record(tool) || !exports.COMPUTER_USE_PUBLIC_TOOLS.includes(tool.name) || !record(tool.inputSchema))
|
|
235
|
+
fail('Invalid original tool descriptor');
|
|
236
|
+
if (tool.description !== undefined && typeof tool.description !== 'string')
|
|
237
|
+
fail('Invalid tool description');
|
|
238
|
+
if (names.has(tool.name))
|
|
239
|
+
fail('Duplicate public tool');
|
|
240
|
+
names.add(tool.name);
|
|
241
|
+
boundedJson(tool, exports.COMPUTER_USE_LIMITS.maxSchemaBytes, 'Tool descriptor');
|
|
242
|
+
}
|
|
243
|
+
boundedJson(value, exports.COMPUTER_USE_LIMITS.maxEnvelopeBytes, 'Surface');
|
|
244
|
+
}
|
|
245
|
+
/** Validate the envelope without rewriting blocks or discarding upstream extensions. */
|
|
246
|
+
function assertComputerUseMcpResult(value) {
|
|
247
|
+
if (!record(value) || !Array.isArray(value.content) || value.content.length > exports.COMPUTER_USE_LIMITS.maxContentBlocks)
|
|
248
|
+
fail('Invalid MCP result content');
|
|
249
|
+
if (value.isError !== undefined && typeof value.isError !== 'boolean')
|
|
250
|
+
fail('Invalid MCP isError');
|
|
251
|
+
if (value.structuredContent !== undefined && !record(value.structuredContent))
|
|
252
|
+
fail('Invalid MCP structuredContent');
|
|
253
|
+
for (const block of value.content) {
|
|
254
|
+
if (!record(block) || typeof block.type !== 'string' || !block.type)
|
|
255
|
+
fail('Invalid MCP content block');
|
|
256
|
+
if (block.type === 'text' && typeof block.text !== 'string')
|
|
257
|
+
fail('Invalid MCP text block');
|
|
258
|
+
if (block.type === 'image' && (typeof block.data !== 'string' || typeof block.mimeType !== 'string'))
|
|
259
|
+
fail('Invalid MCP image block');
|
|
260
|
+
}
|
|
261
|
+
boundedJson(value, exports.COMPUTER_USE_LIMITS.maxEnvelopeBytes, 'MCP result');
|
|
262
|
+
}
|
|
263
|
+
/** Compare full execution identity; a matching conversation alone never grants access. */
|
|
264
|
+
function sameComputerUseContext(left, right) {
|
|
265
|
+
return ['principalId', 'machineId', 'sessionId', 'turnId', 'generation', 'agentId', 'engine', 'conversationId', 'contextKey']
|
|
266
|
+
.every((key) => left[key] === right[key]);
|
|
267
|
+
}
|
|
268
|
+
function assertComputerUseElicitationRequest(value) {
|
|
269
|
+
if (!record(value) || value.kind !== 'computer_use_runtime')
|
|
270
|
+
fail('Expected runtime elicitation');
|
|
271
|
+
exactKeys(value, ['kind', 'requestId', 'context', 'message', 'resource', 'options', 'expiresAt'], 'elicitation request');
|
|
272
|
+
identifier(value.requestId, 'requestId');
|
|
273
|
+
assertComputerUseHostContext(value.context);
|
|
274
|
+
identifier(value.context.toolCallId, 'toolCallId');
|
|
275
|
+
if (typeof value.message !== 'string' || !value.message)
|
|
276
|
+
fail('Missing runtime elicitation message');
|
|
277
|
+
if (value.resource !== undefined && !record(value.resource))
|
|
278
|
+
fail('Invalid runtime resource');
|
|
279
|
+
if (!Number.isSafeInteger(value.expiresAt) || value.expiresAt <= 0)
|
|
280
|
+
fail('Invalid runtime elicitation expiry');
|
|
281
|
+
if (!Array.isArray(value.options) || value.options.length === 0 || value.options.length > exports.COMPUTER_USE_ELICITATION_CHOICES.length)
|
|
282
|
+
fail('Invalid runtime choices');
|
|
283
|
+
const choices = new Set();
|
|
284
|
+
for (const option of value.options) {
|
|
285
|
+
if (!record(option))
|
|
286
|
+
fail('Invalid runtime option');
|
|
287
|
+
exactKeys(option, ['value', 'label', 'description'], 'elicitation option');
|
|
288
|
+
if (!exports.COMPUTER_USE_ELICITATION_CHOICES.includes(option.value) || choices.has(option.value))
|
|
289
|
+
fail('Unsupported or duplicate runtime choice');
|
|
290
|
+
if (typeof option.label !== 'string' || !option.label || (option.description !== undefined && typeof option.description !== 'string'))
|
|
291
|
+
fail('Invalid runtime choice label');
|
|
292
|
+
choices.add(option.value);
|
|
293
|
+
}
|
|
294
|
+
boundedJson(value, exports.COMPUTER_USE_LIMITS.maxEnvelopeBytes, 'Runtime elicitation');
|
|
295
|
+
}
|
|
296
|
+
function assertComputerUseElicitationResponse(value) {
|
|
297
|
+
if (!record(value))
|
|
298
|
+
fail('Expected runtime elicitation response');
|
|
299
|
+
exactKeys(value, ['requestId', 'context', 'choice'], 'elicitation response');
|
|
300
|
+
identifier(value.requestId, 'requestId');
|
|
301
|
+
assertComputerUseHostContext(value.context);
|
|
302
|
+
identifier(value.context.toolCallId, 'toolCallId');
|
|
303
|
+
if (!exports.COMPUTER_USE_ELICITATION_CHOICES.includes(value.choice))
|
|
304
|
+
fail('Unsupported runtime choice');
|
|
305
|
+
boundedJson(value, exports.COMPUTER_USE_LIMITS.maxEnvelopeBytes, 'Runtime elicitation response');
|
|
306
|
+
}
|
|
307
|
+
/** A human answer can only satisfy this exact pending request and offered scope.
|
|
308
|
+
* This matcher is not authentication: the caller must verify the human responder.
|
|
309
|
+
*/
|
|
310
|
+
function acceptsComputerUseElicitationResponse(request, response, now = Date.now()) {
|
|
311
|
+
try {
|
|
312
|
+
assertComputerUseElicitationRequest(request);
|
|
313
|
+
assertComputerUseElicitationResponse(response);
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
return request.kind === 'computer_use_runtime' && request.requestId === response.requestId &&
|
|
319
|
+
Number.isFinite(request.expiresAt) && now < request.expiresAt &&
|
|
320
|
+
sameComputerUseContext(request.context, response.context) &&
|
|
321
|
+
typeof request.context.toolCallId === 'string' && request.context.toolCallId === response.context.toolCallId &&
|
|
322
|
+
exports.COMPUTER_USE_ELICITATION_CHOICES.includes(response.choice) &&
|
|
323
|
+
request.options.some((option) => option.value === response.choice);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Consumer capability projection, never a rewrite of the canonical daemon
|
|
327
|
+
* result. Some model hosts accept MCP AudioContent but silently omit its bytes.
|
|
328
|
+
* Those hosts receive explicit references to already-persisted owned audio.
|
|
329
|
+
* This function never uploads, transcribes, invents a path or grants access.
|
|
330
|
+
*/
|
|
331
|
+
function projectComputerUseResultForModel(result, options) {
|
|
332
|
+
assertComputerUseMcpResult(result);
|
|
333
|
+
if (!options || !['inline', 'artifact-reference'].includes(options.audio))
|
|
334
|
+
fail('Unsupported Computer Use model audio capability');
|
|
335
|
+
const audioCount = result.content.filter((block) => block.type === 'audio').length;
|
|
336
|
+
if (options.audio === 'inline' || audioCount === 0)
|
|
337
|
+
return result;
|
|
338
|
+
identifier(options.principalId, 'audio artifact owner');
|
|
339
|
+
identifier(options.sessionId, 'audio artifact session');
|
|
340
|
+
if (options.consumer !== undefined)
|
|
341
|
+
identifier(options.consumer, 'audio consumer');
|
|
342
|
+
const metadata = record(result._meta) ? result._meta : {};
|
|
343
|
+
const candidates = metadata['skrr.ai/computer-use-artifacts'];
|
|
344
|
+
const references = Array.isArray(candidates)
|
|
345
|
+
? candidates.filter((item) => record(item) && typeof item.mimeType === 'string' && item.mimeType.startsWith('audio/'))
|
|
346
|
+
: [];
|
|
347
|
+
if (references.length < audioCount || references.some((item) => !record(item) || typeof item.fileId !== 'string' || !/^[A-Za-z0-9_-]{1,512}$/.test(item.fileId) ||
|
|
348
|
+
item.reference !== `file:${item.fileId}` || item.ownerUserId !== options.principalId ||
|
|
349
|
+
item.sessionId !== options.sessionId || !Number.isSafeInteger(item.bytes) || item.bytes <= 0 ||
|
|
350
|
+
typeof item.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(item.sha256) ||
|
|
351
|
+
typeof item.mimeType !== 'string' || item.mimeType.length > 256 || !/^audio\/[A-Za-z0-9.+-]+(?:;[ -~]*)?$/.test(item.mimeType))) {
|
|
352
|
+
throw new ComputerUseContractError('computer_use_audio_artifact_required', 'This model cannot receive inline audio. Every audio block requires an existing owned file artifact for this exact session.');
|
|
353
|
+
}
|
|
354
|
+
const notice = [
|
|
355
|
+
'Audio is available as owned file artifacts. This model receives references instead of inline audio and has not listened to the recording.',
|
|
356
|
+
...references.map((item) => `${item.reference} (${item.mimeType}; ${item.bytes} bytes; sha256 ${item.sha256})`),
|
|
357
|
+
].join('\n');
|
|
358
|
+
let inserted = false;
|
|
359
|
+
const content = result.content.flatMap((block) => {
|
|
360
|
+
if (block.type !== 'audio')
|
|
361
|
+
return [block];
|
|
362
|
+
if (inserted)
|
|
363
|
+
return [];
|
|
364
|
+
inserted = true;
|
|
365
|
+
return [{ type: 'text', text: notice }];
|
|
366
|
+
});
|
|
367
|
+
const projected = { ...result, content, _meta: { ...metadata,
|
|
368
|
+
'skrr.ai/computer-use-model-projection': {
|
|
369
|
+
audio: 'artifact-reference', audioBlocks: audioCount,
|
|
370
|
+
...(options.consumer ? { consumer: options.consumer } : {}),
|
|
371
|
+
},
|
|
372
|
+
} };
|
|
373
|
+
assertComputerUseMcpResult(projected);
|
|
374
|
+
return projected;
|
|
375
|
+
}
|
|
@@ -52,16 +52,19 @@ export declare const SCOPES: Readonly<{
|
|
|
52
52
|
readonly TOOLS_FS_WRITE: "daemon:tools:fs:write";
|
|
53
53
|
readonly BROWSER_CDP: "daemon:browser:cdp";
|
|
54
54
|
readonly NATIVE_UI_CONTROL: "daemon:native-ui:control";
|
|
55
|
+
readonly COMPUTER_USE_CONTROL: "daemon:computer-use:control";
|
|
55
56
|
readonly SESSION_REPLAY: "daemon:session:replay";
|
|
56
57
|
readonly OFFLINE_QUEUE: "daemon:offline-queue";
|
|
57
58
|
}>;
|
|
58
59
|
export type DaemonScope = (typeof SCOPES)[keyof typeof SCOPES];
|
|
59
60
|
/**
|
|
60
|
-
*
|
|
61
|
+
* All daemon scopes in canonical order. Login defaults are a separate opt-in policy. Frozen so consumers can
|
|
61
62
|
* pass it directly to OAuth `scope` parameters without defensive
|
|
62
63
|
* copies.
|
|
63
64
|
*/
|
|
64
65
|
export declare const ALL_DAEMON_SCOPES: readonly DaemonScope[];
|
|
66
|
+
/** Login defaults retain the existing surface; script control is explicit opt-in. */
|
|
67
|
+
export declare const DEFAULT_DAEMON_SCOPES: readonly DaemonScope[];
|
|
65
68
|
/**
|
|
66
69
|
* Set form of `ALL_DAEMON_SCOPES` for O(1) membership checks.
|
|
67
70
|
*/
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* never rename in place.
|
|
31
31
|
*/
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.OAUTH_CLI_SCOPE = exports.VALID_DAEMON_SCOPE_SET = exports.ALL_DAEMON_SCOPES = exports.SCOPES = void 0;
|
|
33
|
+
exports.OAUTH_CLI_SCOPE = exports.VALID_DAEMON_SCOPE_SET = exports.DEFAULT_DAEMON_SCOPES = exports.ALL_DAEMON_SCOPES = exports.SCOPES = void 0;
|
|
34
34
|
exports.isDaemonScope = isDaemonScope;
|
|
35
35
|
/**
|
|
36
36
|
* The canonical daemon scope vocabulary. Seven strings, append-only.
|
|
@@ -56,11 +56,12 @@ exports.SCOPES = Object.freeze({
|
|
|
56
56
|
TOOLS_FS_WRITE: 'daemon:tools:fs:write',
|
|
57
57
|
BROWSER_CDP: 'daemon:browser:cdp',
|
|
58
58
|
NATIVE_UI_CONTROL: 'daemon:native-ui:control',
|
|
59
|
+
COMPUTER_USE_CONTROL: 'daemon:computer-use:control',
|
|
59
60
|
SESSION_REPLAY: 'daemon:session:replay',
|
|
60
61
|
OFFLINE_QUEUE: 'daemon:offline-queue',
|
|
61
62
|
});
|
|
62
63
|
/**
|
|
63
|
-
*
|
|
64
|
+
* All daemon scopes in canonical order. Login defaults are a separate opt-in policy. Frozen so consumers can
|
|
64
65
|
* pass it directly to OAuth `scope` parameters without defensive
|
|
65
66
|
* copies.
|
|
66
67
|
*/
|
|
@@ -70,9 +71,12 @@ exports.ALL_DAEMON_SCOPES = Object.freeze([
|
|
|
70
71
|
exports.SCOPES.TOOLS_FS_WRITE,
|
|
71
72
|
exports.SCOPES.BROWSER_CDP,
|
|
72
73
|
exports.SCOPES.NATIVE_UI_CONTROL,
|
|
74
|
+
exports.SCOPES.COMPUTER_USE_CONTROL,
|
|
73
75
|
exports.SCOPES.SESSION_REPLAY,
|
|
74
76
|
exports.SCOPES.OFFLINE_QUEUE,
|
|
75
77
|
]);
|
|
78
|
+
/** Login defaults retain the existing surface; script control is explicit opt-in. */
|
|
79
|
+
exports.DEFAULT_DAEMON_SCOPES = Object.freeze(exports.ALL_DAEMON_SCOPES.filter((scope) => scope !== exports.SCOPES.COMPUTER_USE_CONTROL));
|
|
76
80
|
/**
|
|
77
81
|
* Set form of `ALL_DAEMON_SCOPES` for O(1) membership checks.
|
|
78
82
|
*/
|