@shardflux/cli 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/README.md +132 -27
- package/dist/account-args.js +32 -4
- package/dist/account-commands.js +234 -111
- package/dist/args.d.ts +1 -2
- package/dist/args.js +288 -6
- package/dist/commands.d.ts +15 -1
- package/dist/commands.js +384 -5
- package/dist/format.d.ts +21 -1
- package/dist/format.js +61 -0
- package/dist/main.js +8 -0
- package/package.json +2 -2
package/dist/args.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { parseArgs } from 'node:util';
|
|
13
13
|
import { ACCOUNT_COMMANDS } from "./account-args.js";
|
|
14
14
|
import { UsageError } from "./errors.js";
|
|
15
|
-
export const CLI_VERSION = '0.
|
|
15
|
+
export const CLI_VERSION = '0.10.0';
|
|
16
16
|
export const GLOBAL_OPTIONS = {
|
|
17
17
|
'api-url': { type: 'string', value: '<url>', description: 'API base URL (default $SHARDFLUX_API_URL, else https://api.shardflux.dev).' },
|
|
18
18
|
json: { type: 'boolean', description: 'Print machine-readable JSON on stdout (errors as JSON on stderr).' },
|
|
@@ -32,9 +32,9 @@ const MEMORY_ALLOCATION = {
|
|
|
32
32
|
'allocation-mode': {
|
|
33
33
|
type: 'string',
|
|
34
34
|
value: '<fixed|elastic>',
|
|
35
|
-
description: 'elastic: --memory-mib is
|
|
35
|
+
description: 'elastic: --memory-mib is the most the workspace may grow to; it holds --memory-held while idle and grows when a command needs more, and billing counts the memory it holds. fixed: a static allocation of --memory-mib. Send it with every caps flag to keep the mode you chose; a command without caps flags keeps the stored layout. Takes effect at the next VM start (shard ws resize changes a running or suspended workspace).',
|
|
36
36
|
},
|
|
37
|
-
'memory-held': { type: 'string', value: '<mib>', description: '
|
|
37
|
+
'memory-held': { type: 'string', value: '<mib>', description: 'Elastic: memory held while idle, in MiB (at least 512, default 1024, at most --memory-mib).' },
|
|
38
38
|
};
|
|
39
39
|
/** `--timing` (0.3.0+): the SDK's lifecycle timing of the command's open, wait or wake (README "Timing"). */
|
|
40
40
|
const TIMING = {
|
|
@@ -61,7 +61,16 @@ const WAIT = {
|
|
|
61
61
|
...TIMING,
|
|
62
62
|
};
|
|
63
63
|
const REF = { name: 'id|key', required: true };
|
|
64
|
+
/** A TCP port inside the workspace (1-65535). */
|
|
65
|
+
const PORT = { name: 'port', required: true };
|
|
64
66
|
const SLUG = { name: 'slug', required: true };
|
|
67
|
+
/** The screenshot after a computer action or batch (0.10.0+). */
|
|
68
|
+
const COMPUTER_LOOK = {
|
|
69
|
+
screenshot: { type: 'string', value: '<file>', description: 'Take a screenshot after it and write it here.' },
|
|
70
|
+
settle: { type: 'string', value: '<ms>', description: 'Wait this long before that screenshot when the screen may change (0-10000, default 250).' },
|
|
71
|
+
format: { type: 'string', value: '<png|jpeg>', description: 'Screenshot format (default png).' },
|
|
72
|
+
quality: { type: 'string', value: '<1-100>', description: 'JPEG quality (default 80).' },
|
|
73
|
+
};
|
|
65
74
|
const PAGE = {
|
|
66
75
|
all: { type: 'boolean', description: 'Fetch every page.' },
|
|
67
76
|
limit: { type: 'string', value: '<n>', description: 'Page size.' },
|
|
@@ -216,6 +225,11 @@ const KEY_COMMANDS = [
|
|
|
216
225
|
value: '<processful|file-first>',
|
|
217
226
|
description: 'file-first: the workspace is a versioned file tree with no VM between commands; each "shard ws exec" runs in a fresh VM and keeps the files it changed under /home/user as the next tree revision. Ready at once, never suspended, persistent, needs a layered template version. Default: processful for a new key, the stored mode for an existing one (a mode never changes).',
|
|
218
227
|
},
|
|
228
|
+
'computer-use': {
|
|
229
|
+
type: 'string',
|
|
230
|
+
value: '<on|off|inherit>',
|
|
231
|
+
description: 'Computer use (0.10.0+): on gives the workspace a desktop agents drive (shard ws computer); inherit follows the template. Default: unchanged (off for a new key unless its template turns it on).',
|
|
232
|
+
},
|
|
219
233
|
...INPUTS,
|
|
220
234
|
...CAPS,
|
|
221
235
|
...MEMORY_ALLOCATION,
|
|
@@ -252,6 +266,7 @@ const KEY_COMMANDS = [
|
|
|
252
266
|
{ path: ['workspaces', 'labels'], summary: 'Read or replace workspace labels', positionals: [REF], options: {
|
|
253
267
|
set: { type: 'string', value: '<json>', description: 'Replace all labels; {} clears them.' },
|
|
254
268
|
} },
|
|
269
|
+
{ path: ['workspaces', 'hint'], summary: 'Stage a parked workspace ahead of an imminent tool call', positionals: [REF], options: {} },
|
|
255
270
|
{ path: ['workspaces', 'idle'], summary: 'Inspect idle status, set policy or declare a keepalive', positionals: [REF], options: {
|
|
256
271
|
policy: { type: 'string', value: '<policy>', description: 'adaptive, never, fixed:<seconds>, or default to clear the override.' },
|
|
257
272
|
keepalive: { type: 'string', value: '<seconds>', description: 'Declare ongoing work for this many seconds.' },
|
|
@@ -262,10 +277,20 @@ const KEY_COMMANDS = [
|
|
|
262
277
|
description: 'Runs argv directly (no shell; use `-- bash -lc "..."` for shell syntax) and returns the session at once (JSON on stdout). Read it with "shard ws exec-read", stop it with "shard ws exec-cancel".',
|
|
263
278
|
positionals: [REF, { name: 'command', required: true, variadic: true }],
|
|
264
279
|
options: {
|
|
280
|
+
template: {
|
|
281
|
+
type: 'string',
|
|
282
|
+
value: '<slug>',
|
|
283
|
+
description: 'Open the key first (0.10.0+): the workspace is created from this template on first use (stderr says so) and resumed if suspended; "default" is the platform default template. Without it the key must already have a workspace.',
|
|
284
|
+
},
|
|
265
285
|
'stdin-open': { type: 'boolean', description: 'Keep pipe stdin open for exec-input.' },
|
|
266
286
|
'session-id': { type: 'string', value: '<id>', description: 'Caller-chosen id to deduplicate starts.' },
|
|
267
287
|
cwd: { type: 'string', value: '<dir>', description: 'Absolute working directory.' },
|
|
268
288
|
timeout: { type: 'string', value: '<duration>', description: 'Kill the command after this long (e.g. 30m, 2h; none unless set). The workspace stays awake until the command ends or this passes (1 hour when unset).' },
|
|
289
|
+
'resource-hint': {
|
|
290
|
+
type: 'string',
|
|
291
|
+
value: '<auto|light|heavy>',
|
|
292
|
+
description: 'Processful (0.9.0+): heavy gives an elastic workspace its memory before the command starts (a build, a test suite, an install); light starts it at once; auto (default) decides from the command.',
|
|
293
|
+
},
|
|
269
294
|
},
|
|
270
295
|
examples: ['shard ws exec-start acme/demo --session-id build-1 --timeout 2h -- bash -lc "make -C /home/user/app"', 'shard ws exec-read acme/demo build-1 --follow'],
|
|
271
296
|
},
|
|
@@ -297,9 +322,14 @@ const KEY_COMMANDS = [
|
|
|
297
322
|
{
|
|
298
323
|
path: ['workspaces', 'exec'],
|
|
299
324
|
summary: 'Run a command in a workspace; prints its output and exits with its exit code',
|
|
300
|
-
description: 'Runs argv directly (no shell; use `-- bash -lc "..."` for shell syntax). Processful workspaces: output is streamed as it arrives and resumes from byte offsets after dropped connections; Ctrl-C stops waiting and cancels the command. File-first workspaces: the command runs as an execution in a fresh VM on the latest tree revision; its output is printed when it ended, and the files it changed under /home/user become the next tree revision (-v lists them). An execution runs to completion: Ctrl-C stops waiting and names the command that fetches its result later. A failed or lost execution (nothing published) exits 6, as does a command that could not start (a --cwd that is not a directory, a program not on PATH), with the workspace’s reason.',
|
|
325
|
+
description: 'Also `shard exec` (0.10.0+). With --template the key is opened first, so one command creates the workspace on first use: `shard exec acme/demo --template default -- python3 -V`. Runs argv directly (no shell; use `-- bash -lc "..."` for shell syntax). Processful workspaces: output is streamed as it arrives and resumes from byte offsets after dropped connections; Ctrl-C stops waiting and cancels the command. File-first workspaces: the command runs as an execution in a fresh VM on the latest tree revision; its output is printed when it ended, and the files it changed under /home/user become the next tree revision (-v lists them). An execution runs to completion: Ctrl-C stops waiting and names the command that fetches its result later. A failed or lost execution (nothing published) exits 6, as does a command that could not start (a --cwd that is not a directory, a program not on PATH), with the workspace’s reason.',
|
|
301
326
|
positionals: [REF, { name: 'command', required: true, variadic: true }],
|
|
302
327
|
options: {
|
|
328
|
+
template: {
|
|
329
|
+
type: 'string',
|
|
330
|
+
value: '<slug>',
|
|
331
|
+
description: 'Open the key first (0.10.0+): the workspace is created from this template on first use (stderr says so) and resumed if suspended; "default" is the platform default template. Without it the key must already have a workspace.',
|
|
332
|
+
},
|
|
303
333
|
cwd: { type: 'string', value: '<dir>', description: 'Working directory, an absolute path (default /home/user; under /home/user on a file-first workspace). A relative path is refused (invalid_cwd).' },
|
|
304
334
|
env: { type: 'string', multiple: true, value: '<K=V>', description: 'Environment variable (repeatable).' },
|
|
305
335
|
timeout: { type: 'string', value: '<duration>', description: 'Kill the command after this long (exit code 124).' },
|
|
@@ -310,6 +340,11 @@ const KEY_COMMANDS = [
|
|
|
310
340
|
description: 'File-first: the execution’s id (8-128 of A-Z a-z 0-9 . _ : -, starting with a letter or digit; default a fresh ex-<uuid>). Running the same command again with the same id returns its recorded result instead of running it twice, so scripts can repeat the call safely.',
|
|
311
341
|
},
|
|
312
342
|
'output-limit': { type: 'string', value: '<bytes>', description: 'File-first: keep at most this many bytes of stdout and of stderr each (1-16777216; default 1 MiB).' },
|
|
343
|
+
'resource-hint': {
|
|
344
|
+
type: 'string',
|
|
345
|
+
value: '<auto|light|heavy>',
|
|
346
|
+
description: 'Processful (0.9.0+): heavy gives an elastic workspace its memory before the command starts (a build, a test suite, an install); light starts it at once; auto (default) decides from the command.',
|
|
347
|
+
},
|
|
313
348
|
burst: {
|
|
314
349
|
type: 'boolean',
|
|
315
350
|
description: 'Processful: run this command on a larger, short-lived burst VM on the workspace’s host and apply its file changes back when it exits (needs the burst execution entitlement). Its processes and tmpfs content do not come back; the workspace’s own processes pause meanwhile. Not with --stdin; cannot be canceled.',
|
|
@@ -329,6 +364,7 @@ const KEY_COMMANDS = [
|
|
|
329
364
|
'shard ws exec acme/agent-7 -v --execution-id build-42 --timeout 10m -- bash -lc "make -C /home/user/app"',
|
|
330
365
|
'shard ws exec acme/agent-7 --json -- python3 /home/user/report.py > result.json',
|
|
331
366
|
'shard ws exec acme/demo --burst --burst-vcpus 16 -v -- bash -lc "cd /home/user/app && go build ./..."',
|
|
367
|
+
'shard ws exec acme/demo --resource-hint heavy -- python3 train.py',
|
|
332
368
|
],
|
|
333
369
|
},
|
|
334
370
|
{
|
|
@@ -351,6 +387,23 @@ const KEY_COMMANDS = [
|
|
|
351
387
|
positionals: [REF, { name: 'new-key', required: true }],
|
|
352
388
|
options: { ...CAPS, ...MEMORY_ALLOCATION, ...WAIT },
|
|
353
389
|
},
|
|
390
|
+
{
|
|
391
|
+
path: ['workspaces', 'resize'],
|
|
392
|
+
summary: 'Change a workspace’s memory, CPU or disk, running or suspended, without a restart (0.9.0+)',
|
|
393
|
+
description: 'Memory changes live and disks grow online; a suspended workspace gets its new size when it resumes, before its first call. CPU changes live within the vCPUs the workspace booted with; a larger CPU size applies at the next start. The new caps are stored, so every later start uses them. Prints per resource the change and when it applies: now, on resume or next start. Waits until the resize has finished.',
|
|
394
|
+
positionals: [REF],
|
|
395
|
+
options: {
|
|
396
|
+
memory: { type: 'string', value: '<mib>', description: 'Memory in MiB: the size of a fixed workspace, the most an elastic one may grow to.' },
|
|
397
|
+
held: { type: 'string', value: '<mib>', description: 'Elastic: the memory held while idle, in MiB (at most the memory size).' },
|
|
398
|
+
fixed: { type: 'boolean', description: 'Switch to a static allocation of the memory size.' },
|
|
399
|
+
elastic: { type: 'boolean', description: 'Switch to elastic memory: the workspace holds what its commands use and grows up to the memory size.' },
|
|
400
|
+
cpu: { type: 'string', value: '<millis>', description: 'CPU in millicores (1000 = one vCPU).' },
|
|
401
|
+
disk: { type: 'string', value: '<gib>', description: 'Disk in GiB (disks grow only).' },
|
|
402
|
+
timeout: { type: 'string', value: '<duration>', description: 'Give up waiting after this long (default 5m); the resize continues server side.' },
|
|
403
|
+
...TIMING,
|
|
404
|
+
},
|
|
405
|
+
examples: ['shard ws resize acme/demo --memory 6144', 'shard ws resize acme/demo --memory 8192 --cpu 4000 --disk 40', 'shard ws resize acme/demo --elastic --held 1024', 'shard ws resize acme/demo --memory 4096 --fixed --json'],
|
|
406
|
+
},
|
|
354
407
|
{
|
|
355
408
|
path: ['workspaces', 'delete'],
|
|
356
409
|
summary: 'Delete a workspace (tool access ends now; storage is cleaned up asynchronously)',
|
|
@@ -410,6 +463,231 @@ const KEY_COMMANDS = [
|
|
|
410
463
|
},
|
|
411
464
|
examples: ['shard ws secrets acme/demo', 'shard ws secrets acme/demo --set OPENAI_API_KEY --set DATABASE_URL', 'shard ws secrets acme/demo --clear'],
|
|
412
465
|
},
|
|
466
|
+
{
|
|
467
|
+
path: ['workspaces', 'port', 'expose'],
|
|
468
|
+
summary: 'Serve a port of a workspace at its own private HTTPS URL (0.9.0+)',
|
|
469
|
+
description: 'Requests to the URL reach TCP <port> inside the workspace; a request to a parked or suspended workspace wakes it and is answered once it runs. Every port is private: a request carries a port token (shard ws port token), a browser link’s session (shard ws port link) or arrives on the callback URL (shard ws port callback). The server inside the workspace listens on 0.0.0.0. Idempotent: an exposed port keeps its URL, tokens, links and callback URL. --json prints the API’s port object {port, url, created_at, callback}.',
|
|
470
|
+
positionals: [REF, PORT],
|
|
471
|
+
options: {},
|
|
472
|
+
examples: ['shard ws port expose acme/demo 3000', 'curl -H "Authorization: Bearer $(shard ws port token acme/demo 3000)" "$(shard ws port expose acme/demo 3000 --json | jq -r .url)/"'],
|
|
473
|
+
},
|
|
474
|
+
{ path: ['workspaces', 'port', 'ls'], summary: 'List the exposed ports of a workspace and their URLs (0.9.0+)', positionals: [REF], options: {} },
|
|
475
|
+
{
|
|
476
|
+
path: ['workspaces', 'port', 'close'],
|
|
477
|
+
summary: 'Close an exposed port: its tokens, links and callback URL stop working at once (0.9.0+)',
|
|
478
|
+
description: 'Idempotent (also when the port is not exposed). Exposing the port again gives it new tokens, links and callback URL; the URL stays the same.',
|
|
479
|
+
positionals: [REF, PORT],
|
|
480
|
+
options: {},
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
path: ['workspaces', 'port', 'token'],
|
|
484
|
+
summary: 'Mint a port token and print it alone on stdout (0.9.0+)',
|
|
485
|
+
description: 'Send it as `Authorization: Bearer <token>` (or `X-Shardflux-Token: <token>` when the app reads Authorization itself) with requests to the port’s URL. Closing the port revokes it. --json prints {token, expires_at, url}.',
|
|
486
|
+
positionals: [REF, PORT],
|
|
487
|
+
options: { ttl: { type: 'string', value: '<duration>', description: 'Lifetime, 1m to 24h (e.g. 15m, 2h; default 1h).' } },
|
|
488
|
+
examples: ['TOKEN=$(shard ws port token acme/demo 3000 --ttl 15m)', 'shard ws port token acme/demo 3000 --json | jq -r .token'],
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
path: ['workspaces', 'port', 'link'],
|
|
492
|
+
summary: 'Create a link that opens the port in a browser and print it (0.9.0+)',
|
|
493
|
+
description: 'Opening the link starts a browser session for the port (until it expires) and lands on --path. Anyone with the link can open the port until then: share it like a password. --json prints {url, expires_at}.',
|
|
494
|
+
positionals: [REF, PORT],
|
|
495
|
+
options: {
|
|
496
|
+
ttl: { type: 'string', value: '<duration>', description: 'Lifetime of the link and its browser session, 1m to 7d (default 24h).' },
|
|
497
|
+
path: { type: 'string', value: '<path>', description: 'Where the link lands: a path starting with one / (query allowed; default /).' },
|
|
498
|
+
},
|
|
499
|
+
examples: ['shard ws port link acme/demo 3000 --path /dashboard', 'open "$(shard ws port link acme/demo 3000)"'],
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
path: ['workspaces', 'port', 'callback'],
|
|
503
|
+
summary: 'Create (or replace) the port’s callback URL for webhooks and OAuth redirects, or revoke it (0.9.0+)',
|
|
504
|
+
description: 'Register the printed URL plus your own path with GitHub, Slack, Stripe or an OAuth provider: a request to <url><rest> reaches /<rest> of the port (query kept) without a token header and wakes the workspace like any request. The URL is shown only once; creating it again replaces it (the previous one stops working). --json prints {url, created_at}.',
|
|
505
|
+
positionals: [REF, PORT],
|
|
506
|
+
options: { revoke: { type: 'boolean', description: 'Revoke the port’s callback URL instead (idempotent).' } },
|
|
507
|
+
examples: ['shard ws port callback acme/demo 3000', 'shard ws port callback acme/demo 3000 --revoke'],
|
|
508
|
+
},
|
|
509
|
+
// ---- computer use (0.10.0; contracts §45) ----
|
|
510
|
+
{
|
|
511
|
+
path: ['workspaces', 'computer', 'status'],
|
|
512
|
+
summary: 'Show whether the workspace desktop runs, its size and its viewers (0.10.0+)',
|
|
513
|
+
description: 'Never starts the desktop. Needs computer use on for the workspace (shard ws computer enable). --json prints {running, display, width, height, started_at, session, streams}.',
|
|
514
|
+
positionals: [REF],
|
|
515
|
+
options: {},
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
path: ['workspaces', 'computer', 'screenshot'],
|
|
519
|
+
summary: 'Save a screenshot of the workspace desktop (0.10.0+)',
|
|
520
|
+
description: 'Starts the desktop when it does not run. Writes the image to --out (default screenshot.png, or screenshot.jpg with --format jpeg). --json prints {out, format, width, height, bytes}.',
|
|
521
|
+
positionals: [REF],
|
|
522
|
+
options: {
|
|
523
|
+
out: { type: 'string', value: '<file>', description: 'Where to write the image (default screenshot.png).' },
|
|
524
|
+
format: { type: 'string', value: '<png|jpeg>', description: 'Image format (default png).' },
|
|
525
|
+
quality: { type: 'string', value: '<1-100>', description: 'JPEG quality (default 80).' },
|
|
526
|
+
},
|
|
527
|
+
examples: ['shard ws computer screenshot acme/demo --out desktop.png', 'shard ws computer screenshot acme/demo --format jpeg --quality 60'],
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
path: ['workspaces', 'computer', 'act'],
|
|
531
|
+
summary: 'Run a batch of computer actions on the workspace desktop (0.10.0+)',
|
|
532
|
+
description: 'The actions are a JSON array of Claude computer toolset members with their parameters, e.g. [{"action":"left_click","coordinate":[640,400]},{"action":"type","text":"hello"}]; - reads it from standard input. They run in order; the first failure stops the batch and the rest are reported skipped. --screenshot saves a screenshot taken after the last action. --json prints the full result (images base64).',
|
|
533
|
+
positionals: [REF, { name: 'actions-json', required: true }],
|
|
534
|
+
options: { ...COMPUTER_LOOK },
|
|
535
|
+
examples: [
|
|
536
|
+
`shard ws computer act acme/demo '[{"action":"key","text":"ctrl+l"},{"action":"type","text":"example.com\\n"}]' --screenshot after.png`,
|
|
537
|
+
'echo \'[{"action":"cursor_position"}]\' | shard ws computer act acme/demo -',
|
|
538
|
+
],
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
path: ['workspaces', 'computer', 'click'],
|
|
542
|
+
summary: 'Click on the workspace desktop (0.10.0+)',
|
|
543
|
+
description: 'At <x> <y> (screen pixels from the top-left of a screenshot), or at the pointer without them. --button right|middle, --count 2|3 for a double or triple click (left button), --mods holds modifier keys (e.g. shift, ctrl+shift).',
|
|
544
|
+
positionals: [REF, { name: 'x' }, { name: 'y' }],
|
|
545
|
+
options: {
|
|
546
|
+
button: { type: 'string', value: '<left|right|middle>', description: 'Mouse button (default left).' },
|
|
547
|
+
count: { type: 'string', value: '<1|2|3>', description: 'Clicks: 2 is a double click, 3 a triple click (left button; default 1).' },
|
|
548
|
+
mods: { type: 'string', value: '<keys>', description: 'Modifier keys held during the click, e.g. shift or ctrl+shift.' },
|
|
549
|
+
...COMPUTER_LOOK,
|
|
550
|
+
},
|
|
551
|
+
examples: ['shard ws computer click acme/demo 640 400 --screenshot after.png', 'shard ws computer click acme/demo 200 120 --count 2'],
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
path: ['workspaces', 'computer', 'type'],
|
|
555
|
+
summary: 'Type text on the workspace desktop (0.10.0+)',
|
|
556
|
+
description: 'Types into the focused window, Unicode included (up to 20,000 characters); - reads the text from standard input. A newline presses Return.',
|
|
557
|
+
positionals: [REF, { name: 'text|-', required: true }],
|
|
558
|
+
options: { ...COMPUTER_LOOK },
|
|
559
|
+
examples: ['shard ws computer type acme/demo "hello world"', 'cat notes.txt | shard ws computer type acme/demo -'],
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
path: ['workspaces', 'computer', 'key'],
|
|
563
|
+
summary: 'Press keys on the workspace desktop (0.10.0+)',
|
|
564
|
+
description: 'One key or combination, or several separated by spaces: Return, Escape, ctrl+s, alt+Tab, ctrl+shift+t, F5, Page_Down.',
|
|
565
|
+
positionals: [REF, { name: 'keys', required: true }],
|
|
566
|
+
options: {
|
|
567
|
+
repeat: { type: 'string', value: '<n>', description: 'Press it n times (1-100).' },
|
|
568
|
+
...COMPUTER_LOOK,
|
|
569
|
+
},
|
|
570
|
+
examples: ['shard ws computer key acme/demo ctrl+l', 'shard ws computer key acme/demo Tab --repeat 3 --screenshot form.png'],
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
path: ['workspaces', 'computer', 'scroll'],
|
|
574
|
+
summary: 'Scroll on the workspace desktop (0.10.0+)',
|
|
575
|
+
description: 'Scrolls up, down, left or right by --amount wheel clicks (default 3), at <x> <y> or at the pointer.',
|
|
576
|
+
positionals: [REF, { name: 'up|down|left|right', required: true }, { name: 'x' }, { name: 'y' }],
|
|
577
|
+
options: {
|
|
578
|
+
amount: { type: 'string', value: '<n>', description: 'Wheel clicks (1-100, default 3).' },
|
|
579
|
+
mods: { type: 'string', value: '<keys>', description: 'Modifier keys held while scrolling, e.g. shift.' },
|
|
580
|
+
...COMPUTER_LOOK,
|
|
581
|
+
},
|
|
582
|
+
examples: ['shard ws computer scroll acme/demo down 640 400 --amount 5'],
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
path: ['workspaces', 'computer', 'move'],
|
|
586
|
+
summary: 'Move the pointer on the workspace desktop (0.10.0+)',
|
|
587
|
+
positionals: [REF, { name: 'x', required: true }, { name: 'y', required: true }],
|
|
588
|
+
options: { ...COMPUTER_LOOK },
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
path: ['workspaces', 'computer', 'drag'],
|
|
592
|
+
summary: 'Drag with the left button on the workspace desktop (0.10.0+)',
|
|
593
|
+
description: 'Presses at <x1> <y1>, moves to <x2> <y2> and releases.',
|
|
594
|
+
positionals: [REF, { name: 'x1', required: true }, { name: 'y1', required: true }, { name: 'x2', required: true }, { name: 'y2', required: true }],
|
|
595
|
+
options: {
|
|
596
|
+
mods: { type: 'string', value: '<keys>', description: 'Modifier keys held during the drag, e.g. alt.' },
|
|
597
|
+
...COMPUTER_LOOK,
|
|
598
|
+
},
|
|
599
|
+
examples: ['shard ws computer drag acme/demo 100 200 500 200'],
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
path: ['workspaces', 'computer', 'mouse-down'],
|
|
603
|
+
summary: 'Press the left mouse button and keep it down (0.10.0+)',
|
|
604
|
+
description: 'At the pointer (shard ws computer move first); shard ws computer mouse-up releases it.',
|
|
605
|
+
positionals: [REF],
|
|
606
|
+
options: { ...COMPUTER_LOOK },
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
path: ['workspaces', 'computer', 'mouse-up'],
|
|
610
|
+
summary: 'Release the left mouse button (0.10.0+)',
|
|
611
|
+
positionals: [REF],
|
|
612
|
+
options: { ...COMPUTER_LOOK },
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
path: ['workspaces', 'computer', 'hold-key'],
|
|
616
|
+
summary: 'Hold keys down for some seconds on the workspace desktop (0.10.0+)',
|
|
617
|
+
positionals: [REF, { name: 'keys', required: true }, { name: 'seconds', required: true }],
|
|
618
|
+
options: { ...COMPUTER_LOOK },
|
|
619
|
+
examples: ['shard ws computer hold-key acme/demo shift 2'],
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
path: ['workspaces', 'computer', 'zoom'],
|
|
623
|
+
summary: 'Save an enlarged view of part of the workspace desktop (0.10.0+)',
|
|
624
|
+
description: 'The region <x0> <y0> <x1> <y1> (screen pixels, x0 < x1, y0 < y1), scaled up to the screen width. --json prints {out, format, width, height, bytes}.',
|
|
625
|
+
positionals: [REF, { name: 'x0', required: true }, { name: 'y0', required: true }, { name: 'x1', required: true }, { name: 'y1', required: true }],
|
|
626
|
+
options: {
|
|
627
|
+
out: { type: 'string', value: '<file>', description: 'Where to write the image (default zoom.png).' },
|
|
628
|
+
format: { type: 'string', value: '<png|jpeg>', description: 'Image format (default png).' },
|
|
629
|
+
quality: { type: 'string', value: '<1-100>', description: 'JPEG quality (default 80).' },
|
|
630
|
+
},
|
|
631
|
+
examples: ['shard ws computer zoom acme/demo 0 0 640 200 --out toolbar.png'],
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
path: ['workspaces', 'computer', 'cursor'],
|
|
635
|
+
summary: 'Print where the pointer is on the workspace desktop (0.10.0+)',
|
|
636
|
+
positionals: [REF],
|
|
637
|
+
options: {},
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
path: ['workspaces', 'computer', 'wait'],
|
|
641
|
+
summary: 'Wait on the workspace desktop, then optionally take a screenshot (0.10.0+)',
|
|
642
|
+
description: 'For a page or program that is still loading: shard ws computer wait <ws> 2 --screenshot after.png.',
|
|
643
|
+
positionals: [REF, { name: 'seconds', required: true }],
|
|
644
|
+
options: { ...COMPUTER_LOOK },
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
path: ['workspaces', 'computer', 'start'],
|
|
648
|
+
summary: 'Start the workspace desktop (0.10.0+)',
|
|
649
|
+
description: 'A no-op while it runs. The size applies to a start: 640x480 to 2560x1600 (default 1280x800).',
|
|
650
|
+
positionals: [REF],
|
|
651
|
+
options: {
|
|
652
|
+
width: { type: 'string', value: '<px>', description: 'Screen width (640-2560).' },
|
|
653
|
+
height: { type: 'string', value: '<px>', description: 'Screen height (480-1600).' },
|
|
654
|
+
},
|
|
655
|
+
},
|
|
656
|
+
{ path: ['workspaces', 'computer', 'stop'], summary: 'Stop the workspace desktop; its windows close (0.10.0+)', positionals: [REF], options: {} },
|
|
657
|
+
{
|
|
658
|
+
path: ['workspaces', 'computer', 'stream'],
|
|
659
|
+
summary: 'Print a private link to watch the workspace desktop live (0.10.0+)',
|
|
660
|
+
description: 'Starts the viewer in the workspace, exposes its port and signs a link to it (inbound ports). View only unless --interactive. Anyone with the link can open it until it expires: share it like a password. --stop ends every view instead. --json prints {url, expires_at, port, interactive}.',
|
|
661
|
+
positionals: [REF],
|
|
662
|
+
options: {
|
|
663
|
+
interactive: { type: 'boolean', description: 'Let the viewer use the mouse and keyboard.' },
|
|
664
|
+
ttl: { type: 'string', value: '<duration>', description: 'Lifetime of the link, 1m to 7d (default 24h).' },
|
|
665
|
+
stop: { type: 'boolean', description: 'End every view and close the viewer ports.' },
|
|
666
|
+
},
|
|
667
|
+
examples: ['open "$(shard ws computer stream acme/demo)"', 'shard ws computer stream acme/demo --stop'],
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
path: ['workspaces', 'computer', 'enable'],
|
|
671
|
+
summary: 'Switch computer use on for a workspace (0.10.0+)',
|
|
672
|
+
description: 'Tool tokens then carry the computer tool; the platform starts the desktop on the first computer call. --json prints {enabled, workspace, template, available}.',
|
|
673
|
+
positionals: [REF],
|
|
674
|
+
options: {},
|
|
675
|
+
},
|
|
676
|
+
{ path: ['workspaces', 'computer', 'disable'], summary: 'Switch computer use off for a workspace (0.10.0+)', positionals: [REF], options: {} },
|
|
677
|
+
{
|
|
678
|
+
path: ['workspaces', 'computer', 'inherit'],
|
|
679
|
+
summary: 'Let a workspace follow its template’s computer use switch (0.10.0+)',
|
|
680
|
+
positionals: [REF],
|
|
681
|
+
options: {},
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
path: ['templates', 'computer-use'],
|
|
685
|
+
summary: 'Switch computer use on or off for every workspace of one of your templates (0.10.0+)',
|
|
686
|
+
description: 'A workspace may override it (shard ws computer enable|disable). Platform templates keep it off: switch a workspace on instead.',
|
|
687
|
+
positionals: [SLUG, { name: 'on|off', required: true }],
|
|
688
|
+
options: {},
|
|
689
|
+
examples: ['shard templates computer-use my-desktop-agent on'],
|
|
690
|
+
},
|
|
413
691
|
{
|
|
414
692
|
path: ['files', 'read'],
|
|
415
693
|
summary: 'Print (or save) a file from a workspace',
|
|
@@ -785,6 +1063,7 @@ const GROUPS = {
|
|
|
785
1063
|
egress: 'Outbound network policies of the project and its workspaces (project API key)',
|
|
786
1064
|
volumes: 'Shared volumes: persistent storage attached to workspaces (project API key)',
|
|
787
1065
|
workspaces: 'Open, inspect and manage workspaces',
|
|
1066
|
+
'workspaces port': 'Serve ports of a workspace at private HTTPS URLs: expose, list, close, tokens, browser links and callback URLs (0.9.0+)',
|
|
788
1067
|
files: 'Read, write, list, search and patch files in a workspace',
|
|
789
1068
|
operations: 'Inspect and wait for lifecycle operations',
|
|
790
1069
|
executions: 'Fetch the results of file-first executions (the commands "shard ws exec" runs in file-first workspaces)',
|
|
@@ -811,12 +1090,15 @@ const ALIASES = {
|
|
|
811
1090
|
invite: 'invitations',
|
|
812
1091
|
invites: 'invitations',
|
|
813
1092
|
volume: 'volumes',
|
|
1093
|
+
ports: 'port',
|
|
814
1094
|
};
|
|
815
1095
|
/** Groups also reachable under `workspaces` (`shard workspaces files read ...` == `shard files read ...`). */
|
|
816
1096
|
const FOLDED = new Set(['files', 'operations', 'executions']);
|
|
817
1097
|
/** Canonical command words: aliases resolved, `workspaces files|operations|executions` folded to the top-level group. */
|
|
1098
|
+
/** Top-level shortcuts for a whole command path (0.10.0+): `shard exec` is `shard workspaces exec`. */
|
|
1099
|
+
const SHORTCUTS = { exec: ['workspaces', 'exec'] };
|
|
818
1100
|
export function normalizeWords(words) {
|
|
819
|
-
const w = words.
|
|
1101
|
+
const w = words.flatMap((x, i) => (i === 0 ? SHORTCUTS[x] : undefined) ?? [ALIASES[x] ?? x]);
|
|
820
1102
|
if (w[0] === 'workspaces' && w[1] !== undefined && FOLDED.has(w[1]))
|
|
821
1103
|
return w.slice(1);
|
|
822
1104
|
return w;
|
|
@@ -1111,7 +1393,7 @@ export const EXIT_CODE_HELP = [
|
|
|
1111
1393
|
];
|
|
1112
1394
|
/** The top help's sections: every command's group (first word) is in exactly one (args.test.ts checks). */
|
|
1113
1395
|
export const HELP_SECTIONS = [
|
|
1114
|
-
{ title: 'Account (a user session: shard auth login)', groups: ['auth', 'setup', 'env', 'orgs', 'projects', 'api-keys', 'members', 'invitations', 'billing', 'audit', 'account'] },
|
|
1396
|
+
{ title: 'Account (a user session: shard signup or shard auth login)', groups: ['signup', 'verify', 'auth', 'setup', 'env', 'orgs', 'projects', 'api-keys', 'members', 'invitations', 'billing', 'audit', 'account'] },
|
|
1115
1397
|
{ title: 'Workspaces (a project API key: SHARDFLUX_API_KEY, else the one shard setup saved)', groups: ['login', 'whoami', 'usage', 'workspaces', 'files', 'operations', 'executions', 'secrets', 'volumes', 'egress'] },
|
|
1116
1398
|
{ title: 'Templates (publish and archive use the session; the rest the API key)', groups: ['templates'] },
|
|
1117
1399
|
{ title: 'Other', groups: ['feedback', 'version'] },
|
package/dist/commands.d.ts
CHANGED
|
@@ -96,9 +96,23 @@ export declare function principal(ctx: Ctx): Promise<{
|
|
|
96
96
|
id: string;
|
|
97
97
|
key_id: string;
|
|
98
98
|
};
|
|
99
|
-
tool_permissions: ("git" | "exec" | "files" | "pty" | "process" | "browser")[];
|
|
99
|
+
tool_permissions: ("git" | "exec" | "files" | "pty" | "process" | "browser" | "computer")[];
|
|
100
100
|
}>;
|
|
101
101
|
/** The exit code `shard exec` returns for a finished command. */
|
|
102
102
|
export declare function execExitCode(r: Pick<RunResult, 'exitCode' | 'termSignal' | 'timedOut'>): number;
|
|
103
|
+
/**
|
|
104
|
+
* A lifecycle call a file-first workspace does not have (suspend, resume, fork, reset,
|
|
105
|
+
* save-as-template), refused before any request as the SDK's workspace handle does: NotSupportedForModeError, printed
|
|
106
|
+
* with its hint like the API's own refusal.
|
|
107
|
+
*/
|
|
108
|
+
/** `<port>` of the port commands: a TCP port number, 1-65535. */
|
|
109
|
+
export declare function portArg(text: string): number;
|
|
110
|
+
/** `--ttl <duration>` of port tokens and links: whole seconds within the API's bounds (undefined: the API's default). */
|
|
111
|
+
export declare function ttlSeconds(values: Values, b: {
|
|
112
|
+
option: string;
|
|
113
|
+
min: number;
|
|
114
|
+
max: number;
|
|
115
|
+
range: string;
|
|
116
|
+
}): number | undefined;
|
|
103
117
|
/** The project-key commands; handlers.ts adds the account plane's. */
|
|
104
118
|
export declare const KEY_HANDLERS: Record<string, Handler>;
|