@shardflux/cli 0.18.0-next.5 → 0.18.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 +61 -8
- package/README.md +92 -33
- package/dist/account-args.js +5 -3
- package/dist/account-commands.d.ts +4 -1
- package/dist/account-commands.js +104 -14
- package/dist/account-pool.d.ts +31 -0
- package/dist/account-pool.js +313 -0
- package/dist/agent-setup.d.ts +38 -0
- package/dist/agent-setup.js +116 -0
- package/dist/agent-target-commands.js +10 -1
- package/dist/agent-targets.d.ts +11 -0
- package/dist/agent-targets.js +22 -4
- package/dist/args.d.ts +3 -1
- package/dist/args.js +50 -5
- package/dist/claude-cloud-login.d.ts +11 -0
- package/dist/claude-cloud-login.js +49 -39
- package/dist/cli-proxy-hub.d.ts +26 -1
- package/dist/cli-proxy-hub.js +60 -4
- package/dist/commands.d.ts +3 -0
- package/dist/commands.js +7 -3
- package/dist/conversation-commands.d.ts +5 -0
- package/dist/conversation-commands.js +8 -2
- package/dist/conversations.d.ts +9 -0
- package/dist/desktop-linux.js +6 -5
- package/dist/filesystem-commands.d.ts +12 -2
- package/dist/filesystem-commands.js +46 -18
- package/dist/git-remote-bin.js +0 -0
- package/dist/handlers.js +2 -1
- package/dist/input.d.ts +4 -2
- package/dist/input.js +6 -3
- package/dist/main.js +19 -8
- package/dist/menubar.js +1 -1
- package/dist/t3-asar.d.ts +12 -2
- package/dist/t3-asar.js +14 -5
- package/dist/t3-launch.js +4 -1
- package/dist/t3-linux.d.ts +12 -13
- package/dist/t3-linux.js +81 -87
- package/dist/t3-mode.d.ts +4 -3
- package/dist/t3-mode.js +15 -14
- package/dist/t3-version.d.ts +8 -0
- package/dist/t3-version.js +42 -0
- package/package.json +21 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,70 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.18.0 (not yet published)
|
|
4
|
+
|
|
5
|
+
- A conversation that needs you says why: `shard conversations list` adds it as a fifth column, `shard conversations
|
|
6
|
+
get` prints it after the branch, and `shard agents list` shows it as the session's LAST MESSAGE (one line, cut to
|
|
7
|
+
fit). `--json` carries the API's `question`; `agents list --json` adds it to the session's row.
|
|
8
|
+
|
|
9
|
+
- `shard machine save` and `shard template save` say when the save put software installed under the home into the
|
|
10
|
+
image, linked back at the same paths: `machine: version 4 saved; 1 large tool folder went into the machine image
|
|
11
|
+
(~/.dotnet); they keep working at the same paths`. `--json` carries `moved_to_image`.
|
|
12
|
+
- Setting up pooled accounts creates the hosted CLIProxyAPI hub on codex-connector 5, or upgrades it in place (its
|
|
13
|
+
logins and settings stay), whose VM port runs the account pool router; it gives the hub the API URL and a hub token
|
|
14
|
+
and turns on CLIProxyAPI's rate-limit header passthrough. Hubs without pooled accounts stay as they are.
|
|
15
|
+
- The Shardflux app for Ubuntu 24.04 (x64 and arm64): in a desktop session, bare `shard` opens it instead of the
|
|
16
|
+
terminal onboarding. It ships as the optional `@shardflux/desktop-linux-x64` / `-arm64` package (0.1.0), installs
|
|
17
|
+
with no npm install scripts, adds Shardflux to the app grid and starts at login. It has the Mac app's surfaces: the
|
|
18
|
+
first run, the top-bar panel (conversations, approvals, files, updates; a right click opens a small menu), the
|
|
19
|
+
launcher on Alt+Shift+Space (an X11 shortcut, or a GNOME custom shortcut it adds on Wayland), Settings, device and
|
|
20
|
+
sign-in approvals, notifications with actions, file downloads and self-update. `shard menubar start|stop|status`
|
|
21
|
+
and `--login on|off` manage it on Linux as on macOS. Without the desktop libraries, `shard` keeps the terminal
|
|
22
|
+
onboarding and says how to get the window.
|
|
23
|
+
- `shard agents accounts`: your Claude and ChatGPT/Codex accounts in one list, each with its plan, status (Signed in,
|
|
24
|
+
Low, Limited, Expired), the account threads use, and its usage windows (Claude 5-hour and weekly, Codex primary and
|
|
25
|
+
secondary) with when each resets. `shard agents accounts usage` draws every window as a bar. `shard agents accounts
|
|
26
|
+
add claude|codex` signs in another account in a cloud VM (`--api-key-stdin` adds an API key instead),
|
|
27
|
+
`remove <account>` removes one and `move <account> up|down` changes its place. Accounts are named by
|
|
28
|
+
`claude:<n>`/`codex:<n>`, email, label or id; `shard accounts …` works too. `--json` everywhere (SDK 0.24.0).
|
|
29
|
+
- `shard agents targets --json` carries an `accounts` block: the same list, for the menu bar.
|
|
30
|
+
|
|
31
|
+
## 0.17.1 (not yet published)
|
|
4
32
|
|
|
5
|
-
- Linux (Ubuntu 24.04, x64 and arm64): bare `shard` opens the Shardflux app in a graphical session. The optional CPU package installs without npm install scripts, adds Shardflux to the app grid, and starts at login. Headless sessions keep terminal onboarding. The systemd user helper keeps the live twin, files and conversation mirrors running; `shard device requests`, `shard device approve <id>` and `shard device deny <id>` handle local approvals.
|
|
6
|
-
- The Ubuntu desktop app includes the custom tray panel, launcher capture and project/model menus, all Settings panes, local device and credential approval panels, notifications with actions, file downloads and packaged-app updates. `shard device approve --always` remembers matching in-project requests; outside-folder requests remain one-time approvals.
|
|
7
33
|
- T3 Code on Linux: `shard` finds T3 Code installed from its .deb or AppImage (and AppImageLauncher, Gear Lever,
|
|
8
34
|
flatpak and snap entries), registers the Shardflux provider in it, shows it in onboarding, and opens it from its
|
|
9
35
|
desktop entry. `shard agents new --in t3`, `shard agents open t3` and `shard agents targets --open-in` work as on
|
|
10
36
|
macOS: a T3 build with ACP providers starts each thread on its Shardflux provider in a cloud VM of its own, and T3
|
|
11
|
-
Code 0.0.45 opens the project VM as an SSH environment. `shard agents targets --json` reports it under `t3
|
|
12
|
-
|
|
13
|
-
macOS.
|
|
14
|
-
|
|
37
|
+
Code 0.0.45 opens the project VM as an SSH environment. `shard agents targets --json` reports it under `t3`, and
|
|
38
|
+
`--open-in claude=t3,codex=t3` makes T3 Code where new conversations open. The Shardflux provider is also
|
|
39
|
+
recognized in the latest T3 nightlies on macOS.
|
|
40
|
+
- Setting Shardflux up with a coding agent: `shard setup --guide` prints the one question an agent asks its user first
|
|
41
|
+
(a SaaS platform whose product runs VMs for its customers, or their personal cloud coding agents) and the ordered
|
|
42
|
+
steps of both, with every command; `--json` gives them as a list. Local only, so it never waits. Bare `shard`
|
|
43
|
+
without a terminal prints the same guide instead of the full help (macOS) or the sign-in line (Linux).
|
|
44
|
+
- `shard auth login --browser --no-wait` prints the link and the code and returns; the next `shard auth login
|
|
45
|
+
--browser` waits for that same request while it is valid (`"resumed": true` on its `open` event), so an agent whose
|
|
46
|
+
command is cut off by its tool's time limit runs it again and the person approves one code. The request is kept in
|
|
47
|
+
`browser-login.json` (0600) in the config directory until it is approved, refused or expired.
|
|
48
|
+
- `shard machine open` creates or resumes your machine VM without attaching to it and prints its workspace key: an
|
|
49
|
+
agent installs with `shard ws exec <key>`, writes dotfiles and secret files with `shard files write <key> <path>
|
|
50
|
+
--from -`, then `shard machine save --wait`. `--json` adds the workspace and the next commands.
|
|
51
|
+
- A coding agent's shell (`CLAUDECODE`, `CODEX_SANDBOX`, `CODEX_THREAD_ID`, `CURSOR_AGENT` or `GEMINI_CLI` set) is
|
|
52
|
+
treated as no terminal, also when it is a PTY: bare `shard` prints the guide instead of the command center, `shard
|
|
53
|
+
./` and `shard machine` do not attach, the Claude cloud sign-in says to run it in the user's own terminal, and
|
|
54
|
+
prompts take their non-terminal path (`signup` without `--accept-terms` stops with `terms_not_accepted`).
|
|
55
|
+
- `shard ./` without a terminal (and without `--json`) is a usage error (exit 2) that says to run it in the user's own
|
|
56
|
+
terminal or to start the conversation detached with `--json --prompt`; before, it printed its help and exited 0.
|
|
57
|
+
- `shard setup` without a session and without a terminal prints the guide and exits 4. Sign-in hints name `shard auth
|
|
58
|
+
login --browser` (and `shard signup` for a new account) instead of a password sign-in. After `shard setup` and
|
|
59
|
+
`shard auth login`, the next step names both paths; `shard setup --json` adds `next_steps: {saas, personal}` (`next`
|
|
60
|
+
is unchanged).
|
|
61
|
+
|
|
62
|
+
## 0.17.0 (2026-10-10)
|
|
63
|
+
|
|
64
|
+
- Linux (Ubuntu 24.04, x64 and arm64): bare `shard` signs in and connects Claude/Codex in the terminal. The
|
|
65
|
+
systemd user helper keeps the live twin, files and conversation mirrors running; `shard device requests`,
|
|
66
|
+
`shard device approve <id>` and `shard device deny <id>` handle local approvals. Desktop launches open a terminal;
|
|
67
|
+
macOS keeps its extra menu bar app.
|
|
15
68
|
- A Codex project opens in T3 Code without a Claude sign-in (T3 shows Claude as signed out, and says how to sign in), and `--json` names the T3 Connect sign-in `shard` started for the phone (`t3_link.sign_in`, or `t3_link.needs_login` when this computer has no session).
|
|
16
69
|
- A conversation settles when its turn ends (`done` or `unresolved` right away) and its VM takes the next message.
|
|
17
70
|
`shard agents open`, `shard ./ --resume` and ACP reattach to that VM instead of resuming the conversation into a new
|
|
@@ -67,7 +120,7 @@
|
|
|
67
120
|
active conversation and hears the finished turn the moment the conversation reports it (no polling every second).
|
|
68
121
|
Conversations that finish together for the same branch land in one go, in the order they finished.
|
|
69
122
|
|
|
70
|
-
## 0.16.0 (
|
|
123
|
+
## 0.16.0 (2026-10-10)
|
|
71
124
|
|
|
72
125
|
- Cloud sessions are named for the work: `shard ./` starts the agent with the repository or folder name and the first
|
|
73
126
|
line of your prompt, so claude.ai, the Claude app and its notifications show `Add CSV export · todo-app`
|
package/README.md
CHANGED
|
@@ -50,10 +50,18 @@ Bulk transfers batch writes automatically. Active transfers retain their byte po
|
|
|
50
50
|
|
|
51
51
|
## Install
|
|
52
52
|
|
|
53
|
+
Setting Shardflux up with a coding agent (Claude Code, Codex, Cursor, ...)? See [For AI agents](#for-ai-agents): the
|
|
54
|
+
agent asks one question first, then runs the steps for a SaaS platform or for your personal cloud coding agents.
|
|
55
|
+
|
|
53
56
|
Linux (Ubuntu 24.04, x64 and arm64) and macOS are supported. On Linux, run `shard` to sign in and
|
|
54
57
|
connect Claude, Codex or both (0.17.0+), then run `shard ./` in your project to attach Claude Code or Codex in place. Sign-in opens your browser;
|
|
55
58
|
on a headless terminal, follow the displayed URL and device code. `--accept-terms` accepts the terms notice.
|
|
56
59
|
|
|
60
|
+
In a desktop session, `shard` opens the Shardflux app for this (0.18.0+): guided sign-in, a top-bar panel for your
|
|
61
|
+
conversations, a launcher on Alt+Shift+Space and Settings. It installs with the CLI (the optional
|
|
62
|
+
`@shardflux/desktop-linux-x64` or `-arm64` package), appears in the app grid and starts at login;
|
|
63
|
+
`shard menubar start|stop|status` and `--login on|off` manage it as on macOS.
|
|
64
|
+
|
|
57
65
|
The Linux helper starts automatically after setup as `~/.config/systemd/user/shardflux-helper.service`
|
|
58
66
|
and restarts after a CLI update. It keeps the live twin, `~/Shardflux` files and conversation history in sync.
|
|
59
67
|
Use `shard device requests`, `shard device approve <id>` or `shard device deny <id>` for local approvals;
|
|
@@ -217,38 +225,62 @@ npm test 2>&1 | tail -n 60 | shard feedback --category bug --workspace acme/demo
|
|
|
217
225
|
|
|
218
226
|
## For AI agents
|
|
219
227
|
|
|
220
|
-
`shard` is built to be driven by an agent: no
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
228
|
+
`shard` is built to be driven by an agent: no prompts and no full-screen views when standard input is not a terminal
|
|
229
|
+
or the shell is a coding agent's (Claude Code, Codex, Cursor, Gemini CLI; 0.17.1+), `--json` on every command, secrets
|
|
230
|
+
only on standard input, and documented exit codes.
|
|
231
|
+
|
|
232
|
+
**Ask your user one question first:** is Shardflux for a **SaaS platform** (their product runs VMs for its own
|
|
233
|
+
customers through the API, SDK or MCP) or for their **personal setup** (their own cloud coding agents: each Claude or
|
|
234
|
+
Codex conversation gets its own VM)? `shard setup --guide` prints both paths with every command, `--json` as a list
|
|
235
|
+
(0.17.1+); so does `shard` in a shell without a terminal. The full walk-through:
|
|
236
|
+
[Set up Shardflux with your coding agent](https://docs.shardflux.dev/guides/agent-setup).
|
|
237
|
+
|
|
238
|
+
1. **Account, for both.** Show your user the [Terms of Service](https://shardflux.dev/terms) and the
|
|
239
|
+
[Privacy Policy](https://shardflux.dev/privacy); once they agree, `shard signup --accept-terms --json`. With the
|
|
240
|
+
Codex CLI signed in with ChatGPT on the machine it signs up (or signs in) with that login and runs `shard setup`:
|
|
241
|
+
an organization, a project and an API key, saved. Without a Codex login, or for an account they already have:
|
|
242
|
+
`shard auth login --browser --no-wait --json` prints the link and the code for your user and returns (0.17.1+);
|
|
243
|
+
`shard auth login --browser --json` then waits for that same request (run it again if your tool's time limit cuts
|
|
244
|
+
it off), and `shard setup --json` saves the key. With two-factor authentication a password sign-in exits 4 with
|
|
245
|
+
`mfa_required`: ask for the code, then `shard auth mfa --code <code>`.
|
|
246
|
+
|
|
247
|
+
**SaaS platform** (no agent sign-ins, menu bar or machine):
|
|
248
|
+
|
|
249
|
+
2. `eval "$(shard env)"` exports `SHARDFLUX_API_KEY` for the SDKs, the MCP server and your product's server. Keep it in
|
|
250
|
+
server-side secrets.
|
|
251
|
+
3. Integrate with `@shardflux/sdk`, the Python SDK `shardflux`, the HTTP API or the MCP server. Your customers'
|
|
252
|
+
workspaces start from a template: `shard templates build template.yaml`. `shard exec <key> --template default --
|
|
253
|
+
<cmd>` tries a workspace from here (0.10.0+).
|
|
254
|
+
4. A paid plan: `shard billing upgrade <plan> --json` prints the Stripe Checkout URL; give it to your user, then
|
|
255
|
+
`shard billing upgrade <plan> --wait` (or `shard billing status`) until it is active.
|
|
256
|
+
|
|
257
|
+
**Personal setup** (their own cloud coding agents):
|
|
258
|
+
|
|
259
|
+
2. **Connect Claude and Codex.** Claude: your user runs `shard agents credentials login claude` in their own terminal,
|
|
260
|
+
once (a claude.ai link and a code). Codex: `codex login` on this computer. Then
|
|
261
|
+
`shard setup --inspect --connect --json --apps claude,codex` (0.15.0+) checks both live, copies the Codex login and
|
|
262
|
+
starts the account's Codex remote device.
|
|
263
|
+
3. **Build the machine** every conversation starts from. Ask your user what it should carry: languages and runtimes,
|
|
264
|
+
CLIs and tools, dotfiles and shell, secrets and credentials, editor and agent config. Then
|
|
265
|
+
`shard machine open --json` (0.17.1+) prints the machine VM's key; install with
|
|
266
|
+
`shard ws exec <key> -- bash -lc '...'`, write dotfiles and secret files with
|
|
267
|
+
`shard files write <key> <path> --from -` (contents on standard input), and `shard machine save --wait --json`.
|
|
268
|
+
4. **Set up the project.** In its folder, `shard ./ --json --prompt "Set up this project and run its tests"` starts a
|
|
269
|
+
conversation in its own VM (`shard ./ codex --json ...` for Codex); setup installs the dependencies and saves the
|
|
270
|
+
project template. `shard conversations wait <conversation-id> --timeout 90` follows it (run it again while it says
|
|
271
|
+
Still working), and `shard template --json` shows the saved version. Project secrets:
|
|
272
|
+
`shard secrets import --from <hsec|1password|bitwarden|keychain> NAME`.
|
|
273
|
+
5. **Hand over.** Your user runs `shard ./` in their own terminal. Claude conversations continue on claude.ai and in the
|
|
274
|
+
Claude app; Codex threads in the Codex app, on the web and on the phone.
|
|
275
|
+
|
|
276
|
+
Any time: `shard setup --json` is idempotent, and sensitive actions (exports, deletions, two-factor and email changes)
|
|
277
|
+
need a recent step-up: `printf '%s\n' "$PASSWORD" | shard auth step-up` (without a terminal the command fails with
|
|
278
|
+
`step_up_required`, exit 4, and the hint names this command). Send `shard feedback` as you work, the moment something
|
|
279
|
+
fails, confuses you or is missing, or your user asks for an improvement (see
|
|
280
|
+
[Feedback](#feedback-agents-use-this-while-you-work)).
|
|
281
|
+
|
|
282
|
+
What a person does: agreeing to the terms, approving the browser sign-in, the Claude sign-in in their terminal,
|
|
283
|
+
entering a card in Stripe Checkout and the authenticator app's codes.
|
|
252
284
|
|
|
253
285
|
## Accounts and sign-in (0.5.0+)
|
|
254
286
|
|
|
@@ -256,6 +288,7 @@ What a person does: entering a card in Stripe Checkout, the authenticator app's
|
|
|
256
288
|
shard signup [--email you@example.com] [--name "Ada Lovelace"] [--no-codex] [--no-setup] [--accept-terms] # 0.9.0+
|
|
257
289
|
shard verify [<code>] # 0.9.0+: emails a 6-digit code, then confirms it
|
|
258
290
|
shard auth login --browser [--no-open] # 0.15.0+: approve this computer on the sign-in page
|
|
291
|
+
shard auth login --browser --no-wait # 0.17.1+: print the link and code, return; the next --browser run waits for it
|
|
259
292
|
shard auth login --codex [--accept-terms] # 0.9.0+: sign in with the Codex login on this machine
|
|
260
293
|
printf '%s\n' "$PASSWORD" | shard auth register --email you@example.com [--name "Ada Lovelace"] [--accept-terms]
|
|
261
294
|
shard auth verify-email '<link from the email>' # or just the token in it
|
|
@@ -334,6 +367,9 @@ shard auth totp recovery-codes
|
|
|
334
367
|
3. an API key with every workspace tool, `computer` included (0.15.1+; `--tool` repeatable to narrow it), named
|
|
335
368
|
`shard-cli <hostname>` (`--key-name`), saved in the credentials file and checked against the API.
|
|
336
369
|
|
|
370
|
+
`shard setup --guide` (0.17.1+) prints how to set Shardflux up with a coding agent: the question to ask first (a SaaS
|
|
371
|
+
platform, or the user's own cloud coding agents) and the ordered steps of both; `--json` gives them as a list.
|
|
372
|
+
|
|
337
373
|
It is idempotent: a saved key that still works is kept (`--new-key` makes a new one). A saved key from an earlier
|
|
338
374
|
`shard setup` (every tool but `computer`) is replaced with one that has every tool (0.15.1+); the old key keeps working
|
|
339
375
|
until you revoke it. It prints what
|
|
@@ -1283,9 +1319,13 @@ New project folders are ready to use: `shard ./` and `shard agents new` initiali
|
|
|
1283
1319
|
Your **machine** carries credentials, tools, dotfiles, logins and agent config; the project's **template** carries
|
|
1284
1320
|
toolchains, dependencies, services and project secrets. Both are private filesystem templates and include secrets
|
|
1285
1321
|
as ordinary files. Browser logins and Claude/Codex config belong to the machine. Set up tools and secrets normally inside the VM;
|
|
1286
|
-
your agent uses the same save/rollback commands there.
|
|
1322
|
+
your agent uses the same save/rollback commands there. An agent working from your computer builds the machine with
|
|
1323
|
+
`shard machine open` (0.17.1+): it creates or resumes the machine VM without attaching and prints its key for
|
|
1324
|
+
`shard ws exec` and `shard files write`. Every agent starts from both. Save or roll back with `shard machine save|rollback` and
|
|
1287
1325
|
`shard template save|rollback`; changed files reach running agents live, software at the next start.
|
|
1288
1326
|
`shard machine save --wait` and `shard template save --wait` return once the new version is ready (0.13.3+).
|
|
1327
|
+
Software installed under the home goes into the saved image, linked back at the same path; the save line names those
|
|
1328
|
+
folders, and `--json` carries `moved_to_image` (0.18.0+).
|
|
1289
1329
|
`shard ./ codex` (or `claude`; `--codex` and `--claude` also work, 0.14.4+) starts that agent directly; `shard agents targets <project>/<agent>` lists each
|
|
1290
1330
|
connection it configured and the file it is in (0.13.3+).
|
|
1291
1331
|
|
|
@@ -1321,6 +1361,25 @@ on it with `DISPLAY=:1`, detached so it outlives the command, for example
|
|
|
1321
1361
|
|
|
1322
1362
|
Volume lists and details (0.14.0+) show `kind`. Project spaces show their measured storage and a platform-managed quota.
|
|
1323
1363
|
|
|
1364
|
+
### Claude and ChatGPT/Codex accounts (0.18.0+)
|
|
1365
|
+
|
|
1366
|
+
`shard agents accounts` lists your Claude and ChatGPT/Codex accounts with their plan, status, the account threads use
|
|
1367
|
+
and how much of each usage window is left:
|
|
1368
|
+
|
|
1369
|
+
```
|
|
1370
|
+
Claude
|
|
1371
|
+
claude:1 marc@example.com (Max, in use) · Signed in
|
|
1372
|
+
5-hour 43% (resets in 2h 10m) · Weekly 18% (resets in 4d 8h)
|
|
1373
|
+
ChatGPT / Codex
|
|
1374
|
+
codex:1 marc@example.com (Pro, in use) · Signed in
|
|
1375
|
+
5-hour 12% (resets in 3h 30m) · Weekly 35% (resets in 4d 23h)
|
|
1376
|
+
```
|
|
1377
|
+
|
|
1378
|
+
`shard agents accounts usage` shows every window as a bar. `shard agents accounts add claude` (or `codex`) signs in
|
|
1379
|
+
another account in a cloud VM; `pbpaste | shard agents accounts add claude --api-key-stdin` adds an API key.
|
|
1380
|
+
`shard agents accounts move claude:2 up` changes an account's place and `shard agents accounts remove claude:2`
|
|
1381
|
+
removes it. `--json` prints the API's account list.
|
|
1382
|
+
|
|
1324
1383
|
## Conversations
|
|
1325
1384
|
|
|
1326
1385
|
From 0.14.0, `shard conversations list|get|send|wait|land|move` manages project conversations. `shard c` is the short form. Conversations retain their branch and transcript as their VM binding changes.
|
package/dist/account-args.js
CHANGED
|
@@ -103,12 +103,13 @@ export const ACCOUNT_COMMANDS = [
|
|
|
103
103
|
browser: { type: 'boolean', description: 'Sign in in the browser: open the sign-in page, approve this computer there (0.15.0+). An account created there agrees to the terms on the sign-up page, so --browser needs no --accept-terms.' },
|
|
104
104
|
open: { type: 'boolean', description: 'With --browser: open the page in the default browser (default; --no-open only prints the link).' },
|
|
105
105
|
'client-name': { type: 'string', value: '<name>', description: 'With --browser: the name the sign-in page shows for this computer (default "shard CLI on <hostname>").' },
|
|
106
|
+
wait: { type: 'boolean', description: 'With --browser: wait for the approval (default). --no-wait prints the link and the code and returns; the next "shard auth login --browser" waits for that same request while it is valid (0.17.1+).' },
|
|
106
107
|
email: { type: 'string', value: '<email>', description: 'Your email address, to sign in with a password.' },
|
|
107
108
|
codex: { type: 'boolean', description: 'Sign in with the Codex login on this machine instead of a password (0.9.0+; creates the account when there is none, so it needs --accept-terms like shard signup).' },
|
|
108
109
|
...ACCEPT_TERMS,
|
|
109
110
|
...SECOND_FACTOR,
|
|
110
111
|
},
|
|
111
|
-
examples: ['shard auth login --browser', 'shard auth login --browser --no-open --json', `printf '%s\\n' "$PASSWORD" | shard auth login --email you@example.com`, `printf '%s\\n' "$PASSWORD" | shard auth login --email you@example.com --code 123456`, 'shard auth login --codex'],
|
|
112
|
+
examples: ['shard auth login --browser', 'shard auth login --browser --no-open --json', 'shard auth login --browser --no-wait --json # then: shard auth login --browser --json', `printf '%s\\n' "$PASSWORD" | shard auth login --email you@example.com`, `printf '%s\\n' "$PASSWORD" | shard auth login --email you@example.com --code 123456`, 'shard auth login --codex'],
|
|
112
113
|
},
|
|
113
114
|
{
|
|
114
115
|
path: ['auth', 'mfa'],
|
|
@@ -195,11 +196,12 @@ export const ACCOUNT_COMMANDS = [
|
|
|
195
196
|
{
|
|
196
197
|
path: ['setup'],
|
|
197
198
|
summary: 'Get ready to run workspaces: use (or create) an organization and project, create an API key and save it',
|
|
198
|
-
description: 'Needs a session (shard auth login). With no organization it creates "<your name>\'s organization" and a project "Default"; the key gets every workspace tool unless --tool. The key is saved in the credentials file, checked against the API, and every workspace command uses it from then on. Idempotent: a saved key that still works is kept (unless --new-key).',
|
|
199
|
+
description: 'Needs a session (shard auth login). With no organization it creates "<your name>\'s organization" and a project "Default"; the key gets every workspace tool unless --tool. The key is saved in the credentials file, checked against the API, and every workspace command uses it from then on. Idempotent: a saved key that still works is kept (unless --new-key). --guide (0.17.1+) prints the question a coding agent asks its user first (a SaaS platform, or their personal cloud coding agents) and the ordered steps of both, without a network call.',
|
|
199
200
|
positionals: [],
|
|
200
201
|
options: {
|
|
201
202
|
...ORG,
|
|
202
203
|
...PROJECT,
|
|
204
|
+
guide: { type: 'boolean', description: 'Print how to set up Shardflux with a coding agent: the one question to ask your user, then the steps for a SaaS platform and for a personal setup (0.17.1+).' },
|
|
203
205
|
'prepare-sample': { type: 'boolean', description: 'Copy the Daylight sample app into a new local Git project, "Daylight (sample)", for the first-run demo; prints its path.' },
|
|
204
206
|
activity: { type: 'boolean', description: 'With --inspect: the current commands, listening ports, sudo installs and browser window of --workspace, without waking it.' },
|
|
205
207
|
workspace: { type: 'string', value: '<key|conv_id>', description: 'The workspace or conversation to inspect for live onboarding activity.' },
|
|
@@ -214,7 +216,7 @@ export const ACCOUNT_COMMANDS = [
|
|
|
214
216
|
'new-key': { type: 'boolean', description: 'Create and save a new key even when the saved one works (the old key stays valid until revoked).' },
|
|
215
217
|
codex: { type: 'boolean', description: 'Set up the account Codex Cloud executor with this machine’s Codex login (default when signed in); --no-codex skips it.' },
|
|
216
218
|
},
|
|
217
|
-
examples: ['shard setup', 'shard setup --json --inspect --apps claude,codex', 'shard setup --org acme --project web --tool exec --tool files'],
|
|
219
|
+
examples: ['shard setup', 'shard setup --guide', 'shard setup --json --inspect --apps claude,codex', 'shard setup --org acme --project web --tool exec --tool files'],
|
|
218
220
|
},
|
|
219
221
|
{
|
|
220
222
|
path: ['env'],
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { setupGuide } from './agent-setup.js';
|
|
2
|
+
import type { Ctx, Handler } from './commands.js';
|
|
2
3
|
export declare const DEFAULT_API_URL = "https://api.shardflux.dev";
|
|
3
4
|
/** What `shard setup` gave a key before 0.15.1: every tool but `computer`. Such a saved key is replaced with a full one. */
|
|
4
5
|
export declare function outdatedDefaultKey(permissions: readonly string[]): boolean;
|
|
@@ -17,4 +18,6 @@ export declare function exportLine(shell: ShellKind, name: string, value: string
|
|
|
17
18
|
export declare function parseTime(text: string, option: string, now?: number): string;
|
|
18
19
|
/** A spend cap in dollars ("9", "9.5", "9.50", "$9") as minor units (cents); at most two decimals. */
|
|
19
20
|
export declare function dollarsToMinor(text: string, what: string): number;
|
|
21
|
+
/** The setup guide for this computer: whether a session and an API key are saved (no network call). */
|
|
22
|
+
export declare function agentSetupGuide(ctx: Ctx): ReturnType<typeof setupGuide>;
|
|
20
23
|
export declare const ACCOUNT_HANDLERS: Record<string, Handler>;
|
package/dist/account-commands.js
CHANGED
|
@@ -20,9 +20,13 @@ import { API_KEY_TOOL_PERMISSIONS, CheckoutTimeoutError, Shardflux, ShardfluxAcc
|
|
|
20
20
|
import { CLI_VERSION, UUID, parseDuration, parsePositiveInt } from "./args.js";
|
|
21
21
|
import { openUrl } from "./browser.js";
|
|
22
22
|
import { defaultClientName, startDeviceAuthorization, waitForDeviceSession } from "./browser-login.js";
|
|
23
|
+
import { setupGuide, setupGuideText } from "./agent-setup.js";
|
|
24
|
+
import { readFileSync, rmSync } from 'node:fs';
|
|
25
|
+
import { join } from 'node:path';
|
|
23
26
|
import { legalFields, requireTermsAcceptance, showLegalNotice } from "./legal.js";
|
|
24
27
|
import { fileExists, oneOf, out, parseSlugVersion, principal, readInput, resolveWorkspace, str, strs, waitTimeout } from "./commands.js";
|
|
25
|
-
import {
|
|
28
|
+
import { writePrivateFile } from "./credentials.js";
|
|
29
|
+
import { AuthConfigError, CheckoutEndedError, EXIT, InterruptedError, MfaPendingError, NotFoundError, UsageError, describeError } from "./errors.js";
|
|
26
30
|
import { apiKeyTable, attachmentTable, auditTable, authSessionTable, billingStatusText, dataExportText, egressVersionTable, invitationTable, invoiceTable, isGrantPlan, kv, memberTable, money, orgTable, overagePolicyText, planTable, projectEgressText, projectTable, table, time, toolsText, volumeDetail, volumeTable, workspaceEgressText, WORKSPACE_HEADERS, workspaceRow, } from "./format.js";
|
|
27
31
|
export const DEFAULT_API_URL = 'https://api.shardflux.dev';
|
|
28
32
|
const TOTP = /^\d{6}$/;
|
|
@@ -39,6 +43,9 @@ export function outdatedDefaultKey(permissions) {
|
|
|
39
43
|
const DEFAULT_CHECKOUT_WAIT_MS = 15 * 60_000;
|
|
40
44
|
const CHECKOUT_POLL_MS = 2_000;
|
|
41
45
|
const NEXT_WORKSPACE = 'shard ws open demo --template python-node-browser';
|
|
46
|
+
/** After setup (0.17.1+): the next step for each answer to the setup question (shard setup --guide has them all). */
|
|
47
|
+
const NEXT_STEPS = { saas: 'eval "$(shard env)", then the SDK, HTTP API or MCP server', personal: 'shard setup --inspect --connect --apps claude,codex, then shard ./' };
|
|
48
|
+
const nextLines = () => `next, for your product (SDK, API, MCP): ${NEXT_STEPS.saas}\nnext, for your own cloud coding agents: ${NEXT_STEPS.personal}\n`;
|
|
42
49
|
const SWITCHED_NOTE = 'note: another user was signed in here; their default organization, project and saved API key were removed from this profile (the key stays valid until revoked).\n';
|
|
43
50
|
const pipe = (cmd) => `printf '%s\\n' "$PASSWORD" | ${cmd}`;
|
|
44
51
|
function need(values, option, example) {
|
|
@@ -274,7 +281,7 @@ function nextAfterSignIn(ctx, user, me) {
|
|
|
274
281
|
const hasKey = profile.api_key !== undefined || Boolean(ctx.io.env.SHARDFLUX_API_KEY?.trim());
|
|
275
282
|
if (!hasKey || !me || me.memberships.length === 0)
|
|
276
283
|
return 'shard setup (an organization, a project and an API key, saved)';
|
|
277
|
-
return
|
|
284
|
+
return 'shard setup --guide (the steps for your product, or for your own cloud coding agents)';
|
|
278
285
|
}
|
|
279
286
|
async function signedInReport(ctx, account, user, session, extra = {}) {
|
|
280
287
|
let me = null;
|
|
@@ -682,7 +689,7 @@ async function runSetup(ctx, values, account) {
|
|
|
682
689
|
]) +
|
|
683
690
|
envNote +
|
|
684
691
|
(codex ? 'Codex Cloud is ready. One account executor; no pairing. Its residency is billed as workspace usage.\n' : '') +
|
|
685
|
-
|
|
692
|
+
nextLines(),
|
|
686
693
|
data: {
|
|
687
694
|
organization: org,
|
|
688
695
|
project,
|
|
@@ -691,10 +698,46 @@ async function runSetup(ctx, values, account) {
|
|
|
691
698
|
...(codex ? { codex } : {}),
|
|
692
699
|
credentials_file: ctx.store.file,
|
|
693
700
|
next: NEXT_WORKSPACE,
|
|
701
|
+
next_steps: NEXT_STEPS,
|
|
694
702
|
},
|
|
695
703
|
};
|
|
696
704
|
}
|
|
697
705
|
// ---- browser sign-in (0.15.0+) -----------------------------------------------------------------------------------
|
|
706
|
+
/**
|
|
707
|
+
* A browser sign-in to finish later (0.17.1+): `auth login --browser --no-wait` saves the request (0600, next to the
|
|
708
|
+
* credentials) and returns; the next `auth login --browser` for the same API waits for that request while it is valid,
|
|
709
|
+
* so an agent whose command is cut off by its tool's time limit runs it again and the person approves one code.
|
|
710
|
+
*/
|
|
711
|
+
const PENDING_LOGIN_FILE = 'browser-login.json';
|
|
712
|
+
/** A request this close to its expiry is not resumed: a new one gives the person time to approve it. */
|
|
713
|
+
const PENDING_MARGIN_MS = 15_000;
|
|
714
|
+
function pendingLogin(ctx) {
|
|
715
|
+
try {
|
|
716
|
+
const saved = JSON.parse(readFileSync(join(ctx.store.dir, PENDING_LOGIN_FILE), 'utf8'));
|
|
717
|
+
const r = saved.request;
|
|
718
|
+
if (saved.api_url !== ctx.apiUrl || typeof saved.expires_at !== 'number' || !r || typeof r.device_code !== 'string' || typeof r.user_code !== 'string' || typeof r.verification_uri_complete !== 'string' || typeof r.interval !== 'number')
|
|
719
|
+
return null;
|
|
720
|
+
const left = saved.expires_at - Date.now();
|
|
721
|
+
if (left < PENDING_MARGIN_MS)
|
|
722
|
+
return null;
|
|
723
|
+
ctx.addSecret(r.device_code);
|
|
724
|
+
return { device_code: r.device_code, user_code: r.user_code, verification_uri: typeof r.verification_uri === 'string' ? r.verification_uri : r.verification_uri_complete, verification_uri_complete: r.verification_uri_complete, interval: r.interval, expires_in: Math.floor(left / 1000) };
|
|
725
|
+
}
|
|
726
|
+
catch {
|
|
727
|
+
return null;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
function savePendingLogin(ctx, d) {
|
|
731
|
+
writePrivateFile(ctx.store.dir, join(ctx.store.dir, PENDING_LOGIN_FILE), `${JSON.stringify({ api_url: ctx.apiUrl, expires_at: Date.now() + d.expires_in * 1000, request: d })}\n`);
|
|
732
|
+
}
|
|
733
|
+
function clearPendingLogin(ctx) {
|
|
734
|
+
try {
|
|
735
|
+
rmSync(join(ctx.store.dir, PENDING_LOGIN_FILE), { force: true });
|
|
736
|
+
}
|
|
737
|
+
catch {
|
|
738
|
+
// Expires on its own.
|
|
739
|
+
}
|
|
740
|
+
}
|
|
698
741
|
/** One NDJSON line of `auth login --browser --json` (the Mac app reads them). */
|
|
699
742
|
function event(ctx, value) {
|
|
700
743
|
ctx.io.stdout.write(`${JSON.stringify(value)}\n`);
|
|
@@ -708,23 +751,49 @@ async function browserSignIn(ctx, values, noticeShown = false) {
|
|
|
708
751
|
try {
|
|
709
752
|
const opts = ctx.accountOptions();
|
|
710
753
|
const clientName = str(values['client-name'])?.trim() || defaultClientName(ctx.hostname());
|
|
711
|
-
const
|
|
754
|
+
const waits = values.wait !== false;
|
|
755
|
+
// A request saved by --no-wait (0.17.1+) is the one to wait for; otherwise a new one.
|
|
756
|
+
const earlier = pendingLogin(ctx);
|
|
757
|
+
const resumed = earlier !== null;
|
|
758
|
+
const d = earlier ?? (await startDeviceAuthorization(opts, clientName, ctx.signal));
|
|
759
|
+
ctx.addSecret(d.device_code);
|
|
760
|
+
if (!waits && !resumed)
|
|
761
|
+
savePendingLogin(ctx, d);
|
|
712
762
|
// The terms notice comes before the browser opens: a line here, the URLs in the event for an app to show. No
|
|
713
763
|
// --accept-terms: an account created in the browser agrees to the terms on the sign-up page, which records it.
|
|
714
764
|
if (ctx.json) {
|
|
715
|
-
event(ctx, { event: 'open', verification_uri_complete: d.verification_uri_complete, user_code: d.user_code, expires_in: d.expires_in, ...legalFields() });
|
|
765
|
+
event(ctx, { event: 'open', verification_uri_complete: d.verification_uri_complete, user_code: d.user_code, expires_in: d.expires_in, ...legalFields(), ...(resumed ? { resumed: true } : {}) });
|
|
716
766
|
}
|
|
717
767
|
else if (!noticeShown)
|
|
718
768
|
showLegalNotice(ctx);
|
|
719
|
-
|
|
769
|
+
// A resumed request was opened (or printed) by the command that started it.
|
|
770
|
+
const opened = !resumed && values.open !== false && openUrl(d.verification_uri_complete, ctx.io.env);
|
|
720
771
|
const minutes = Math.max(1, Math.round(d.expires_in / 60));
|
|
721
772
|
if (!ctx.json) {
|
|
722
|
-
ctx.io.stderr.write(`${opened ? 'Opening your browser to sign in' : 'Open this page to sign in'}: ${d.verification_uri_complete}\n` +
|
|
773
|
+
ctx.io.stderr.write(`${resumed ? 'Continuing the sign-in started earlier' : opened ? 'Opening your browser to sign in' : 'Open this page to sign in'}: ${d.verification_uri_complete}\n` +
|
|
723
774
|
`Your code: ${d.user_code} (approve only if the page shows the same code)\n` +
|
|
724
|
-
|
|
775
|
+
(waits
|
|
776
|
+
? `Waiting for the approval in the browser (the code expires in ${minutes} minutes; Ctrl-C stops)...\n`
|
|
777
|
+
: `Approve it in the browser, then run shard auth login --browser to finish (the code is valid for ${minutes} minutes).\n`));
|
|
778
|
+
}
|
|
779
|
+
if (!waits) {
|
|
780
|
+
if (ctx.json)
|
|
781
|
+
event(ctx, { event: 'pending', expires_in: d.expires_in, next: 'shard auth login --browser --json' });
|
|
782
|
+
return null;
|
|
725
783
|
}
|
|
726
784
|
const sleep = opts.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
727
|
-
|
|
785
|
+
let s;
|
|
786
|
+
try {
|
|
787
|
+
s = await waitForDeviceSession(opts, d, { signal: ctx.signal, sleep });
|
|
788
|
+
}
|
|
789
|
+
catch (err) {
|
|
790
|
+
// Refused, expired or unknown: the saved request is done. Interrupted (or cut off): it stays for the next run.
|
|
791
|
+
if (resumed && !ctx.signal.aborted && err instanceof ShardfluxApiError)
|
|
792
|
+
clearPendingLogin(ctx);
|
|
793
|
+
throw err;
|
|
794
|
+
}
|
|
795
|
+
if (resumed)
|
|
796
|
+
clearPendingLogin(ctx);
|
|
728
797
|
ctx.addSecret(s.session_token);
|
|
729
798
|
const replaced = ctx.store.profile(ctx.apiUrl).session?.token ?? null;
|
|
730
799
|
const saved = { token: s.session_token, expires_at: s.session_expires_at || null, user: { id: s.user.id, email: s.user.email }, state: 'active' };
|
|
@@ -747,8 +816,8 @@ async function browserSignIn(ctx, values, noticeShown = false) {
|
|
|
747
816
|
}
|
|
748
817
|
/** `shard signup` on a terminal without a Codex login or --email (0.15.0+): the browser sign-in, then setup like signup. */
|
|
749
818
|
async function browserSignup(ctx, values) {
|
|
750
|
-
// signup has shown the notice (and asked) already.
|
|
751
|
-
const { account, user } = await browserSignIn(ctx, values, true);
|
|
819
|
+
// signup has shown the notice (and asked) already; it always waits for the approval.
|
|
820
|
+
const { account, user } = (await browserSignIn(ctx, { ...values, wait: true }, true));
|
|
752
821
|
let text = `Signed in as ${userLine(user)} in the browser.\nsession: saved in ${ctx.store.file}\n`;
|
|
753
822
|
const data = { status: 'authenticated', user, method: 'browser', credentials_file: ctx.store.file };
|
|
754
823
|
if (values.setup !== false) {
|
|
@@ -773,8 +842,16 @@ function wantsBrowser(ctx, values) {
|
|
|
773
842
|
}
|
|
774
843
|
if (values.browser === false || email || values.codex === true)
|
|
775
844
|
return false;
|
|
845
|
+
// --no-wait (0.17.1+) is a browser sign-in to finish with the next shard auth login --browser.
|
|
846
|
+
if (values.wait === false)
|
|
847
|
+
return true;
|
|
776
848
|
return ctx.input.interactive && !ctx.json;
|
|
777
849
|
}
|
|
850
|
+
/** The setup guide for this computer: whether a session and an API key are saved (no network call). */
|
|
851
|
+
export function agentSetupGuide(ctx) {
|
|
852
|
+
const profile = ctx.store.profile(ctx.apiUrl);
|
|
853
|
+
return setupGuide({ signedIn: ctx.sessionSource() !== null, email: profile.session?.user?.email ?? null, apiKey: profile.api_key !== undefined || Boolean(ctx.io.env.SHARDFLUX_API_KEY?.trim()) });
|
|
854
|
+
}
|
|
778
855
|
// ---- handlers --------------------------------------------------------------------------------------------------
|
|
779
856
|
export const ACCOUNT_HANDLERS = {
|
|
780
857
|
async 'auth register'(ctx, values) {
|
|
@@ -826,15 +903,18 @@ export const ACCOUNT_HANDLERS = {
|
|
|
826
903
|
if (wantsBrowser(ctx, values)) {
|
|
827
904
|
if (factorFlags(values) !== null)
|
|
828
905
|
throw new UsageError('--code and --recovery-code go with --email; in the browser the sign-in page asks for your second factor');
|
|
829
|
-
const
|
|
906
|
+
const signedIn = await browserSignIn(ctx, values);
|
|
907
|
+
if (!signedIn)
|
|
908
|
+
return 0;
|
|
909
|
+
const { account, user, saved } = signedIn;
|
|
830
910
|
if (ctx.json) {
|
|
831
911
|
event(ctx, { event: 'signed_in', email: user.email });
|
|
832
912
|
return 0;
|
|
833
913
|
}
|
|
834
914
|
return signedInReport(ctx, account, user, saved);
|
|
835
915
|
}
|
|
836
|
-
if (values.open !== undefined || str(values['client-name']) !== undefined)
|
|
837
|
-
throw new UsageError('--no-open and --client-name go with --browser', 'shard auth login --browser --no-open');
|
|
916
|
+
if (values.open !== undefined || values.wait !== undefined || str(values['client-name']) !== undefined)
|
|
917
|
+
throw new UsageError('--no-open, --no-wait and --client-name go with --browser', 'shard auth login --browser --no-open');
|
|
838
918
|
if (values.codex === true)
|
|
839
919
|
return ACCOUNT_HANDLERS.signup(ctx, { ...values, setup: false, codex: true, email: undefined }, []);
|
|
840
920
|
const given = str(values.email)?.trim();
|
|
@@ -1099,6 +1179,16 @@ export const ACCOUNT_HANDLERS = {
|
|
|
1099
1179
|
return 0;
|
|
1100
1180
|
},
|
|
1101
1181
|
async setup(ctx, values) {
|
|
1182
|
+
if (values.guide === true) {
|
|
1183
|
+
const guide = agentSetupGuide(ctx);
|
|
1184
|
+
out(ctx, setupGuideText(guide), { guide });
|
|
1185
|
+
return 0;
|
|
1186
|
+
}
|
|
1187
|
+
// Not signed in, without a terminal (0.17.1+): the setup question and both paths' steps instead of an error line.
|
|
1188
|
+
if (ctx.sessionSource() === null && !ctx.json && values.inspect !== true && values['prepare-sample'] !== true && !ctx.input.interactive) {
|
|
1189
|
+
ctx.io.stdout.write(`Not signed in to ${ctx.apiUrl} yet.\n\n${setupGuideText(agentSetupGuide(ctx))}`);
|
|
1190
|
+
return EXIT.auth;
|
|
1191
|
+
}
|
|
1102
1192
|
if (values['prepare-sample'] === true) {
|
|
1103
1193
|
const path = await prepareOnboardingSample(ctx.store.dir);
|
|
1104
1194
|
out(ctx, `Daylight is ready at ${path}\n`, { sample_path: path });
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `shard agents accounts` (0.18.0+); with --json every write prints the updated `{accounts, pool}` block (the menu bar
|
|
3
|
+
* redraws from it), plus the account it changed.: the organization's Claude and ChatGPT/Codex accounts, with each one's usage
|
|
4
|
+
* windows, reset times, status and threads (docs/progress/account-pool.md). Sign-ins run the provider's own login in a
|
|
5
|
+
* workspace, as `shard agents credentials login claude` does; API keys come from standard input and are write-only.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentAccount, AgentAccountList } from '@shardflux/sdk';
|
|
8
|
+
import type { Ctx, Handler } from './commands.js';
|
|
9
|
+
import { CodedError } from './errors.js';
|
|
10
|
+
import type { HubCloud } from './cli-proxy-hub.js';
|
|
11
|
+
/** "in 2h 10m", "in 4d 8h", "in 41m"; "now" once passed. */
|
|
12
|
+
export declare function resetIn(resetsAt: string | null, now: number): string | null;
|
|
13
|
+
/** Account references: the id, `<provider>:<n>` (its place in the list, from 1), the email or the label. */
|
|
14
|
+
export declare function findAccount(list: AgentAccountList, ref: string): AgentAccount;
|
|
15
|
+
/** The compact list: one row per account, grouped by provider. */
|
|
16
|
+
export declare function formatAccounts(list: AgentAccountList, now: number): string;
|
|
17
|
+
/** The usage view: every window of every account as a bar with its reset time. */
|
|
18
|
+
export declare function formatUsage(list: AgentAccountList, now: number): string;
|
|
19
|
+
/** Codex's device sign-in page, as Codex 0.160.0 prints it (test/fixtures/cloud-agents/codex-login-device-auth-0.160.0.json). */
|
|
20
|
+
export declare function codexLoginUrls(output: string): string[];
|
|
21
|
+
export declare const ACCOUNT_POOL_HANDLERS: Record<string, Handler>;
|
|
22
|
+
/** The `accounts` block of `shard agents targets --json` (0.18.0+): the account list for the menu bar; null when it cannot be read. */
|
|
23
|
+
export declare function targetsAccounts(ctx: Ctx): Promise<AgentAccountList | null>;
|
|
24
|
+
/** The conversation's thread runs on the account pool (its `account.mode`, API with the pool). */
|
|
25
|
+
export declare function conversationPooled(conversation: unknown): boolean;
|
|
26
|
+
/** A pooled thread has no provider login on its session, so claude.ai, Claude Desktop and the Codex app cannot reach it. */
|
|
27
|
+
export declare const pooledNeedsT3: (ref: string) => CodedError;
|
|
28
|
+
/** Test seam: the hub cloud the pool toggle ensures (the SDK's by default). */
|
|
29
|
+
export declare const accountPoolSeams: {
|
|
30
|
+
hubCloud?: (ctx: Ctx) => HubCloud;
|
|
31
|
+
};
|