@shardflux/cli 0.4.1 → 0.5.1
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 +226 -0
- package/README.md +517 -34
- package/dist/account-args.d.ts +13 -0
- package/dist/account-args.js +425 -0
- package/dist/account-commands.d.ts +18 -0
- package/dist/account-commands.js +1657 -0
- package/dist/args.d.ts +15 -3
- package/dist/args.js +292 -41
- package/dist/bin.js +5 -16
- package/dist/browser.d.ts +7 -0
- package/dist/browser.js +39 -0
- package/dist/commands.d.ts +69 -5
- package/dist/commands.js +440 -30
- package/dist/credentials.d.ts +77 -0
- package/dist/credentials.js +217 -0
- package/dist/errors.d.ts +63 -11
- package/dist/errors.js +114 -21
- package/dist/format.d.ts +89 -6
- package/dist/format.js +479 -10
- package/dist/handlers.d.ts +2 -0
- package/dist/handlers.js +7 -0
- package/dist/index.d.ts +19 -7
- package/dist/index.js +13 -6
- package/dist/input.d.ts +25 -0
- package/dist/input.js +167 -0
- package/dist/main.d.ts +16 -2
- package/dist/main.js +477 -31
- package/dist/update-check.d.ts +64 -0
- package/dist/update-check.js +128 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,232 @@
|
|
|
3
3
|
Every command and option the README shows is available from the version named here. Below 1.0, a minor release may
|
|
4
4
|
break compatibility; breaking changes are marked **Breaking**.
|
|
5
5
|
|
|
6
|
+
## 0.5.1 (not yet published; npm `latest` is 0.5.0)
|
|
7
|
+
|
|
8
|
+
### A command that could not start is never a silent exit
|
|
9
|
+
|
|
10
|
+
Production (2026-09-29): `shard ws exec <key> --cwd app -- ls` exited 1 and printed nothing on stdout or stderr. The
|
|
11
|
+
cell had ended the session `failed_to_start` (`working directory "app" is not a directory`).
|
|
12
|
+
|
|
13
|
+
- `shard ws exec` on a processful workspace: a command that could not start (a `--cwd` that is not a directory, a
|
|
14
|
+
program not on `PATH`, an unknown user) exits 6, as a failed file-first execution does, with the workspace's reason
|
|
15
|
+
and a hint on stderr: `error: The command could not start: working directory "/home/user/app" is not a directory
|
|
16
|
+
(exec_failed_to_start) [code=conflict source=cell]`, then `hint: --cwd must name a directory that exists in the
|
|
17
|
+
workspace, ...` (or the `PATH` hint). It exited 1 with no output. With `--json` the error document has
|
|
18
|
+
`details.reason` `exec_failed_to_start`, `details.error` and `details.session_id`. Through `@shardflux/sdk` 0.10.0
|
|
19
|
+
(`ExecStartError`).
|
|
20
|
+
- A relative `--cwd` is refused by the API before anything runs: 422 `invalid_cwd`, exit 2, and the message names the
|
|
21
|
+
absolute path it likely means (`use "/home/user/app"`). That holds for every CLI version once the cell refuses it.
|
|
22
|
+
- A session that ended without an exit code, timeout or signal (`lost`, when its host restarted) prints `exec session
|
|
23
|
+
<id> ended lost without an exit code: <reason>` on stderr; the exit code stays 1. `--json` adds `state` (and `error`
|
|
24
|
+
when the session has one) to the result.
|
|
25
|
+
- The file-first hint for `exec_failed_to_start` names `--cwd` when the reason is a working directory, instead of
|
|
26
|
+
always asking whether argv[0] is on `PATH`. `--cwd` help: an absolute path, default `/home/user`.
|
|
27
|
+
|
|
28
|
+
- A 402 `allowance_exhausted` and a spend-policy `version_mismatch` end without the `feedback:` line: they are billing
|
|
29
|
+
states whose hint names the next step, not problems to report.
|
|
30
|
+
### Opt-in overage with a spend cap
|
|
31
|
+
|
|
32
|
+
- `shard usage` prints an overage block from the summary's `spend_cap`: the state (`off`, `paused`, `accruing`,
|
|
33
|
+
`warning`, `reached`, ...), the spend cap, the charges of the cap with what is left, the date the cap is projected
|
|
34
|
+
to be reached, and a table of the units past each allowance (CPU-hours, RAM GiB-hours) with the billed units, rate
|
|
35
|
+
and amount. Allowances past `included` while overage is on show cap state `overage`; `allowance exhausted` names the
|
|
36
|
+
reason (`allowance_used`, `overage_paused`, `spend_cap_reached`). An API without overage prints no block.
|
|
37
|
+
- `shard billing overage` (signed in; owners and billing members change it): `status` (the default: the state, the
|
|
38
|
+
spend cap and its range up to the plan price, the rates), `on [--cap <dollars>]`, `cap <dollars>` (e.g. `9` or
|
|
39
|
+
`9.50`) and `off`, with `--if-version <n>` and `--json` (the API's spend policy). A refusal exits 2 with a hint that
|
|
40
|
+
names the bound (`spend_cap_above_plan_price`: the plan price; `spend_cap_below_minimum`; `spend_cap_below_charges`:
|
|
41
|
+
what overage already charged) or the next step (`overage_unavailable`, `spend_cap_required`); a 409
|
|
42
|
+
`version_mismatch` (also from `egress set --if-version`) exits 1 and names the current version.
|
|
43
|
+
- 402 `allowance_exhausted` gets a hint per `details.reason`: `allowance_used` (upgrade, or `shard billing overage on
|
|
44
|
+
--cap <dollars>`), `spend_cap_reached` (raise the cap with `shard billing overage cap <dollars>`, or upgrade),
|
|
45
|
+
`overage_paused` (a payment is past due: update the payment method, `shard billing portal --open`). The exit code
|
|
46
|
+
stays 1.
|
|
47
|
+
|
|
48
|
+
### Suspend when idle (contracts §20.6)
|
|
49
|
+
|
|
50
|
+
- `shard workspaces suspend <id|key> --when-idle <duration>` (30s to 1h): the workspace is suspended once it has been
|
|
51
|
+
idle that long, counted from the later of its last work and the request (suspend when idle, for the end of an agent
|
|
52
|
+
turn). A running command, an attached stream or a keepalive postpones it; the next tool call or a resume cancels it.
|
|
53
|
+
`--cancel-when-idle` cancels it. `--json` prints `{workspace, operation, suspend_request}`.
|
|
54
|
+
- `shard workspaces get` shows a pending request (`suspend when idle after N s idle, not before ...`).
|
|
55
|
+
|
|
56
|
+
## 0.5.0 (not yet published; npm `latest` is 0.4.1)
|
|
57
|
+
|
|
58
|
+
Needs `@shardflux/sdk` 0.9.0 or later.
|
|
59
|
+
|
|
60
|
+
### File search, patches and revisions (contracts §26)
|
|
61
|
+
|
|
62
|
+
- `shard files search <id|key> <path> <pattern>`: content search under a directory (or in one file), printed
|
|
63
|
+
grep-style (`path:line:column: text`, context lines as `path-line- text`). `--regex` (RE2), `-i`/`--ignore-case`,
|
|
64
|
+
repeatable gitignore-style `--include`/`--exclude` globs (`--exclude` replaces the default `.git`/`node_modules`
|
|
65
|
+
exclusions), `--max N` (1-5000, default 200). A search stopped early says why on stderr (`--max` matches, the 10 s
|
|
66
|
+
budget or 4 MiB of results); a suspended workspace searched on its disk is noted. `--json` prints
|
|
67
|
+
`{matches, truncated, stop_reason?, files_scanned, served_from}`.
|
|
68
|
+
- `shard files patch <id|key> <path>`: repeatable `--old T --new T` pairs (each must occur exactly once unless
|
|
69
|
+
`--replace-all`; applied in order, all or nothing) or `--content-file F|-` (UTF-8, up to 7 MiB), with
|
|
70
|
+
`--expected-revision <sha256|absent>`. Atomic and durable; prints the new revision (`--json`: the patch result).
|
|
71
|
+
- `shard files stat <id|key> <path> [--revision]`: one path's metadata; `--revision` adds the content's SHA-256, the
|
|
72
|
+
value `--expected-revision` takes.
|
|
73
|
+
- Hints for the new refusals: `revision_mismatch` (exit 1) names the current revision; `edit_not_found` and
|
|
74
|
+
`edit_ambiguous` (exit 2, like any `validation_failed`) name the `--old` by position; `host_capacity` says to retry
|
|
75
|
+
shortly (reads, searches and patches already retry it after `Retry-After`).
|
|
76
|
+
- A workspace on a host that predates search and patches (contracts §26.7, while the fleet is upgraded): `files
|
|
77
|
+
search` and `files patch` fail at once with 409 `conflict` `host_feature_unavailable` (exit 1, not retried, no
|
|
78
|
+
wake), with a hint naming `details.feature` and another way to do it now (`shard ws exec <id|key> -- grep -rn ...`
|
|
79
|
+
for a search; `files read` then `files write` for a patch); they work once the workspace runs on an upgraded host.
|
|
80
|
+
Such a host returns no revisions (`files stat --revision` prints none).
|
|
81
|
+
- All three take `--timing`. `files patch` wakes a suspended workspace like `files write`; `files search` and
|
|
82
|
+
`files stat` read its disk (below).
|
|
83
|
+
- `files read|ls|stat|search` of a suspended workspace are answered from its disk without resuming it (the state at
|
|
84
|
+
suspension), also on the first command after the suspend: every `shard` run fetches a new tool token, which the API
|
|
85
|
+
refused for a suspended workspace, so these commands used to resume it. Needs `@shardflux/sdk` 0.9.0 and an API
|
|
86
|
+
that issues tool tokens for suspended workspaces (contracts §26.4); with an older API they resume it as before.
|
|
87
|
+
Every other command still resumes it.
|
|
88
|
+
|
|
89
|
+
### File-first workspaces (contracts §29)
|
|
90
|
+
|
|
91
|
+
- `shard workspaces open --mode processful|file-first` (`file_first` too): a file-first workspace is a versioned file
|
|
92
|
+
tree with no VM between commands. It is ready at once, never suspended and always persistent. Without `--mode` a new
|
|
93
|
+
key is processful and an existing key keeps its mode. `--mode file-first` with `--lifetime session` is a usage error.
|
|
94
|
+
- `shard workspaces exec` on a file-first workspace runs the command as an execution: a fresh VM on the latest tree
|
|
95
|
+
revision; the files it changed under /home/user become the next revision. Its stdout and stderr are printed byte for
|
|
96
|
+
byte when it ended, and `shard` exits with its exit code (124 timed out, 128+N killed by signal N). An execution that
|
|
97
|
+
ended `failed` or `lost` published nothing: exit 6, with its reason and `retryable`
|
|
98
|
+
(`{"error": {"code": "execution_failed", ...}}` with `--json`).
|
|
99
|
+
- `-v` / `--verbose`: after the output, on stderr, the execution id, state and exit status, `base -> new` tree
|
|
100
|
+
revision, `replayed`, the timings and the changed paths (`A|M|D path`). On a processful workspace `-v` prints the
|
|
101
|
+
session id and exit status.
|
|
102
|
+
- `--json`: one object, the cell's result with stdout/stderr as text, plus `stdout_base64` / `stderr_base64` when a
|
|
103
|
+
stream is not UTF-8.
|
|
104
|
+
- `--execution-id <id>`: the execution's idempotency key (default a fresh `ex-<uuid>`): the same id with the same
|
|
105
|
+
command returns the recorded result instead of running it twice. `--output-limit <bytes>` (1-16777216, default
|
|
106
|
+
1 MiB per stream). Both are usage errors on a processful workspace.
|
|
107
|
+
- Ctrl-C stops waiting (exit 130; an execution cannot be canceled) and prints the `shard executions get` command
|
|
108
|
+
that fetches its result later.
|
|
109
|
+
- `shard executions get <id|key> <execution-id> [--wait D]` (also `shard workspaces executions get`; alias
|
|
110
|
+
`execution`): an execution's result, printed like `exec -v`. Exit: the command's code, 6 failed or lost, 5 while it
|
|
111
|
+
still runs (`--wait` waits up to D for it to end).
|
|
112
|
+
- `--if-revision <n>` on `shard files write` and `shard files patch`: the change applies only while the tree is at
|
|
113
|
+
revision n (`If-Match`). On a file-first workspace both print the tree revision after the change (`tree_revision`
|
|
114
|
+
with `--json`). A usage error on a processful workspace.
|
|
115
|
+
- `shard workspaces get` shows the mode and a file-first workspace's tree revision; `shard workspaces list` shows
|
|
116
|
+
`running (file-first)`.
|
|
117
|
+
- `shard workspaces suspend|resume|fork|reset|save-as-template` on a file-first workspace are refused without a
|
|
118
|
+
request (`not_supported_for_mode`, exit 1).
|
|
119
|
+
- Hints for the new refusals: `not_supported_for_mode` (either mode), `mode_mismatch`, `mode_not_available`,
|
|
120
|
+
`layout_unsupported` (file-first), `tree_revision_mismatch` (names the current revision to retry with),
|
|
121
|
+
`outside_tree_root`, `execution_in_progress` (names the running execution), `execution_id_reused`,
|
|
122
|
+
`no_execution_host`, and failed or lost executions (`exec_failed_to_start`, `lease_expired`, `host_unreachable`,
|
|
123
|
+
`host_restarted`, `tree_moved`, ...).
|
|
124
|
+
- The error line names `execution_id=` when the error is about an execution.
|
|
125
|
+
|
|
126
|
+
### Waking a suspended workspace is one request (contracts §22.6)
|
|
127
|
+
|
|
128
|
+
- Through `@shardflux/sdk` 0.9.0: a command on a suspended workspace (`ws exec`, `files ...`, `ws changes`) wakes it
|
|
129
|
+
with one held resume that returns the running workspace and the CLI's tool token, then runs (refused call, resume,
|
|
130
|
+
the command; before: also a wait, a view and a token request). An API without the held resume works as before.
|
|
131
|
+
- `--timing` shows the wake as one `request` phase `(held)`; a wake that runs out of time shows the hold, then the
|
|
132
|
+
states it saw after it (`request 1.00 s (held) → queued …`).
|
|
133
|
+
- `shard workspaces resume --wait` is one held request; its tool token is attributed to the CLI's agent label.
|
|
134
|
+
### The account plane (contracts §30)
|
|
135
|
+
|
|
136
|
+
Needs `@shardflux/sdk` 0.9.0 or later (`ShardfluxAccount`, `checkClientVersion`) and an API with CLI sessions
|
|
137
|
+
(contracts §30).
|
|
138
|
+
|
|
139
|
+
### Everything the web app does, from a terminal (docs/progress/account-cli.md §5)
|
|
140
|
+
|
|
141
|
+
- **Accounts and sign-in:** `shard auth register|verify-email|resend-verification|login|mfa|status|logout|sessions|step-up`,
|
|
142
|
+
`shard auth password change|reset|reset-confirm`, `shard auth email change|confirm`,
|
|
143
|
+
`shard auth totp enroll|confirm|disable|recovery-codes`. A sign-in is a CLI session (`sfu_...`, 30 days of use,
|
|
144
|
+
at most 90) on the SDK's `ShardfluxAccount`. Emailed links (or their tokens) are arguments; passwords never are:
|
|
145
|
+
they come from standard input (one line per secret) or a no-echo prompt on a terminal (a new password twice).
|
|
146
|
+
Two-factor sign-in takes `--code`/`--recovery-code` or the prompt; without either the pending sign-in is saved
|
|
147
|
+
and `shard auth mfa --code` completes it (`auth login` exits 4, `mfa_required`). After signing in `shard` prints
|
|
148
|
+
the user, whether the email is verified, the organizations and the next step.
|
|
149
|
+
- **`shard setup`:** uses (or creates) the organization ("<name>'s organization") and project ("Default"), creates
|
|
150
|
+
an API key with every tool (or `--tool`), saves it and checks it against the API. Idempotent: a working saved key
|
|
151
|
+
is kept (`--new-key` for another). `shard env [--shell sh|fish|powershell]` prints the saved key as exports.
|
|
152
|
+
- **Organizations, projects, keys, members:** `shard orgs list|create|get|use|workspaces|export|deletion|delete` (`workspaces`: every project's workspaces, as the dashboard lists them),
|
|
153
|
+
`shard projects list|create|get|use`, `shard api-keys list|create|revoke` (the new key is printed once, alone
|
|
154
|
+
on stdout, or saved with `--save`), `shard members list|set-role|remove`,
|
|
155
|
+
`shard invitations list|create|revoke|accept`, `shard templates publish|archive <slug>@<version>`. Default
|
|
156
|
+
organization and project: `--org`/`--project` (id or slug), else the saved default (`orgs use`, `projects use`,
|
|
157
|
+
`setup`), else the only one; with several the usage error lists them.
|
|
158
|
+
- **Billing:** `shard billing plans` (public, no sign-in), `status`, `upgrade <plan> [--open] [--wait] [--timeout]`
|
|
159
|
+
(Stripe Checkout URL; `--wait` exits 0 once the webhook activated the subscription, 6 when the checkout expired or
|
|
160
|
+
was canceled, 5 on `--timeout`, default 15m; an organization with a subscription gets the portal URL instead),
|
|
161
|
+
`portal [--open]`, `invoices`, `alerts [--set 50,80,100 | --clear]`.
|
|
162
|
+
- **Usage:** `shard usage --estimate` (the bill so far, projected allowance use), `--series` (usage over time;
|
|
163
|
+
`--from`, `--to`, `--granularity hour|day`, `--meter`) and `--workspace <id|key>` (one workspace's usage), as the
|
|
164
|
+
dashboard's usage page shows; `shard usage` alone is the summary as before.
|
|
165
|
+
- **Audit, exports, deletion:** `shard audit list|export`, `shard account status|export|delete|cancel-deletion`.
|
|
166
|
+
Exports are downloaded to 0600 files (`./<kind>-export-<id>.json` by default) and never overwrite without `--force`.
|
|
167
|
+
- **Egress and volumes** with the project key: `shard egress get|set|history|clear`,
|
|
168
|
+
`shard volumes list|create|get|delete|attachments|attach|detach`.
|
|
169
|
+
- **Step-up:** a command that answers 403 `step_up_required` asks for the password (and a code with two-factor
|
|
170
|
+
authentication) on a terminal and retries once; without a terminal it exits 4 with the hint
|
|
171
|
+
`printf '%s\n' "$PASSWORD" | shard auth step-up`.
|
|
172
|
+
- Destructive commands need `--yes`, and the typed `--confirm` value where the API asks for one (organization slug,
|
|
173
|
+
your email).
|
|
174
|
+
- New exit-code cases: 4 for `step_up_required`, `mfa_required`, `email_unverified`, `invalid_credentials`,
|
|
175
|
+
`token_invalid`; 5 and 6 for `billing upgrade --wait` (`timeout`, `checkout_ended`).
|
|
176
|
+
|
|
177
|
+
### The credentials file (**behaviour change**)
|
|
178
|
+
|
|
179
|
+
Before 0.5.0 `shard` stored nothing. It now keeps `credentials.json` in its config directory
|
|
180
|
+
(`$SHARDFLUX_CONFIG_DIR`, else `$XDG_CONFIG_HOME/shardflux`, else `~/.config/shardflux`, `%APPDATA%\shardflux` on
|
|
181
|
+
Windows): directory 0700, file 0600, atomic writes, one profile per API URL with the session, the default
|
|
182
|
+
organization and project, and the saved API key. It is written only by `auth login`/`auth mfa`, `setup`,
|
|
183
|
+
`api-keys create --save`, `orgs use`/`projects use`/`invitations accept --use` and session renewals. Environment
|
|
184
|
+
variables still win: `SHARDFLUX_API_KEY` over the saved key, the new `SHARDFLUX_SESSION_TOKEN` over the saved
|
|
185
|
+
session. A corrupt file is a usage error naming it and is moved aside (never overwritten) before a new one is
|
|
186
|
+
written. A saved session the API rejects is removed with a hint to sign in again. `shard login` (the key check) is
|
|
187
|
+
unchanged and still stores nothing.
|
|
188
|
+
|
|
189
|
+
### Version check
|
|
190
|
+
|
|
191
|
+
- `shard` checks `GET /v1/client-versions` at most once a day per API URL (cached in
|
|
192
|
+
`<config dir>/update-check.json`), in parallel with the command, and prints one line on stderr when it is outdated
|
|
193
|
+
or no longer supported. A late answer is skipped (at most ~300 ms of waiting), the exit code never changes, and
|
|
194
|
+
nothing is printed after a `--json` failure. Off with `SHARDFLUX_NO_UPDATE_CHECK=1` or `NO_UPDATE_NOTIFIER=1`. The
|
|
195
|
+
SDK's own check is off inside `shard` (`versionCheck: false`).
|
|
196
|
+
- `shard version` shows the update status; `shard version --check` asks now; `--json` adds
|
|
197
|
+
`update: {package, current, status, latest, minimum_supported, upgrade_command, checked_at}`.
|
|
198
|
+
- `main({ distribution: { package, version } })` (exported): the `shardflux` npm bundle runs the CLI under its own
|
|
199
|
+
name, so its users are told to update `shardflux`.
|
|
200
|
+
|
|
201
|
+
### Also
|
|
202
|
+
|
|
203
|
+
- `redact()` removes user session tokens (`sfu_...`) from error output, as it does API keys.
|
|
204
|
+
- `--password`, `--token`, `--key`, `--secret`, `--api-key` stay refused; the messages name the new sources.
|
|
205
|
+
- The top help starts with the no-browser path and groups commands by the credential they use; `shard <group>`
|
|
206
|
+
and `shard auth totp` (a sub-group) list their commands.
|
|
207
|
+
|
|
208
|
+
### Feedback straight to the founder (needs an API with POST /v1/feedback)
|
|
209
|
+
|
|
210
|
+
- `shard feedback [--category bug|confusing|missing|idea|praise|other] [--workspace W] [--request-id ID]
|
|
211
|
+
[--error-code CODE] [--command TEXT] [--from-file F|-] <message...>` sends feedback to the Shardflux founder by
|
|
212
|
+
email. The message is the remaining words (no quotes needed unless the shell needs them) or `--from-file` (`-`:
|
|
213
|
+
standard input, for logs). It is checked before any request (1-8000 characters, a known category, the context
|
|
214
|
+
bounds). The context carries `client: shard-cli/0.5.0` and, unless it is the default `cli`, the agent label as
|
|
215
|
+
`agent`. Output: one line with the feedback id, or `Already received` for a duplicate within 24 hours; `--json`:
|
|
216
|
+
`{id, received_at, duplicate}`. It sends with the project API key, or, when none is configured, with the signed-in
|
|
217
|
+
session (`SHARDFLUX_SESSION_TOKEN` or the saved one). Without either, or when rate limited, the hint says how to
|
|
218
|
+
continue or to email shardflux@heliosone.fi.
|
|
219
|
+
- `shard --help` opens with a Feedback section, and `shard feedback --help` explains when to use each category: coding
|
|
220
|
+
agents are asked to send short feedback while they work, the moment something fails, confuses or is missing, and to
|
|
221
|
+
pass on (paraphrased, without private data) what their user is frustrated about or asked for that Shardflux could not
|
|
222
|
+
do, telling the user they sent it.
|
|
223
|
+
- A failure ends with
|
|
224
|
+
`feedback: shard feedback --category bug --request-id <id> --error-code <code> "<what you expected>"`; with `--json`
|
|
225
|
+
the error object gains a sibling `"feedback"` field holding that command. Existing fields are unchanged. Not for
|
|
226
|
+
the expected flow: usage and validation errors, Ctrl-C, a missing or refused credential, a sign-in or step-up to
|
|
227
|
+
finish, a wait that gave up, a checkout nobody paid, refusals whose hint names the next step (a stale revision, an
|
|
228
|
+
edit that does not match, a mode the workspace lacks, a reused execution id), and `shard feedback` itself.
|
|
229
|
+
- The positional usage of `shard feedback` is shown as `<message...>`; `--agent-label` also names the reporting agent.
|
|
230
|
+
|
|
231
|
+
|
|
6
232
|
## 0.4.1 (2026-09-28)
|
|
7
233
|
|
|
8
234
|
Needs `@shardflux/sdk` 0.8.0 or later. No command changes: the SDK's 0.8.0 is a types-only release (its provider tool
|