agent-relay 11.1.1 → 11.2.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/README.md +80 -0
- package/dist/cli/commands/agent.d.ts.map +1 -1
- package/dist/cli/commands/agent.js +12 -0
- package/dist/cli/commands/agent.js.map +1 -1
- package/dist/cli/commands/cloud-integration.d.ts +6 -0
- package/dist/cli/commands/cloud-integration.d.ts.map +1 -0
- package/dist/cli/commands/cloud-integration.js +282 -0
- package/dist/cli/commands/cloud-integration.js.map +1 -0
- package/dist/cli/commands/cloud-room.d.ts +11 -0
- package/dist/cli/commands/cloud-room.d.ts.map +1 -0
- package/dist/cli/commands/cloud-room.js +569 -0
- package/dist/cli/commands/cloud-room.js.map +1 -0
- package/dist/cli/commands/cloud.d.ts.map +1 -1
- package/dist/cli/commands/cloud.js +4 -0
- package/dist/cli/commands/cloud.js.map +1 -1
- package/dist/cli/commands/core.d.ts +2 -0
- package/dist/cli/commands/core.d.ts.map +1 -1
- package/dist/cli/commands/core.js +11 -5
- package/dist/cli/commands/core.js.map +1 -1
- package/dist/cli/commands/node.js +4 -0
- package/dist/cli/commands/node.js.map +1 -1
- package/dist/cli/lib/broker-lifecycle.d.ts +3 -2
- package/dist/cli/lib/broker-lifecycle.d.ts.map +1 -1
- package/dist/cli/lib/broker-lifecycle.js +37 -4
- package/dist/cli/lib/broker-lifecycle.js.map +1 -1
- package/dist/cli/lib/sdk-client.d.ts.map +1 -1
- package/dist/cli/lib/sdk-client.js +10 -1
- package/dist/cli/lib/sdk-client.js.map +1 -1
- package/dist/index.cjs +18 -4
- package/package.json +8 -8
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import { constants as fsConstants } from 'node:fs';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { InvalidArgumentError } from 'commander';
|
|
5
|
+
import { defaultApiUrl } from '@agent-relay/cloud';
|
|
6
|
+
import { stripAnsiFast } from '@agent-relay/utils';
|
|
7
|
+
const CLOUD_WORKSPACE_UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
8
|
+
const UNIFIED_WORKSPACE_ID_PATTERN = /^rw_[a-z0-9]{8}$/;
|
|
9
|
+
const ROOM_RESOURCE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
|
|
10
|
+
const DEFAULT_INVITATION_LIFETIME_SECONDS = 7 * 24 * 60 * 60;
|
|
11
|
+
const MIN_INVITATION_LIFETIME_SECONDS = 60;
|
|
12
|
+
const MAX_INVITATION_LIFETIME_SECONDS = 30 * 24 * 60 * 60;
|
|
13
|
+
const MAX_ROOM_SECRET_LENGTH = 2_048;
|
|
14
|
+
const ROOM_INVITATION_TOKEN_PATTERN = /^relay_room_inv_[A-Za-z0-9_-]{43}$/;
|
|
15
|
+
function isObject(value) {
|
|
16
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
17
|
+
}
|
|
18
|
+
function requireObject(value, label) {
|
|
19
|
+
if (!isObject(value)) {
|
|
20
|
+
throw new Error(`Cloud room returned an invalid ${label} response.`);
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
function requireStringField(record, key, label) {
|
|
25
|
+
const value = record[key];
|
|
26
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
27
|
+
throw new Error(`Cloud room returned an invalid ${label} response.`);
|
|
28
|
+
}
|
|
29
|
+
return value.trim();
|
|
30
|
+
}
|
|
31
|
+
function requireNullableStringField(record, key, label) {
|
|
32
|
+
const value = record[key];
|
|
33
|
+
if (value === null)
|
|
34
|
+
return null;
|
|
35
|
+
if (typeof value !== 'string') {
|
|
36
|
+
throw new Error(`Cloud room returned an invalid ${label} response.`);
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function requireIsoDateField(record, key, label) {
|
|
41
|
+
const value = requireStringField(record, key, label);
|
|
42
|
+
if (!Number.isFinite(Date.parse(value))) {
|
|
43
|
+
throw new Error(`Cloud room returned an invalid ${label} response.`);
|
|
44
|
+
}
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
function requireResponseRole(record, label) {
|
|
48
|
+
const role = record.role;
|
|
49
|
+
if (role !== 'participant') {
|
|
50
|
+
throw new Error(`Cloud room returned an invalid ${label} response.`);
|
|
51
|
+
}
|
|
52
|
+
return role;
|
|
53
|
+
}
|
|
54
|
+
function containsForbiddenCredentialField(value) {
|
|
55
|
+
if (Array.isArray(value))
|
|
56
|
+
return value.some(containsForbiddenCredentialField);
|
|
57
|
+
if (!isObject(value))
|
|
58
|
+
return false;
|
|
59
|
+
return Object.entries(value).some(([key, nested]) => /^(?:workspaceKey|relaycastApiKey|relayfileToken|relayfileCredentials|accessToken|refreshToken|authorization|apiKey)$/i.test(key) || containsForbiddenCredentialField(nested));
|
|
60
|
+
}
|
|
61
|
+
function normalizeInvite(value, requireToken) {
|
|
62
|
+
const invite = requireObject(value, 'invitation');
|
|
63
|
+
const normalized = {
|
|
64
|
+
id: requireStringField(invite, 'id', 'invitation'),
|
|
65
|
+
email: requireStringField(invite, 'email', 'invitation'),
|
|
66
|
+
role: requireResponseRole(invite, 'invitation'),
|
|
67
|
+
expiresAt: requireIsoDateField(invite, 'expiresAt', 'invitation'),
|
|
68
|
+
createdAt: requireIsoDateField(invite, 'createdAt', 'invitation'),
|
|
69
|
+
};
|
|
70
|
+
if (requireToken) {
|
|
71
|
+
normalized.token = requireInvitationToken(requireStringField(invite, 'token', 'invitation'));
|
|
72
|
+
}
|
|
73
|
+
return normalized;
|
|
74
|
+
}
|
|
75
|
+
function normalizeInviteCreate(payload) {
|
|
76
|
+
const response = requireObject(payload, 'invitation');
|
|
77
|
+
return {
|
|
78
|
+
invite: normalizeInvite(response.invite, true),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function normalizeInviteList(payload) {
|
|
82
|
+
const response = requireObject(payload, 'invitation list');
|
|
83
|
+
if (!Array.isArray(response.invites)) {
|
|
84
|
+
throw new Error('Cloud room returned an invalid invitation list response.');
|
|
85
|
+
}
|
|
86
|
+
return { invites: response.invites.map((invite) => normalizeInvite(invite, false)) };
|
|
87
|
+
}
|
|
88
|
+
function normalizeMemberList(payload) {
|
|
89
|
+
const response = requireObject(payload, 'member list');
|
|
90
|
+
if (!Array.isArray(response.members)) {
|
|
91
|
+
throw new Error('Cloud room returned an invalid member list response.');
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
members: response.members.map((value) => {
|
|
95
|
+
const member = requireObject(value, 'member list');
|
|
96
|
+
const status = requireStringField(member, 'status', 'member list');
|
|
97
|
+
if (status !== 'active' && status !== 'revoking') {
|
|
98
|
+
throw new Error('Cloud room returned an invalid member list response.');
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
id: requireStringField(member, 'id', 'member list'),
|
|
102
|
+
userId: requireStringField(member, 'userId', 'member list'),
|
|
103
|
+
email: requireNullableStringField(member, 'email', 'member list'),
|
|
104
|
+
name: requireNullableStringField(member, 'name', 'member list'),
|
|
105
|
+
role: requireResponseRole(member, 'member list'),
|
|
106
|
+
status,
|
|
107
|
+
joinedAt: requireIsoDateField(member, 'joinedAt', 'member list'),
|
|
108
|
+
};
|
|
109
|
+
}),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function normalizeMembership(payload) {
|
|
113
|
+
const response = requireObject(payload, 'membership');
|
|
114
|
+
const membership = requireObject(response.membership, 'membership');
|
|
115
|
+
return {
|
|
116
|
+
membership: {
|
|
117
|
+
id: requireStringField(membership, 'id', 'membership'),
|
|
118
|
+
workspaceId: requireStringField(membership, 'workspaceId', 'membership'),
|
|
119
|
+
role: requireResponseRole(membership, 'membership'),
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function normalizeRoomSession(payload) {
|
|
124
|
+
const response = requireObject(payload, 'session');
|
|
125
|
+
const role = requireResponseRole(response, 'session');
|
|
126
|
+
const relaycastBaseUrl = requireRelaycastBaseUrl(requireStringField(response, 'relaycastBaseUrl', 'session'));
|
|
127
|
+
if (typeof response.agentToken !== 'string' ||
|
|
128
|
+
!response.agentToken.trim().startsWith('at_live_') ||
|
|
129
|
+
response.observerToken !== undefined) {
|
|
130
|
+
throw new Error('Cloud room returned an invalid participant session response.');
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
role,
|
|
134
|
+
relaycastBaseUrl,
|
|
135
|
+
agentName: requireStringField(response, 'agentName', 'participant session'),
|
|
136
|
+
agentToken: response.agentToken.trim(),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function parsePositiveInteger(value) {
|
|
140
|
+
if (!/^[1-9][0-9]*$/.test(value)) {
|
|
141
|
+
throw new InvalidArgumentError('Expected a positive whole number.');
|
|
142
|
+
}
|
|
143
|
+
const parsed = Number(value);
|
|
144
|
+
if (!Number.isSafeInteger(parsed) ||
|
|
145
|
+
parsed < MIN_INVITATION_LIFETIME_SECONDS ||
|
|
146
|
+
parsed > MAX_INVITATION_LIFETIME_SECONDS) {
|
|
147
|
+
throw new InvalidArgumentError(`Expected between ${MIN_INVITATION_LIFETIME_SECONDS} and ${MAX_INVITATION_LIFETIME_SECONDS} seconds.`);
|
|
148
|
+
}
|
|
149
|
+
return parsed;
|
|
150
|
+
}
|
|
151
|
+
function requireWorkspaceId(value) {
|
|
152
|
+
const workspaceId = value.trim();
|
|
153
|
+
if (!CLOUD_WORKSPACE_UUID_PATTERN.test(workspaceId) && !UNIFIED_WORKSPACE_ID_PATTERN.test(workspaceId)) {
|
|
154
|
+
throw new Error('Unsupported Cloud workspace identifier. Use a Cloud workspace UUID or unified rw_ workspace ID.');
|
|
155
|
+
}
|
|
156
|
+
return workspaceId;
|
|
157
|
+
}
|
|
158
|
+
function requireResourceId(value, label) {
|
|
159
|
+
const resourceId = value.trim();
|
|
160
|
+
// Cloud owns these opaque identifiers. Only reject values that cannot be
|
|
161
|
+
// safely carried in a URL path or terminal; encodeURIComponent handles the
|
|
162
|
+
// remaining printable characters without coupling the CLI to an ID format.
|
|
163
|
+
if (!resourceId ||
|
|
164
|
+
resourceId.length > 512 ||
|
|
165
|
+
// eslint-disable-next-line no-control-regex
|
|
166
|
+
/[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/.test(resourceId)) {
|
|
167
|
+
throw new Error(`Invalid ${label}.`);
|
|
168
|
+
}
|
|
169
|
+
return resourceId;
|
|
170
|
+
}
|
|
171
|
+
function requireEmail(value) {
|
|
172
|
+
const email = value.trim().toLowerCase();
|
|
173
|
+
if (email.length > 320 || /[\r\n]/.test(email) || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
174
|
+
throw new Error('A valid email address is required.');
|
|
175
|
+
}
|
|
176
|
+
return email;
|
|
177
|
+
}
|
|
178
|
+
function requireDeviceId(value) {
|
|
179
|
+
const deviceId = value.trim();
|
|
180
|
+
if (!ROOM_RESOURCE_ID_PATTERN.test(deviceId)) {
|
|
181
|
+
throw new Error('Invalid device ID. Use 1-128 letters, numbers, underscores, or hyphens.');
|
|
182
|
+
}
|
|
183
|
+
return deviceId;
|
|
184
|
+
}
|
|
185
|
+
/** Keep Cloud/user-provided text from controlling or escaping the terminal. */
|
|
186
|
+
function sanitizeTerminalCell(value) {
|
|
187
|
+
// eslint-disable-next-line no-control-regex
|
|
188
|
+
return stripAnsiFast(value).replace(/[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/g, '�');
|
|
189
|
+
}
|
|
190
|
+
async function defaultReadStdin() {
|
|
191
|
+
let input = '';
|
|
192
|
+
for await (const chunk of process.stdin) {
|
|
193
|
+
input += String(chunk);
|
|
194
|
+
if (input.length > MAX_ROOM_SECRET_LENGTH + 1) {
|
|
195
|
+
throw new Error('Invalid room invitation token.');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return input;
|
|
199
|
+
}
|
|
200
|
+
async function defaultReadSecretFile(filePath) {
|
|
201
|
+
const noFollow = process.platform === 'win32' ? 0 : fsConstants.O_NOFOLLOW;
|
|
202
|
+
const handle = await fs.open(filePath, fsConstants.O_RDONLY | noFollow);
|
|
203
|
+
try {
|
|
204
|
+
const metadata = await handle.stat();
|
|
205
|
+
if (!metadata.isFile()) {
|
|
206
|
+
throw new Error('Room invitation token file must be a regular file.');
|
|
207
|
+
}
|
|
208
|
+
if (process.platform !== 'win32' && (metadata.mode & 0o077) !== 0) {
|
|
209
|
+
throw new Error('Room invitation token file must have owner-only permissions (0600).');
|
|
210
|
+
}
|
|
211
|
+
if (metadata.size > MAX_ROOM_SECRET_LENGTH + 1) {
|
|
212
|
+
throw new Error('Invalid room invitation token.');
|
|
213
|
+
}
|
|
214
|
+
return handle.readFile('utf8');
|
|
215
|
+
}
|
|
216
|
+
finally {
|
|
217
|
+
await handle.close();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async function defaultWriteSecretFile(filePath, value) {
|
|
221
|
+
const noFollow = process.platform === 'win32' ? 0 : fsConstants.O_NOFOLLOW;
|
|
222
|
+
const handle = await fs.open(filePath, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | noFollow, 0o600);
|
|
223
|
+
try {
|
|
224
|
+
await handle.writeFile(`${value}\n`, 'utf8');
|
|
225
|
+
await handle.sync();
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
await handle.close();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function requireInvitationToken(value) {
|
|
232
|
+
const token = value.trim();
|
|
233
|
+
if (!ROOM_INVITATION_TOKEN_PATTERN.test(token)) {
|
|
234
|
+
throw new Error('Invalid room invitation token.');
|
|
235
|
+
}
|
|
236
|
+
return token;
|
|
237
|
+
}
|
|
238
|
+
function requireRelaycastBaseUrl(value) {
|
|
239
|
+
let url;
|
|
240
|
+
try {
|
|
241
|
+
url = new URL(value);
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
throw new Error('Cloud room returned an invalid session response.');
|
|
245
|
+
}
|
|
246
|
+
const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]';
|
|
247
|
+
if ((url.protocol !== 'https:' && !(url.protocol === 'http:' && loopback)) ||
|
|
248
|
+
url.username ||
|
|
249
|
+
url.password ||
|
|
250
|
+
url.search ||
|
|
251
|
+
url.hash) {
|
|
252
|
+
throw new Error('Cloud room returned an invalid session response.');
|
|
253
|
+
}
|
|
254
|
+
return url.toString().replace(/\/+$/, '');
|
|
255
|
+
}
|
|
256
|
+
function canonicalApiBaseUrl(value) {
|
|
257
|
+
let url;
|
|
258
|
+
try {
|
|
259
|
+
url = new URL(value);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
throw new Error('Invalid Cloud API URL.');
|
|
263
|
+
}
|
|
264
|
+
const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]';
|
|
265
|
+
if ((url.protocol !== 'https:' && !(url.protocol === 'http:' && loopback)) ||
|
|
266
|
+
url.username ||
|
|
267
|
+
url.password ||
|
|
268
|
+
url.search ||
|
|
269
|
+
url.hash) {
|
|
270
|
+
throw new Error('Invalid Cloud API URL.');
|
|
271
|
+
}
|
|
272
|
+
return url.toString().replace(/\/+$/, '');
|
|
273
|
+
}
|
|
274
|
+
function cloudRoomError(response) {
|
|
275
|
+
if (response.status === 401) {
|
|
276
|
+
return new Error('Cloud login required. Run `agent-relay cloud login` and retry.');
|
|
277
|
+
}
|
|
278
|
+
if (response.status === 403) {
|
|
279
|
+
return new Error('You do not have permission to perform that room operation.');
|
|
280
|
+
}
|
|
281
|
+
if (response.status === 404) {
|
|
282
|
+
return new Error('The room resource was not found or is no longer available.');
|
|
283
|
+
}
|
|
284
|
+
if (response.status === 409) {
|
|
285
|
+
return new Error('The room operation conflicts with the current membership state.');
|
|
286
|
+
}
|
|
287
|
+
if (response.status === 410) {
|
|
288
|
+
return new Error('The room invitation has expired or was already used.');
|
|
289
|
+
}
|
|
290
|
+
if (response.status === 429) {
|
|
291
|
+
const retryAfter = response.headers.get('retry-after')?.trim();
|
|
292
|
+
return new Error(`Cloud room rate limit exceeded.${retryAfter ? ` Retry-After: ${retryAfter} seconds.` : ' Wait and retry.'}`);
|
|
293
|
+
}
|
|
294
|
+
if (response.status >= 400 && response.status < 500) {
|
|
295
|
+
return new Error(`Cloud rejected the room request (${response.status}).`);
|
|
296
|
+
}
|
|
297
|
+
return new Error(`Cloud room request failed (${response.status}).`);
|
|
298
|
+
}
|
|
299
|
+
async function requestRoomWithAuth(deps, path, init, apiUrl, priorAuth) {
|
|
300
|
+
const requestedApiUrl = apiUrl ?? defaultApiUrl();
|
|
301
|
+
const auth = priorAuth ??
|
|
302
|
+
(await deps.ensureCloudSession({
|
|
303
|
+
apiUrl: requestedApiUrl,
|
|
304
|
+
interactive: false,
|
|
305
|
+
})).auth;
|
|
306
|
+
if (apiUrl && canonicalApiBaseUrl(auth.apiUrl) !== canonicalApiBaseUrl(requestedApiUrl)) {
|
|
307
|
+
throw new Error(`Cloud login is bound to ${canonicalApiBaseUrl(auth.apiUrl)}. Run \`agent-relay cloud login --api-url ${canonicalApiBaseUrl(requestedApiUrl)} --force\` before using this host.`);
|
|
308
|
+
}
|
|
309
|
+
const result = await deps.authorizedApiFetch(auth, path, init, {
|
|
310
|
+
interactive: false,
|
|
311
|
+
});
|
|
312
|
+
const payload = (await result.response.json().catch(() => null));
|
|
313
|
+
if (!result.response.ok) {
|
|
314
|
+
throw cloudRoomError(result.response);
|
|
315
|
+
}
|
|
316
|
+
if (containsForbiddenCredentialField(payload)) {
|
|
317
|
+
throw new Error('Cloud room returned a forbidden workspace or integration credential.');
|
|
318
|
+
}
|
|
319
|
+
return { payload, auth: result.auth };
|
|
320
|
+
}
|
|
321
|
+
async function requestRoom(deps, path, init, apiUrl) {
|
|
322
|
+
return (await requestRoomWithAuth(deps, path, init, apiUrl)).payload;
|
|
323
|
+
}
|
|
324
|
+
async function runRoomAction(deps, action) {
|
|
325
|
+
try {
|
|
326
|
+
await action();
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
deps.error(error instanceof Error ? error.message : String(error));
|
|
330
|
+
deps.exit(1);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function logJson(deps, payload) {
|
|
334
|
+
deps.log(JSON.stringify(payload, null, 2));
|
|
335
|
+
}
|
|
336
|
+
function textField(record, key) {
|
|
337
|
+
const value = record[key];
|
|
338
|
+
return typeof value === 'string' && value.trim() ? sanitizeTerminalCell(value.trim()) : undefined;
|
|
339
|
+
}
|
|
340
|
+
function renderInvites(payload, deps) {
|
|
341
|
+
const { invites } = payload;
|
|
342
|
+
if (invites.length === 0) {
|
|
343
|
+
deps.log('No active room invitations.');
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
for (const invite of invites) {
|
|
347
|
+
const id = textField(invite, 'id') ?? 'unknown';
|
|
348
|
+
const email = textField(invite, 'email') ?? 'unknown';
|
|
349
|
+
const role = textField(invite, 'role') ?? 'unknown';
|
|
350
|
+
const expiresAt = textField(invite, 'expiresAt');
|
|
351
|
+
deps.log([id, email, role, expiresAt ? `expires ${expiresAt}` : undefined].filter(Boolean).join(' '));
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function renderMembers(payload, deps) {
|
|
355
|
+
const { members } = payload;
|
|
356
|
+
if (members.length === 0) {
|
|
357
|
+
deps.log('No room members.');
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
for (const member of members) {
|
|
361
|
+
const id = textField(member, 'id') ?? 'unknown';
|
|
362
|
+
const email = textField(member, 'email') ?? textField(member, 'name') ?? 'unknown';
|
|
363
|
+
const role = textField(member, 'role') ?? 'unknown';
|
|
364
|
+
const status = textField(member, 'status');
|
|
365
|
+
deps.log([id, email, role, status].filter(Boolean).join(' '));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
export function registerCloudRoomCommands(cloudCommand, deps, ioOverrides = {}) {
|
|
369
|
+
const io = {
|
|
370
|
+
readStdin: defaultReadStdin,
|
|
371
|
+
readSecretFile: defaultReadSecretFile,
|
|
372
|
+
writeSecretFile: defaultWriteSecretFile,
|
|
373
|
+
...ioOverrides,
|
|
374
|
+
};
|
|
375
|
+
const room = cloudCommand.command('room').description('Manage workspace-scoped multiplayer rooms');
|
|
376
|
+
room
|
|
377
|
+
.command('invite')
|
|
378
|
+
.description('Invite a full participant to a workspace room')
|
|
379
|
+
.requiredOption('--workspace <workspace>', 'Cloud UUID or unified rw_ workspace ID')
|
|
380
|
+
.requiredOption('--email <email>', 'Email address bound to the invitation')
|
|
381
|
+
.option('--api-url <url>', 'Cloud API base URL')
|
|
382
|
+
.option('--expires-in <seconds>', 'Invitation lifetime in seconds', parsePositiveInteger, DEFAULT_INVITATION_LIFETIME_SECONDS)
|
|
383
|
+
.option('--token-stdout', 'Print only the one-time invitation token')
|
|
384
|
+
.option('--token-file <path>', 'Write the token to a new owner-only 0600 file')
|
|
385
|
+
.option('--json', 'Output the invitation and its one-time token as JSON')
|
|
386
|
+
.action(async (options) => {
|
|
387
|
+
await runRoomAction(deps, async () => {
|
|
388
|
+
const manualSinkCount = [options.tokenStdout, Boolean(options.tokenFile), options.json].filter(Boolean).length;
|
|
389
|
+
if (manualSinkCount !== 1) {
|
|
390
|
+
throw new Error('Use exactly one invitation token sink: --token-stdout, --token-file, or --json.');
|
|
391
|
+
}
|
|
392
|
+
const workspaceId = requireWorkspaceId(options.workspace);
|
|
393
|
+
const email = requireEmail(options.email);
|
|
394
|
+
const created = await requestRoomWithAuth(deps, `/api/v1/workspaces/${encodeURIComponent(workspaceId)}/room/invites`, {
|
|
395
|
+
method: 'POST',
|
|
396
|
+
body: JSON.stringify({
|
|
397
|
+
email,
|
|
398
|
+
role: 'participant',
|
|
399
|
+
expiresInSeconds: options.expiresIn,
|
|
400
|
+
}),
|
|
401
|
+
}, options.apiUrl);
|
|
402
|
+
const payload = normalizeInviteCreate(created.payload);
|
|
403
|
+
if (options.json) {
|
|
404
|
+
logJson(deps, payload);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (options.tokenStdout) {
|
|
408
|
+
deps.log(payload.invite.token);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
try {
|
|
412
|
+
await io.writeSecretFile(options.tokenFile ?? '', payload.invite.token);
|
|
413
|
+
}
|
|
414
|
+
catch (writeError) {
|
|
415
|
+
try {
|
|
416
|
+
await requestRoomWithAuth(deps, `/api/v1/workspaces/${encodeURIComponent(workspaceId)}/room/invites/${encodeURIComponent(payload.invite.id)}`, { method: 'DELETE' }, options.apiUrl, created.auth);
|
|
417
|
+
}
|
|
418
|
+
catch (cleanupError) {
|
|
419
|
+
throw new AggregateError([writeError, cleanupError], `Could not write the invitation token. Revocation could not be confirmed; revoke invitation ${sanitizeTerminalCell(payload.invite.id)} before retrying.`, { cause: writeError });
|
|
420
|
+
}
|
|
421
|
+
throw writeError;
|
|
422
|
+
}
|
|
423
|
+
deps.log(`Created full room-participant invitation for ${email}.`);
|
|
424
|
+
deps.log(`Wrote the one-time invitation token to ${sanitizeTerminalCell(options.tokenFile ?? '')}.`);
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
room
|
|
428
|
+
.command('invites')
|
|
429
|
+
.description('List workspace room invitations')
|
|
430
|
+
.requiredOption('--workspace <workspace>', 'Cloud UUID or unified rw_ workspace ID')
|
|
431
|
+
.option('--api-url <url>', 'Cloud API base URL')
|
|
432
|
+
.option('--json', 'Output invitations as JSON')
|
|
433
|
+
.action(async (options) => {
|
|
434
|
+
await runRoomAction(deps, async () => {
|
|
435
|
+
const workspaceId = requireWorkspaceId(options.workspace);
|
|
436
|
+
const payload = normalizeInviteList(await requestRoom(deps, `/api/v1/workspaces/${encodeURIComponent(workspaceId)}/room/invites`, { method: 'GET' }, options.apiUrl));
|
|
437
|
+
if (options.json) {
|
|
438
|
+
logJson(deps, payload);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
renderInvites(payload, deps);
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
room
|
|
445
|
+
.command('revoke-invite')
|
|
446
|
+
.description('Revoke an unused workspace room invitation')
|
|
447
|
+
.argument('<invite-id>', 'Invitation ID')
|
|
448
|
+
.requiredOption('--workspace <workspace>', 'Cloud UUID or unified rw_ workspace ID')
|
|
449
|
+
.option('--api-url <url>', 'Cloud API base URL')
|
|
450
|
+
.option('--json', 'Output the revocation response as JSON')
|
|
451
|
+
.action(async (inviteIdInput, options) => {
|
|
452
|
+
await runRoomAction(deps, async () => {
|
|
453
|
+
const workspaceId = requireWorkspaceId(options.workspace);
|
|
454
|
+
const inviteId = requireResourceId(inviteIdInput, 'invitation ID');
|
|
455
|
+
await requestRoom(deps, `/api/v1/workspaces/${encodeURIComponent(workspaceId)}/room/invites/${encodeURIComponent(inviteId)}`, { method: 'DELETE' }, options.apiUrl);
|
|
456
|
+
if (options.json) {
|
|
457
|
+
logJson(deps, { ok: true });
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
deps.log(`Revoked room invitation ${inviteId}.`);
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
room
|
|
464
|
+
.command('members')
|
|
465
|
+
.description('List workspace room members')
|
|
466
|
+
.requiredOption('--workspace <workspace>', 'Cloud UUID or unified rw_ workspace ID')
|
|
467
|
+
.option('--api-url <url>', 'Cloud API base URL')
|
|
468
|
+
.option('--json', 'Output members as JSON')
|
|
469
|
+
.action(async (options) => {
|
|
470
|
+
await runRoomAction(deps, async () => {
|
|
471
|
+
const workspaceId = requireWorkspaceId(options.workspace);
|
|
472
|
+
const payload = normalizeMemberList(await requestRoom(deps, `/api/v1/workspaces/${encodeURIComponent(workspaceId)}/room/members`, { method: 'GET' }, options.apiUrl));
|
|
473
|
+
if (options.json) {
|
|
474
|
+
logJson(deps, payload);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
renderMembers(payload, deps);
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
room
|
|
481
|
+
.command('remove-member')
|
|
482
|
+
.description('Remove a member and revoke their live room access')
|
|
483
|
+
.argument('<member-id>', 'Workspace membership ID')
|
|
484
|
+
.requiredOption('--workspace <workspace>', 'Cloud UUID or unified rw_ workspace ID')
|
|
485
|
+
.option('--api-url <url>', 'Cloud API base URL')
|
|
486
|
+
.option('--json', 'Output the removal response as JSON')
|
|
487
|
+
.action(async (memberIdInput, options) => {
|
|
488
|
+
await runRoomAction(deps, async () => {
|
|
489
|
+
const workspaceId = requireWorkspaceId(options.workspace);
|
|
490
|
+
const memberId = requireResourceId(memberIdInput, 'membership ID');
|
|
491
|
+
await requestRoom(deps, `/api/v1/workspaces/${encodeURIComponent(workspaceId)}/room/members/${encodeURIComponent(memberId)}`, { method: 'DELETE' }, options.apiUrl);
|
|
492
|
+
if (options.json) {
|
|
493
|
+
logJson(deps, { ok: true });
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
deps.log(`Removed room member ${memberId} and revoked their room sessions.`);
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
room
|
|
500
|
+
.command('accept')
|
|
501
|
+
.description('Accept an email-bound room invitation')
|
|
502
|
+
.option('--token-stdin', 'Read the single-use invitation token from stdin')
|
|
503
|
+
.option('--token-file <path>', 'Read the invitation token from an owner-only 0600 file')
|
|
504
|
+
.option('--api-url <url>', 'Cloud API base URL')
|
|
505
|
+
.option('--json', 'Output the accepted membership as JSON')
|
|
506
|
+
.action(async (options) => {
|
|
507
|
+
await runRoomAction(deps, async () => {
|
|
508
|
+
if (Boolean(options.tokenStdin) === Boolean(options.tokenFile)) {
|
|
509
|
+
throw new Error('Use exactly one of --token-stdin or --token-file.');
|
|
510
|
+
}
|
|
511
|
+
const token = requireInvitationToken(options.tokenStdin ? await io.readStdin() : await io.readSecretFile(options.tokenFile ?? ''));
|
|
512
|
+
const payload = normalizeMembership(await requestRoom(deps, '/api/v1/room/invites/accept', {
|
|
513
|
+
method: 'POST',
|
|
514
|
+
body: JSON.stringify({ token }),
|
|
515
|
+
}, options.apiUrl));
|
|
516
|
+
if (options.json) {
|
|
517
|
+
logJson(deps, payload);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
deps.log('Room invitation accepted.');
|
|
521
|
+
});
|
|
522
|
+
});
|
|
523
|
+
room
|
|
524
|
+
.command('revoke-session')
|
|
525
|
+
.description('Revoke this member’s scoped session for one device')
|
|
526
|
+
.requiredOption('--workspace <workspace>', 'Cloud UUID or unified rw_ workspace ID')
|
|
527
|
+
.requiredOption('--device-id <device-id>', 'Stable non-secret identifier for this client')
|
|
528
|
+
.option('--api-url <url>', 'Cloud API base URL')
|
|
529
|
+
.option('--json', 'Output the revocation response as JSON')
|
|
530
|
+
.action(async (options) => {
|
|
531
|
+
await runRoomAction(deps, async () => {
|
|
532
|
+
const workspaceId = requireWorkspaceId(options.workspace);
|
|
533
|
+
const deviceId = requireDeviceId(options.deviceId);
|
|
534
|
+
await requestRoom(deps, `/api/v1/workspaces/${encodeURIComponent(workspaceId)}/room/session`, {
|
|
535
|
+
method: 'DELETE',
|
|
536
|
+
body: JSON.stringify({ deviceId }),
|
|
537
|
+
}, options.apiUrl);
|
|
538
|
+
if (options.json) {
|
|
539
|
+
logJson(deps, { ok: true });
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
deps.log(`Revoked room session for device ${sanitizeTerminalCell(deviceId)}.`);
|
|
543
|
+
});
|
|
544
|
+
});
|
|
545
|
+
room
|
|
546
|
+
.command('session')
|
|
547
|
+
.description('Create or resume this device’s full room-participant session')
|
|
548
|
+
.requiredOption('--workspace <workspace>', 'Cloud UUID or unified rw_ workspace ID')
|
|
549
|
+
.requiredOption('--device-id <device-id>', 'Stable non-secret identifier for this client')
|
|
550
|
+
.option('--api-url <url>', 'Cloud API base URL')
|
|
551
|
+
.option('--json', 'Output the session, including its participant credential')
|
|
552
|
+
.action(async (options) => {
|
|
553
|
+
await runRoomAction(deps, async () => {
|
|
554
|
+
const workspaceId = requireWorkspaceId(options.workspace);
|
|
555
|
+
const deviceId = requireDeviceId(options.deviceId);
|
|
556
|
+
const payload = normalizeRoomSession(await requestRoom(deps, `/api/v1/workspaces/${encodeURIComponent(workspaceId)}/room/session`, {
|
|
557
|
+
method: 'POST',
|
|
558
|
+
body: JSON.stringify({ deviceId }),
|
|
559
|
+
}, options.apiUrl));
|
|
560
|
+
if (options.json) {
|
|
561
|
+
logJson(deps, payload);
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
deps.log('Full-participant room session ready.');
|
|
565
|
+
deps.log('Scoped credentials are hidden. Trusted clients may request them explicitly with --json.');
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
//# sourceMappingURL=cloud-room.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-room.js","sourceRoot":"","sources":["../../../src/cli/commands/cloud-room.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/cloud.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAgC,MAAM,WAAW,CAAC;AAElE,OAAO,EAEL,kBAAkB,EAClB,kBAAkB,EAgBlB,eAAe,EACf,yBAAyB,EAI1B,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/cloud.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAgC,MAAM,WAAW,CAAC;AAElE,OAAO,EAEL,kBAAkB,EAClB,kBAAkB,EAgBlB,eAAe,EACf,yBAAyB,EAI1B,MAAM,oBAAoB,CAAC;AAkB5B,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD;AAID,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;AAEtC,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,yBAAyB,EAAE,OAAO,yBAAyB,CAAC;IAC5D;;;;OAIG;IACH,2BAA2B,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;CAC1D;AAuVD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,GAAE,OAAO,CAAC,iBAAiB,CAAM,GAAG,IAAI,CA+oBxG"}
|
|
@@ -6,6 +6,8 @@ import { ensureAuthenticated, ensureCloudSession, authorizedApiFetch, readStored
|
|
|
6
6
|
import { defaultExit } from '../lib/exit.js';
|
|
7
7
|
import { errorClassName } from '../lib/telemetry-helpers.js';
|
|
8
8
|
import { track } from '../telemetry/index.js';
|
|
9
|
+
import { registerCloudRoomCommands } from './cloud-room.js';
|
|
10
|
+
import { registerCloudIntegrationCommands } from './cloud-integration.js';
|
|
9
11
|
import { registerCloudWorkerCommands } from './cloud-worker.js';
|
|
10
12
|
const CLOUD_SYNC_PATCH_EXCLUDES = [
|
|
11
13
|
'.agent-bin/**',
|
|
@@ -266,6 +268,8 @@ export function registerCloudCommands(program, overrides = {}) {
|
|
|
266
268
|
.command('cloud')
|
|
267
269
|
.description('Cloud account, provider auth, and workflow commands');
|
|
268
270
|
registerCloudWorkerCommands(cloudCommand, deps);
|
|
271
|
+
registerCloudRoomCommands(cloudCommand, deps);
|
|
272
|
+
registerCloudIntegrationCommands(cloudCommand, deps);
|
|
269
273
|
// ── login ──────────────────────────────────────────────────────────────────
|
|
270
274
|
cloudCommand
|
|
271
275
|
.command('login')
|