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