@bctrl/cli 0.1.7 → 0.1.9
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 +17 -89
- package/dist/api/client.d.ts +1 -0
- package/dist/api/client.js +1 -0
- package/dist/api/errors.js +2 -2
- package/dist/bin/bctrl.js +0 -0
- package/dist/commands/{vault → account}/index.d.ts +1 -1
- package/dist/commands/account/index.js +21 -0
- package/dist/commands/ai/index.js +13 -8
- package/dist/commands/api-key/index.js +1 -1
- package/dist/commands/browser-extension/index.js +8 -8
- package/dist/commands/conversation/index.d.ts +3 -0
- package/dist/commands/conversation/index.js +51 -0
- package/dist/commands/file/index.js +8 -3
- package/dist/commands/run/index.js +23 -292
- package/dist/commands/runtime/index.js +32 -453
- package/dist/commands/shared/operation.d.ts +3 -0
- package/dist/commands/shared/operation.js +20 -7
- package/dist/commands/space/index.js +0 -25
- package/dist/commands/subaccount/index.js +2 -2
- package/dist/commands/tool/index.js +15 -5
- package/dist/commands/tool-call/index.js +22 -6
- package/dist/commands/toolset/index.js +1 -1
- package/dist/commands/view/index.d.ts +3 -0
- package/dist/commands/view/index.js +26 -0
- package/dist/commands/webhook/index.d.ts +3 -0
- package/dist/commands/webhook/index.js +64 -0
- package/dist/generated/help.d.ts +4896 -5977
- package/dist/generated/help.js +6208 -7532
- package/dist/generated/openapi-routes.d.ts +114 -142
- package/dist/generated/openapi-routes.js +37 -44
- package/dist/generated/openapi-types.d.ts +4451 -5302
- package/dist/root.js +8 -2
- package/package.json +14 -12
- package/dist/commands/vault/index.js +0 -171
|
@@ -1,465 +1,44 @@
|
|
|
1
|
-
import { Command
|
|
2
|
-
import {
|
|
3
|
-
import { addPaginationFlags, buildOperationInput, createOperationJsonBodyCommand, outputFlags, requestOperationAndPrint, uploadOperationFile, } from '../shared/operation.js';
|
|
4
|
-
import { parsePositiveInteger } from '../shared/options.js';
|
|
5
|
-
import { addOutputFlags, outputData } from '../shared/output.js';
|
|
6
|
-
import { CliError } from '../../runtime/errors.js';
|
|
7
|
-
import { addCliOperationHelp } from '../shared/help.js';
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { createOperationDeleteCommand, createOperationJsonBodyCommand, createOperationListCommand, createOperationViewCommand, } from '../shared/operation.js';
|
|
8
3
|
export function createRuntimeCommand(factory) {
|
|
9
|
-
const command = new Command('runtime').description('Manage
|
|
10
|
-
command.addCommand(
|
|
11
|
-
.
|
|
12
|
-
|
|
13
|
-
'active',
|
|
14
|
-
'failed',
|
|
15
|
-
'stopped',
|
|
16
|
-
]))
|
|
17
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (options) => {
|
|
18
|
-
await requestOperationAndPrint(factory, 'runtimes.list', await buildOperationInput('runtimes.list', options, {
|
|
19
|
-
query: {
|
|
20
|
-
spaceId: options.space,
|
|
21
|
-
status: options.status ? [options.status] : undefined,
|
|
22
|
-
limit: options.limit,
|
|
23
|
-
cursor: options.cursor,
|
|
24
|
-
},
|
|
25
|
-
output: outputFlags(options),
|
|
26
|
-
}));
|
|
4
|
+
const command = new Command('runtime').description('Manage runtime lifecycle');
|
|
5
|
+
command.addCommand(createOperationListCommand(factory, {
|
|
6
|
+
operationId: 'runtimes.list',
|
|
7
|
+
description: 'List runtimes',
|
|
27
8
|
}));
|
|
28
|
-
command.addCommand(addOutputFlags(new Command('get')
|
|
29
|
-
.description('Get a runtime')
|
|
30
|
-
.argument('<runtimeId>')
|
|
31
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
32
|
-
await requestOperationAndPrint(factory, 'runtimes.get', await buildOperationInput('runtimes.get', options, {
|
|
33
|
-
pathParams: { runtimeId },
|
|
34
|
-
output: outputFlags(options),
|
|
35
|
-
}));
|
|
36
|
-
}));
|
|
37
|
-
command.addCommand(createRuntimeCreateCommand(factory));
|
|
38
|
-
command.addCommand(createRuntimePatchCommand(factory));
|
|
39
|
-
command.addCommand(addOutputFlags(new Command('delete')
|
|
40
|
-
.description('Delete a runtime and its browser state')
|
|
41
|
-
.argument('<runtimeId>')
|
|
42
|
-
.option('-y, --yes', 'Confirm deletion')
|
|
43
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
44
|
-
if (options.yes !== true) {
|
|
45
|
-
throw new CliError('Refusing to delete without --yes');
|
|
46
|
-
}
|
|
47
|
-
await requestOperationAndPrint(factory, 'runtimes.delete', await buildOperationInput('runtimes.delete', options, {
|
|
48
|
-
pathParams: { runtimeId },
|
|
49
|
-
output: outputFlags(options),
|
|
50
|
-
}));
|
|
51
|
-
}));
|
|
52
|
-
command.addCommand(createRuntimeStartCommand(factory));
|
|
53
|
-
command.addCommand(addOutputFlags(new Command('stop')
|
|
54
|
-
.description('Stop a runtime')
|
|
55
|
-
.argument('<runtimeId>')
|
|
56
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
57
|
-
await requestOperationAndPrint(factory, 'runtimes.stop', await buildOperationInput('runtimes.stop', options, {
|
|
58
|
-
pathParams: { runtimeId },
|
|
59
|
-
output: outputFlags(options),
|
|
60
|
-
}));
|
|
61
|
-
}));
|
|
62
|
-
command.addCommand(createRuntimeFileCommand(factory));
|
|
63
|
-
command.addCommand(createRuntimeInvocationCommand(factory));
|
|
64
|
-
command.addCommand(createRuntimeHumanActionCommand(factory));
|
|
65
|
-
command.addCommand(createRuntimeTargetCommand(factory));
|
|
66
|
-
return command;
|
|
67
|
-
}
|
|
68
|
-
function createRuntimeTargetCommand(factory) {
|
|
69
|
-
const command = new Command('target').description('Manage runtime targets (tabs)');
|
|
70
|
-
command.addCommand(addOutputFlags(new Command('list')
|
|
71
|
-
.description('List targets')
|
|
72
|
-
.argument('<runtimeId>')
|
|
73
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
74
|
-
await requestOperationAndPrint(factory, 'runtimes.targets.list', await buildOperationInput('runtimes.targets.list', options, {
|
|
75
|
-
pathParams: { runtimeId },
|
|
76
|
-
output: outputFlags(options),
|
|
77
|
-
}));
|
|
78
|
-
}));
|
|
79
|
-
command.addCommand(addOutputFlags(new Command('create')
|
|
80
|
-
.description('Open a new target')
|
|
81
|
-
.argument('<runtimeId>')
|
|
82
|
-
.option('--uri <uri>', 'Navigate the new target to this URI')
|
|
83
|
-
.option('--activate', 'Focus the new target')
|
|
84
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')
|
|
85
|
-
.option('--body <json>', 'Request body as JSON (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
86
|
-
await requestOperationAndPrint(factory, 'runtimes.targets.create', await buildOperationInput('runtimes.targets.create', options, {
|
|
87
|
-
pathParams: { runtimeId },
|
|
88
|
-
body: {
|
|
89
|
-
...(options.uri ? { uri: options.uri } : {}),
|
|
90
|
-
...(options.activate ? { activate: true } : {}),
|
|
91
|
-
},
|
|
92
|
-
output: outputFlags(options),
|
|
93
|
-
}));
|
|
94
|
-
}));
|
|
95
|
-
command.addCommand(addOutputFlags(new Command('get')
|
|
96
|
-
.description('Get a target')
|
|
97
|
-
.argument('<runtimeId>')
|
|
98
|
-
.argument('<targetId>')
|
|
99
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, targetId, options) => {
|
|
100
|
-
await requestOperationAndPrint(factory, 'runtimes.targets.get', await buildOperationInput('runtimes.targets.get', options, {
|
|
101
|
-
pathParams: { runtimeId, targetId },
|
|
102
|
-
output: outputFlags(options),
|
|
103
|
-
}));
|
|
104
|
-
}));
|
|
105
|
-
command.addCommand(addOutputFlags(new Command('activate')
|
|
106
|
-
.description('Focus a target')
|
|
107
|
-
.argument('<runtimeId>')
|
|
108
|
-
.argument('<targetId>')
|
|
109
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, targetId, options) => {
|
|
110
|
-
await requestOperationAndPrint(factory, 'runtimes.targets.activate', await buildOperationInput('runtimes.targets.activate', options, {
|
|
111
|
-
pathParams: { runtimeId, targetId },
|
|
112
|
-
output: outputFlags(options),
|
|
113
|
-
}));
|
|
114
|
-
}));
|
|
115
|
-
command.addCommand(addOutputFlags(new Command('delete')
|
|
116
|
-
.description('Close a target')
|
|
117
|
-
.argument('<runtimeId>')
|
|
118
|
-
.argument('<targetId>')
|
|
119
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, targetId, options) => {
|
|
120
|
-
await requestOperationAndPrint(factory, 'runtimes.targets.delete', await buildOperationInput('runtimes.targets.delete', options, {
|
|
121
|
-
pathParams: { runtimeId, targetId },
|
|
122
|
-
output: outputFlags(options),
|
|
123
|
-
}));
|
|
124
|
-
}));
|
|
125
|
-
return command;
|
|
126
|
-
}
|
|
127
|
-
function createRuntimeCreateCommand(factory) {
|
|
128
|
-
return addOutputFlags(addCliOperationHelp(new Command('create')
|
|
129
|
-
.description('Create a runtime')
|
|
130
|
-
.option('--space <id>', 'Space id; omitted uses caller default space')
|
|
131
|
-
.option('--name <name>', 'Runtime name')
|
|
132
|
-
.option('--profile', 'Persist browser state across runtime starts')
|
|
133
|
-
.option('--proxy <id-or-url>', 'Saved proxy id or inline custom proxy URL')
|
|
134
|
-
.addOption(new Option('--device <device>', 'Fingerprint device filter').choices([
|
|
135
|
-
'desktop',
|
|
136
|
-
'mobile',
|
|
137
|
-
]))
|
|
138
|
-
.addOption(new Option('--os <os>', 'Fingerprint OS filter').choices([
|
|
139
|
-
'windows',
|
|
140
|
-
'macos',
|
|
141
|
-
'android',
|
|
142
|
-
'ios',
|
|
143
|
-
]))
|
|
144
|
-
.addOption(new Option('--browser <browser>', 'Fingerprint browser filter').choices([
|
|
145
|
-
'chrome',
|
|
146
|
-
'edge',
|
|
147
|
-
'safari',
|
|
148
|
-
]))
|
|
149
|
-
.option('--browser-version <version>', 'Fingerprint browser version filter')
|
|
150
|
-
.option('--locale <locale>', 'Fingerprint locale/language filter; repeat to set an ordered language stack', collectLocale, [])
|
|
151
|
-
.option('--config-file <path>', 'Runtime config JSON file')
|
|
152
|
-
.option('--metadata-file <path>', 'Runtime metadata JSON file')
|
|
153
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')
|
|
154
|
-
.option('--body <json>', 'Full request body as JSON (inline, @file, or - for stdin)'), 'runtimes.create')).action(async (options) => {
|
|
155
|
-
// --body (raw JSON) is the complete body; otherwise build it from
|
|
156
|
-
// the curated flags. --params can still add query params. The control-plane
|
|
157
|
-
// validates the body against the runtimes.create schema either way.
|
|
158
|
-
const config = typeof options.configFile === 'string'
|
|
159
|
-
? await readJsonFile(options.configFile, '--config-file')
|
|
160
|
-
: undefined;
|
|
161
|
-
await requestOperationAndPrint(factory, 'runtimes.create', await buildOperationInput('runtimes.create', options, {
|
|
162
|
-
body: {
|
|
163
|
-
type: 'browser',
|
|
164
|
-
spaceId: options.space,
|
|
165
|
-
name: options.name,
|
|
166
|
-
config: buildRuntimeCreateConfig(config, options),
|
|
167
|
-
metadata: typeof options.metadataFile === 'string'
|
|
168
|
-
? await readJsonFile(options.metadataFile, '--metadata-file')
|
|
169
|
-
: undefined,
|
|
170
|
-
},
|
|
171
|
-
output: outputFlags(options),
|
|
172
|
-
}));
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
function collectLocale(value, previous) {
|
|
176
|
-
return [...previous, value];
|
|
177
|
-
}
|
|
178
|
-
function isRecord(value) {
|
|
179
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
180
|
-
}
|
|
181
|
-
function buildRuntimeCreateConfig(config, options) {
|
|
182
|
-
const fingerprint = {
|
|
183
|
-
...(options.device ? { device: options.device } : {}),
|
|
184
|
-
...(options.os ? { os: options.os } : {}),
|
|
185
|
-
...(options.browser ? { browser: options.browser } : {}),
|
|
186
|
-
...(options.browserVersion ? { browserVersion: options.browserVersion } : {}),
|
|
187
|
-
...(options.locale && options.locale.length === 1 ? { locale: options.locale[0] } : {}),
|
|
188
|
-
...(options.locale && options.locale.length > 1 ? { locale: options.locale } : {}),
|
|
189
|
-
};
|
|
190
|
-
const overrides = {
|
|
191
|
-
...(options.profile === true ? { profile: true } : {}),
|
|
192
|
-
...(options.proxy ? { proxy: options.proxy } : {}),
|
|
193
|
-
...(Object.keys(fingerprint).length > 0 ? { fingerprint } : {}),
|
|
194
|
-
};
|
|
195
|
-
if (Object.keys(overrides).length === 0) {
|
|
196
|
-
return config;
|
|
197
|
-
}
|
|
198
|
-
if (config !== undefined && !isRecord(config)) {
|
|
199
|
-
throw new Error('--config-file must contain a JSON object when combined with runtime flags');
|
|
200
|
-
}
|
|
201
|
-
if (!isRecord(config)) {
|
|
202
|
-
return overrides;
|
|
203
|
-
}
|
|
204
|
-
return {
|
|
205
|
-
...config,
|
|
206
|
-
...overrides,
|
|
207
|
-
...(isRecord(config.fingerprint) || 'fingerprint' in overrides
|
|
208
|
-
? {
|
|
209
|
-
fingerprint: {
|
|
210
|
-
...(isRecord(config.fingerprint) ? config.fingerprint : {}),
|
|
211
|
-
...(isRecord(overrides.fingerprint) ? overrides.fingerprint : {}),
|
|
212
|
-
},
|
|
213
|
-
}
|
|
214
|
-
: {}),
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
function createRuntimePatchCommand(factory) {
|
|
218
|
-
return addOutputFlags(new Command('patch')
|
|
219
|
-
.description('Update a runtime')
|
|
220
|
-
.argument('<runtimeId>')
|
|
221
|
-
.option('--name <name>', 'Runtime name')
|
|
222
|
-
.option('--idle-timeout-seconds <seconds>', 'Idle timeout in seconds', parsePositiveInteger)
|
|
223
|
-
.option('--config-file <path>', 'Runtime config JSON file')
|
|
224
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')
|
|
225
|
-
.option('--body <json>', 'Request body as JSON (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
226
|
-
await requestOperationAndPrint(factory, 'runtimes.update', await buildOperationInput('runtimes.update', options, {
|
|
227
|
-
pathParams: { runtimeId },
|
|
228
|
-
body: {
|
|
229
|
-
name: options.name,
|
|
230
|
-
idleTimeoutSeconds: options.idleTimeoutSeconds,
|
|
231
|
-
config: typeof options.configFile === 'string'
|
|
232
|
-
? await readJsonFile(options.configFile, '--config-file')
|
|
233
|
-
: undefined,
|
|
234
|
-
},
|
|
235
|
-
output: outputFlags(options),
|
|
236
|
-
}));
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
function createRuntimeStartCommand(factory) {
|
|
240
|
-
return addOutputFlags(new Command('start')
|
|
241
|
-
.description('Start a runtime')
|
|
242
|
-
.argument('<runtimeId>')
|
|
243
|
-
.option('--idempotency-key <key>', 'Idempotency key for retry-safe start')
|
|
244
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
245
|
-
await requestOperationAndPrint(factory, 'runtimes.start', await buildOperationInput('runtimes.start', options, {
|
|
246
|
-
pathParams: { runtimeId },
|
|
247
|
-
idempotencyKey: options.idempotencyKey,
|
|
248
|
-
output: outputFlags(options),
|
|
249
|
-
}));
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
function createRuntimeInvocationCommand(factory) {
|
|
253
|
-
const command = new Command('invocation').description('Create, wait for, and cancel invocations');
|
|
254
|
-
command.addCommand(createRuntimeInvocationCreateCommand(factory));
|
|
255
|
-
command.addCommand(createRuntimeInvocationWaitCommand(factory));
|
|
256
|
-
command.addCommand(addOutputFlags(new Command('cancel')
|
|
257
|
-
.description('Cancel an invocation')
|
|
258
|
-
.argument('<runtimeId>')
|
|
259
|
-
.argument('<invocationId>')
|
|
260
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, invocationId, options) => {
|
|
261
|
-
await requestOperationAndPrint(factory, 'runtimes.invocations.cancel', await buildOperationInput('runtimes.invocations.cancel', options, {
|
|
262
|
-
pathParams: { runtimeId, invocationId },
|
|
263
|
-
output: outputFlags(options),
|
|
264
|
-
}));
|
|
265
|
-
}));
|
|
266
|
-
return command;
|
|
267
|
-
}
|
|
268
|
-
function createRuntimeInvocationCreateCommand(factory) {
|
|
269
|
-
return addOutputFlags(new Command('create')
|
|
270
|
-
.description('Create a runtime invocation')
|
|
271
|
-
.argument('<runtimeId>')
|
|
272
|
-
.option('--action <action>', 'Invocation action')
|
|
273
|
-
.option('--instruction <text>', 'Instruction for action/agent invocations')
|
|
274
|
-
.option('--target <target>', "Target to act on: 'active' (default), 'new', or a target id")
|
|
275
|
-
.option('--model <model>', 'Model id')
|
|
276
|
-
.option('--tool <id...>', 'Inline tool id')
|
|
277
|
-
.option('--toolset <id>', 'Toolset id')
|
|
278
|
-
.option('--timeout-seconds <seconds>', 'Invocation timeout in seconds', parsePositiveInteger)
|
|
279
|
-
.option('--idempotency-key <key>', 'Idempotency key for retry-safe create')
|
|
280
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')
|
|
281
|
-
.option('--body <json>', 'Request body as JSON (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
282
|
-
const body = {
|
|
283
|
-
action: options.action,
|
|
284
|
-
instruction: options.instruction,
|
|
285
|
-
target: options.target === undefined
|
|
286
|
-
? undefined
|
|
287
|
-
: options.target === 'active' || options.target === 'new'
|
|
288
|
-
? options.target
|
|
289
|
-
: { id: options.target },
|
|
290
|
-
model: options.model,
|
|
291
|
-
toolIds: options.tool,
|
|
292
|
-
toolsetId: options.toolset,
|
|
293
|
-
timeoutSeconds: options.timeoutSeconds,
|
|
294
|
-
};
|
|
295
|
-
await requestOperationAndPrint(factory, 'runtimes.invocations.create', await buildOperationInput('runtimes.invocations.create', options, {
|
|
296
|
-
pathParams: { runtimeId },
|
|
297
|
-
body: body,
|
|
298
|
-
idempotencyKey: options.idempotencyKey,
|
|
299
|
-
output: outputFlags(options),
|
|
300
|
-
}));
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
function createRuntimeInvocationWaitCommand(factory) {
|
|
304
|
-
return createOperationJsonBodyCommand(factory, {
|
|
305
|
-
operationId: 'runtimes.invocations.wait',
|
|
306
|
-
name: 'wait',
|
|
307
|
-
description: 'Wait for an invocation',
|
|
308
|
-
argNames: ['runtimeId', 'invocationId'],
|
|
309
|
-
configure: (cmd) => cmd
|
|
310
|
-
.option('--timeout-seconds <seconds>', 'Wait timeout in seconds', parsePositiveInteger),
|
|
311
|
-
body: async (_args, options) => {
|
|
312
|
-
return {
|
|
313
|
-
timeoutSeconds: options.timeoutSeconds,
|
|
314
|
-
};
|
|
315
|
-
},
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
function createRuntimeHumanActionCommand(factory) {
|
|
319
|
-
const command = new Command('human-action').description('Manage runtime human actions');
|
|
320
9
|
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
321
|
-
operationId: 'runtimes.
|
|
10
|
+
operationId: 'runtimes.create',
|
|
322
11
|
name: 'create',
|
|
323
|
-
description: '
|
|
324
|
-
argNames: ['runtimeId'],
|
|
325
|
-
configure: (cmd) => cmd
|
|
326
|
-
.option('--message <message>', 'Instructions for the human')
|
|
327
|
-
.option('--timeout-seconds <seconds>', 'Human action timeout in seconds', parsePositiveInteger),
|
|
328
|
-
body: async (_args, options) => {
|
|
329
|
-
return {
|
|
330
|
-
message: options.message,
|
|
331
|
-
timeoutSeconds: options.timeoutSeconds,
|
|
332
|
-
};
|
|
333
|
-
},
|
|
12
|
+
description: 'Create a runtime',
|
|
334
13
|
}));
|
|
335
|
-
command.addCommand(
|
|
336
|
-
.
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
pathParams: { runtimeId },
|
|
341
|
-
output: outputFlags(options),
|
|
342
|
-
}));
|
|
14
|
+
command.addCommand(createOperationViewCommand(factory, {
|
|
15
|
+
operationId: 'runtimes.get',
|
|
16
|
+
name: 'get',
|
|
17
|
+
description: 'Get a runtime',
|
|
18
|
+
argName: 'runtimeId',
|
|
343
19
|
}));
|
|
344
|
-
command.addCommand(
|
|
345
|
-
.
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
pathParams: { runtimeId },
|
|
350
|
-
output: outputFlags(options),
|
|
351
|
-
}));
|
|
20
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
21
|
+
operationId: 'runtimes.update',
|
|
22
|
+
name: 'patch',
|
|
23
|
+
description: 'Update a runtime',
|
|
24
|
+
argNames: ['runtimeId'],
|
|
352
25
|
}));
|
|
353
|
-
command.addCommand(
|
|
354
|
-
.
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
await requestOperationAndPrint(factory, 'runtimes.human-actions.cancel', await buildOperationInput('runtimes.human-actions.cancel', options, {
|
|
358
|
-
pathParams: { runtimeId },
|
|
359
|
-
output: outputFlags(options),
|
|
360
|
-
}));
|
|
26
|
+
command.addCommand(createOperationDeleteCommand(factory, {
|
|
27
|
+
operationId: 'runtimes.delete',
|
|
28
|
+
description: 'Delete a runtime',
|
|
29
|
+
argNames: ['runtimeId'],
|
|
361
30
|
}));
|
|
362
|
-
command.addCommand(
|
|
363
|
-
.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
.option('--body <json>', 'Request body as JSON (inline, @file, or - for stdin)'), 'runtimes.human-actions.wait')).action(async (runtimeId, options) => {
|
|
368
|
-
await requestOperationAndPrint(factory, 'runtimes.human-actions.wait', await buildOperationInput('runtimes.human-actions.wait', options, {
|
|
369
|
-
pathParams: { runtimeId },
|
|
370
|
-
body: {
|
|
371
|
-
timeoutSeconds: options.timeoutSeconds,
|
|
372
|
-
},
|
|
373
|
-
output: outputFlags(options),
|
|
374
|
-
}));
|
|
31
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
32
|
+
operationId: 'runtimes.start',
|
|
33
|
+
name: 'start',
|
|
34
|
+
description: 'Start a runtime',
|
|
35
|
+
argNames: ['runtimeId'],
|
|
375
36
|
}));
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
.option('--type <type>', 'Filter by file type')
|
|
382
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (runtimeId, options) => {
|
|
383
|
-
await requestOperationAndPrint(factory, 'runtimes.files.list', await buildOperationInput('runtimes.files.list', options, {
|
|
384
|
-
pathParams: { runtimeId },
|
|
385
|
-
query: {
|
|
386
|
-
type: options.type,
|
|
387
|
-
limit: options.limit,
|
|
388
|
-
cursor: options.cursor,
|
|
389
|
-
},
|
|
390
|
-
output: outputFlags(options),
|
|
391
|
-
}));
|
|
37
|
+
command.addCommand(createOperationJsonBodyCommand(factory, {
|
|
38
|
+
operationId: 'runtimes.stop',
|
|
39
|
+
name: 'stop',
|
|
40
|
+
description: 'Stop a runtime',
|
|
41
|
+
argNames: ['runtimeId'],
|
|
392
42
|
}));
|
|
393
|
-
command.addCommand(createRuntimeFileUploadCommand(factory));
|
|
394
|
-
command.addCommand(createRuntimeFileStageCommand(factory));
|
|
395
|
-
command.addCommand(createRuntimeFileCollectCommand(factory));
|
|
396
43
|
return command;
|
|
397
44
|
}
|
|
398
|
-
function createRuntimeFileUploadCommand(factory) {
|
|
399
|
-
return addOutputFlags(new Command('upload')
|
|
400
|
-
.description('Upload a local file into a runtime workspace')
|
|
401
|
-
.argument('<runtimeId>')
|
|
402
|
-
.argument('<localPath>')
|
|
403
|
-
.option('--destination-path <path>', 'Durable BCTRL storage destination')
|
|
404
|
-
.option('--runtime-path <path>', 'Runtime workspace destination')
|
|
405
|
-
.option('--name <name>', 'Display name')
|
|
406
|
-
.option('--metadata <json>', 'Metadata as inline JSON (overrides --metadata-file)')
|
|
407
|
-
.option('--metadata-file <path>', 'Metadata JSON file')).action(async (runtimeId, localPath, options) => {
|
|
408
|
-
const file = await readBlob(localPath);
|
|
409
|
-
const metadata = options.metadata !== undefined
|
|
410
|
-
? JSON.stringify(parseJsonString(options.metadata, '--metadata'))
|
|
411
|
-
: typeof options.metadataFile === 'string'
|
|
412
|
-
? JSON.stringify(await readJsonFile(options.metadataFile, '--metadata-file'))
|
|
413
|
-
: undefined;
|
|
414
|
-
const result = await uploadOperationFile(factory, 'runtimes.files.upload', {
|
|
415
|
-
pathParams: { runtimeId },
|
|
416
|
-
file: file.blob,
|
|
417
|
-
fileName: options.name ?? file.fileName,
|
|
418
|
-
fields: {
|
|
419
|
-
...(options.destinationPath ? { destinationPath: options.destinationPath } : {}),
|
|
420
|
-
...(options.runtimePath ? { runtimePath: options.runtimePath } : {}),
|
|
421
|
-
...(options.name ? { name: options.name } : {}),
|
|
422
|
-
...(metadata ? { metadata } : {}),
|
|
423
|
-
},
|
|
424
|
-
});
|
|
425
|
-
await outputData(factory.io, result, options);
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
function createRuntimeFileStageCommand(factory) {
|
|
429
|
-
return createOperationJsonBodyCommand(factory, {
|
|
430
|
-
operationId: 'runtimes.files.stage',
|
|
431
|
-
name: 'stage',
|
|
432
|
-
description: 'Stage a durable file into a runtime',
|
|
433
|
-
argNames: ['runtimeId'],
|
|
434
|
-
configure: (cmd) => cmd
|
|
435
|
-
.option('--file <id>', 'Durable file id')
|
|
436
|
-
.option('--runtime-path <path>', 'Runtime workspace destination')
|
|
437
|
-
.option('--name <name>', 'Runtime-local display name'),
|
|
438
|
-
body: async (_args, options) => {
|
|
439
|
-
return {
|
|
440
|
-
fileId: options.file,
|
|
441
|
-
runtimePath: options.runtimePath,
|
|
442
|
-
name: options.name,
|
|
443
|
-
};
|
|
444
|
-
},
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
function createRuntimeFileCollectCommand(factory) {
|
|
448
|
-
return createOperationJsonBodyCommand(factory, {
|
|
449
|
-
operationId: 'runtimes.files.collect',
|
|
450
|
-
name: 'collect',
|
|
451
|
-
description: 'Collect a runtime-local file into durable storage',
|
|
452
|
-
argNames: ['runtimeId'],
|
|
453
|
-
configure: (cmd) => cmd
|
|
454
|
-
.requiredOption('--runtime-path <path>', 'Runtime workspace source')
|
|
455
|
-
.option('--name <name>', 'Durable file name')
|
|
456
|
-
.option('--destination-path <path>', 'Durable BCTRL storage destination'),
|
|
457
|
-
body: async (_args, options) => {
|
|
458
|
-
return {
|
|
459
|
-
runtimePath: options.runtimePath,
|
|
460
|
-
name: options.name,
|
|
461
|
-
destinationPath: options.destinationPath,
|
|
462
|
-
};
|
|
463
|
-
},
|
|
464
|
-
});
|
|
465
|
-
}
|
|
@@ -43,6 +43,7 @@ type OperationBodyInput<OperationId extends CliOperationId> = [
|
|
|
43
43
|
export type OperationRequestInput<OperationId extends CliOperationId> = OperationPathInput<OperationId> & OperationQueryInput<OperationId> & OperationBodyInput<OperationId> & {
|
|
44
44
|
idempotencyKey?: string;
|
|
45
45
|
actingSubaccountId?: string;
|
|
46
|
+
runtimeId?: string;
|
|
46
47
|
output?: OutputFlags;
|
|
47
48
|
};
|
|
48
49
|
export declare function optionString(options: Record<string, unknown>, name: string): string | undefined;
|
|
@@ -94,6 +95,7 @@ export declare function streamOperationText<OperationId extends CliOperationId>(
|
|
|
94
95
|
export declare function createOperationListCommand<OperationId extends CliOperationId>(factory: ApiDeps, config: {
|
|
95
96
|
operationId: OperationId;
|
|
96
97
|
name?: string;
|
|
98
|
+
argNames?: string[];
|
|
97
99
|
description: string;
|
|
98
100
|
configure?: (command: Command) => Command;
|
|
99
101
|
query?: (options: Record<string, unknown>) => CliOperationQuery<OperationId>;
|
|
@@ -126,5 +128,6 @@ export declare function createOperationJsonBodyCommand<OperationId extends CliOp
|
|
|
126
128
|
body?: (args: Record<string, string>, options: Record<string, unknown>) => Promise<CliOperationJsonBody<OperationId>>;
|
|
127
129
|
query?: (args: Record<string, string>, options: Record<string, unknown>) => CliOperationQuery<OperationId>;
|
|
128
130
|
actingSubaccountId?: (args: Record<string, string>, options: Record<string, unknown>) => string | undefined;
|
|
131
|
+
runtimeId?: (args: Record<string, string>, options: Record<string, unknown>) => string | undefined;
|
|
129
132
|
}): Command;
|
|
130
133
|
export {};
|
|
@@ -122,6 +122,8 @@ export async function buildOperationInput(operationId, options, curated) {
|
|
|
122
122
|
merged.idempotencyKey = c.idempotencyKey;
|
|
123
123
|
if (c.actingSubaccountId)
|
|
124
124
|
merged.actingSubaccountId = c.actingSubaccountId;
|
|
125
|
+
if (c.runtimeId)
|
|
126
|
+
merged.runtimeId = c.runtimeId;
|
|
125
127
|
if (c.output)
|
|
126
128
|
merged.output = c.output;
|
|
127
129
|
return merged;
|
|
@@ -171,6 +173,7 @@ export async function requestOperation(deps, operationId, input) {
|
|
|
171
173
|
...('body' in input && input.body !== undefined ? { body: input.body } : {}),
|
|
172
174
|
...(input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : {}),
|
|
173
175
|
...(input.actingSubaccountId ? { actingSubaccountId: input.actingSubaccountId } : {}),
|
|
176
|
+
...(input.runtimeId ? { runtimeId: input.runtimeId } : {}),
|
|
174
177
|
};
|
|
175
178
|
const options = Object.keys(requestOptions).length > 0 ? requestOptions : undefined;
|
|
176
179
|
const result = route.method === 'get'
|
|
@@ -179,9 +182,7 @@ export async function requestOperation(deps, operationId, input) {
|
|
|
179
182
|
? await client.post(path, options)
|
|
180
183
|
: route.method === 'patch'
|
|
181
184
|
? await client.patch(path, options)
|
|
182
|
-
:
|
|
183
|
-
? await client.put(path, options)
|
|
184
|
-
: await client.delete(path, options);
|
|
185
|
+
: await client.delete(path, options);
|
|
185
186
|
return result;
|
|
186
187
|
}
|
|
187
188
|
export async function uploadOperationFile(deps, operationId, input) {
|
|
@@ -208,17 +209,26 @@ export async function streamOperationText(deps, operationId, input) {
|
|
|
208
209
|
});
|
|
209
210
|
}
|
|
210
211
|
export function createOperationListCommand(factory, config) {
|
|
212
|
+
const argNames = config.argNames ?? [];
|
|
211
213
|
let command = new Command(config.name ?? 'list').description(config.description);
|
|
212
214
|
command = addCliOperationHelp(command, config.operationId);
|
|
215
|
+
for (const arg of argNames)
|
|
216
|
+
command = command.argument(`<${arg}>`);
|
|
213
217
|
command = config.configure ? config.configure(command) : addPaginationFlags(command);
|
|
214
218
|
command = addRequestOverrideFlags(command);
|
|
215
219
|
command = addOutputFlags(command);
|
|
216
|
-
return command.action(async (
|
|
220
|
+
return command.action(async (...actionArgs) => {
|
|
221
|
+
const options = getActionOptions(actionArgs);
|
|
222
|
+
const args = {};
|
|
223
|
+
for (let i = 0; i < argNames.length; i += 1)
|
|
224
|
+
args[argNames[i]] = String(actionArgs[i]);
|
|
217
225
|
const overrides = await resolveRequestOverrides(config.operationId, options);
|
|
218
226
|
const curatedQuery = config.query ? config.query(options) : defaultListQuery(options);
|
|
219
227
|
const actingSubaccountId = config.actingSubaccountId?.(options);
|
|
220
228
|
await requestOperationAndPrint(factory, config.operationId, withActingSubaccount({
|
|
221
|
-
...(
|
|
229
|
+
...(argNames.length > 0 || overrides.pathParams
|
|
230
|
+
? { pathParams: overlayDefined(overrides.pathParams, args) }
|
|
231
|
+
: {}),
|
|
222
232
|
query: overlayDefined(overrides.query, curatedQuery),
|
|
223
233
|
output: outputFlags(options),
|
|
224
234
|
}, actingSubaccountId));
|
|
@@ -293,12 +303,15 @@ export function createOperationJsonBodyCommand(factory, config) {
|
|
|
293
303
|
const body = overrides.body !== undefined ? overrides.body : (curatedBody ?? {});
|
|
294
304
|
const curatedQuery = config.query ? config.query(args, options) : undefined;
|
|
295
305
|
const actingSubaccountId = config.actingSubaccountId?.(args, options);
|
|
296
|
-
|
|
306
|
+
const runtimeId = config.runtimeId?.(args, options);
|
|
307
|
+
const requestInput = withActingSubaccount({
|
|
297
308
|
pathParams: overlayDefined(overrides.pathParams, args),
|
|
298
309
|
body,
|
|
299
310
|
query: overlayDefined(overrides.query, curatedQuery),
|
|
300
311
|
output: outputFlags(options),
|
|
301
|
-
|
|
312
|
+
...(runtimeId ? { runtimeId } : {}),
|
|
313
|
+
}, actingSubaccountId);
|
|
314
|
+
await requestOperationAndPrint(factory, config.operationId, requestInput);
|
|
302
315
|
});
|
|
303
316
|
}
|
|
304
317
|
function defaultListQuery(options) {
|
|
@@ -54,30 +54,5 @@ export function createSpaceCommand(factory) {
|
|
|
54
54
|
output: outputFlags(options),
|
|
55
55
|
}));
|
|
56
56
|
}));
|
|
57
|
-
command.addCommand(createSpaceEnvironmentCommand(factory));
|
|
58
|
-
return command;
|
|
59
|
-
}
|
|
60
|
-
function createSpaceEnvironmentCommand(factory) {
|
|
61
|
-
const command = new Command('env').description('Manage a space environment');
|
|
62
|
-
command.addCommand(addOutputFlags(new Command('get')
|
|
63
|
-
.description('Get a space environment')
|
|
64
|
-
.argument('<spaceId>')
|
|
65
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')).action(async (spaceId, options) => {
|
|
66
|
-
await requestOperationAndPrint(factory, 'spaces.environment.get', await buildOperationInput('spaces.environment.get', options, {
|
|
67
|
-
pathParams: { spaceId },
|
|
68
|
-
output: outputFlags(options),
|
|
69
|
-
}));
|
|
70
|
-
}));
|
|
71
|
-
command.addCommand(addOutputFlags(new Command('patch')
|
|
72
|
-
.description('Update a space environment')
|
|
73
|
-
.argument('<spaceId>')
|
|
74
|
-
.option('--params <json>', 'Path/query parameters as a JSON object (inline, @file, or - for stdin)')
|
|
75
|
-
.option('--body <json>', 'Request body as JSON (inline, @file, or - for stdin)')).action(async (spaceId, options) => {
|
|
76
|
-
await requestOperationAndPrint(factory, 'spaces.environment.update', await buildOperationInput('spaces.environment.update', options, {
|
|
77
|
-
pathParams: { spaceId },
|
|
78
|
-
body: {},
|
|
79
|
-
output: outputFlags(options),
|
|
80
|
-
}));
|
|
81
|
-
}));
|
|
82
57
|
return command;
|
|
83
58
|
}
|
|
@@ -14,13 +14,13 @@ export function createSubaccountCommand(factory) {
|
|
|
14
14
|
include: options.includeUsage === true ? 'usage' : undefined,
|
|
15
15
|
status: typeof options.status === 'string' ? options.status : undefined,
|
|
16
16
|
externalId: typeof options.externalId === 'string' ? options.externalId : undefined,
|
|
17
|
-
|
|
17
|
+
q: typeof options.q === 'string' ? options.q : undefined,
|
|
18
18
|
}),
|
|
19
19
|
configure: (cmd) => addPaginationFlags(cmd)
|
|
20
20
|
.option('--include-usage', 'Inline current usage')
|
|
21
21
|
.option('--status <status>', 'Filter by status')
|
|
22
22
|
.option('--external-id <id>', 'Filter by external id')
|
|
23
|
-
.option('--
|
|
23
|
+
.option('--q <text>', 'Search by id, name, or external id'),
|
|
24
24
|
}));
|
|
25
25
|
command.addCommand(createOperationViewCommand(factory, {
|
|
26
26
|
operationId: 'subaccounts.get',
|