@shardflux/cli 0.24.0 → 0.25.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 +148 -0
- package/README.md +263 -1
- package/dist/account-args.js +5 -0
- package/dist/account-pool.js +5 -1
- package/dist/acp-journal.js +23 -1
- package/dist/acp-permission-elsewhere.d.ts +38 -0
- package/dist/acp-permission-elsewhere.js +85 -0
- package/dist/acp-rpc.d.ts +2 -1
- package/dist/acp-rpc.js +11 -2
- package/dist/acp.js +95 -22
- package/dist/agent-credentials.d.ts +3 -0
- package/dist/agent-credentials.js +7 -0
- package/dist/args.d.ts +1 -1
- package/dist/args.js +172 -9
- package/dist/board-args.d.ts +6 -0
- package/dist/board-args.js +172 -0
- package/dist/board-commands.d.ts +62 -0
- package/dist/board-commands.js +412 -0
- package/dist/codex-cloud.d.ts +30 -3
- package/dist/codex-cloud.js +86 -12
- package/dist/conversation-commands.d.ts +30 -0
- package/dist/conversation-commands.js +328 -9
- package/dist/conversation-transcript.d.ts +44 -0
- package/dist/conversation-transcript.js +206 -0
- package/dist/conversations.d.ts +7 -3
- package/dist/conversations.js +20 -10
- package/dist/device-approvals.js +4 -3
- package/dist/device-bridge.d.ts +42 -1
- package/dist/device-bridge.js +223 -12
- package/dist/device-folders.d.ts +66 -0
- package/dist/device-folders.js +236 -0
- package/dist/device-helper.d.ts +6 -0
- package/dist/device-helper.js +98 -14
- package/dist/drive-commands.d.ts +25 -0
- package/dist/drive-commands.js +201 -0
- package/dist/errors.js +2 -1
- package/dist/format.js +6 -2
- package/dist/handlers.js +7 -1
- package/dist/land.d.ts +116 -0
- package/dist/land.js +238 -0
- package/dist/main.js +10 -1
- package/dist/move-files.d.ts +39 -0
- package/dist/move-files.js +167 -0
- package/dist/move.js +12 -11
- package/dist/onboarding.d.ts +10 -6
- package/dist/onboarding.js +24 -6
- package/dist/project-git.d.ts +7 -1
- package/dist/project-git.js +16 -3
- package/dist/project-preparation.d.ts +7 -0
- package/dist/project-preparation.js +14 -0
- package/dist/project-template-setup.js +32 -11
- package/dist/router-commands.d.ts +33 -0
- package/dist/router-commands.js +179 -0
- package/dist/task-land-hub.py +150 -0
- package/dist/transcribe-commands.d.ts +7 -0
- package/dist/transcribe-commands.js +80 -0
- package/dist/worktree-twin-engine.d.ts +8 -0
- package/dist/worktree-twin-engine.js +28 -22
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,153 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- Device requests reach the right computer (0.25.0+): the background helper tells the API which conversations are
|
|
6
|
+
local to this computer (started or opened here), so their requests come here first, then to the computer you used
|
|
7
|
+
last, never to whichever was seen last. A project link with a first task (`project_link` with `brief`) reads the
|
|
8
|
+
start's whole JSON output; before, it failed with "Unexpected token '}'" although the conversation started.
|
|
9
|
+
|
|
10
|
+
- `shard board` and `shard task show` show what a working task does now ("working (Fixing the login cookie)") and
|
|
11
|
+
what each working step does, next to the plain waiting line of a task that waits to start.
|
|
12
|
+
- `shard transcribe <file>` (0.25.0+, SDK 0.28.0) prints what a recording says (WebM/Opus or PCM WAV from the file;
|
|
13
|
+
raw PCM with `--format pcm16 --sample-rate`); `--words` adds each word's start and end, `--json` prints the
|
|
14
|
+
transcript.
|
|
15
|
+
- Faster conversation starts (0.24.1): the project's dependency fingerprint is read from Git's own file list instead of walking the whole folder, so ignored and untracked trees beside the project (agent worktrees, build output) no longer hold a start on **Getting your project…**. A folder with 1.2 million such files took 32 s per start; it now takes 0.3 s, with the same fingerprint.
|
|
16
|
+
- A folder without Git that `shard` makes a repository of (a first chat, `shard projects link`) starts with its files as
|
|
17
|
+
the first commit (0.25.0+; `.gitignore` respected, large media stay untracked), so a conversation starts from the
|
|
18
|
+
same commit as the folder and its work comes back by fast-forward, as in any repository. Before, an empty first
|
|
19
|
+
commit left every file to the starting snapshot and the landing asked the agent to merge. A repository of your own
|
|
20
|
+
keeps its staged and untracked files as they are.
|
|
21
|
+
- Device requests (0.25.0+) are answered between turns and as a turn ends; only an archived conversation refuses them.
|
|
22
|
+
- Background preparation of a project with no build or test command ends ready (0.25.0+): there is nothing to check,
|
|
23
|
+
so `shard projects sync list` and the folders `shard projects link` adds no longer show an error.
|
|
24
|
+
- `shard move` (0.25.0+) brings the files the session used outside the project: files you @-mentioned or named in a
|
|
25
|
+
prompt, files it read or edited, and the files a handed file names (a `~/Downloads` handoff and what it points to).
|
|
26
|
+
Each goes to the same place under the VM's home, and this computer's home path leads there, so the history's paths
|
|
27
|
+
open in the cloud. Before, only the checkout and the transcript moved, and a moved session stopped at a handoff it
|
|
28
|
+
could no longer open. Key and sign-in stores (`~/.ssh`, `~/.aws`, `.env` files, private keys) stay here. Up to 64
|
|
29
|
+
files, 64 MiB in all, 16 MiB each; the command names what it brings and what stays, and `--json` adds `files` and
|
|
30
|
+
`files_left`.
|
|
31
|
+
- 0.25.0 (pending): Allowance hints respect unavailable overage; operation errors retain the service’s recovery message and retry delay.
|
|
32
|
+
|
|
33
|
+
- Landing that lands (0.25.0+): `shard task land <task>` merges a finished task's result (`shard/<task id>`, where its
|
|
34
|
+
master merged its workers' branches; when a master did not, their branches are merged into it here when they merge
|
|
35
|
+
cleanly) into the project's default branch on the project hub, a fast-forward or a clean merge commit, never by
|
|
36
|
+
force; brings it into your folder on this computer the way finished conversations land (your branch moves, your
|
|
37
|
+
uncommitted edits stay, rewritten files are backed up first); checks the commit is in the branch; and only then
|
|
38
|
+
records it on the board (`Landed in ~/code/best-todo · 3f2a1c9`). A conflict changes nothing and asks the task's
|
|
39
|
+
master to merge (`land_conflict`). `shard needs-you answer land_… land` does the same, and
|
|
40
|
+
`shard conversations land <id> merge` now lands the conversation's branch the same way before it records it (before,
|
|
41
|
+
both only recorded a landing). `--path <folder>` picks the folder; `--json` returns `{landed, result, hub, folder,
|
|
42
|
+
recorded, message}`.
|
|
43
|
+
|
|
44
|
+
- `shard conversations delete <id> --yes` (`shard c delete`, 0.25.0+, SDK 0.28.0) deletes a conversation everywhere at
|
|
45
|
+
once: its agent stops, its computer is deleted (a computer other conversations share stays for them), and its
|
|
46
|
+
messages, transcript and branch go with it, on every device. Without `--yes` it is refused before any request, as
|
|
47
|
+
every deletion is. `--json` prints the API's answer, `{id, deleted, deleted_at, operation}`; deleting it again answers
|
|
48
|
+
the same. The person who started it (or created the API key that did) and organization owners and admins delete
|
|
49
|
+
conversations. `shard conversations feed` shows a deleted conversation once as `<id> Deleted conversation deleted`.
|
|
50
|
+
- ACP input recovery (0.25.0): temporary guest-agent interruptions use bounded backoff with the same native input identity. The editor retains its running turn; permanent errors and unverified receipts still require loading the session.
|
|
51
|
+
|
|
52
|
+
- Tunnel recovery (0.24.1, SDK 0.27.3): a foreground reverse tunnel replaces its guest helper automatically when replay is lost. Existing TCP peers reset; fresh connections reach the new listener. SSH and device port-forward connections close cleanly for a new connection instead of looping on an unrecoverable cursor.
|
|
53
|
+
- Folders on this computer (0.25.0+): an agent can list a folder here (`dir_list`: names, kinds, sizes and Git
|
|
54
|
+
remotes, never file contents), make one of your projects from it (`project_link`, with an optional first task), and
|
|
55
|
+
move a file to or from anywhere here with an absolute or `~/` path. Nothing runs before you approve it: **Allow once**,
|
|
56
|
+
or **Always for this folder**, which covers that kind of request for that folder and what is inside it, from any of
|
|
57
|
+
your conversations. A path outside every such folder asks again, and commands never run under a folder grant. The
|
|
58
|
+
background helper now answers for your signed-in project (and, signed in without a key, every project you can reach),
|
|
59
|
+
so a home conversation or an Orchestrator task can ask too, and reads every project's requests in one poll.
|
|
60
|
+
- `shard projects link <path> [--prompt <text>] [--app claude|codex]` (0.25.0+) makes a local folder one of your
|
|
61
|
+
projects: prepared in the background and kept as this computer's live copy; `--prompt` also starts a conversation
|
|
62
|
+
there. `--json`: `{project: {project_id, repo_remote, folder, name, conversation_id?}}`.
|
|
63
|
+
- `shard device-helper` (0.25.0+) asks the desktop app first when it serves `device-approver.sock` in the config folder,
|
|
64
|
+
so approvals show there as Needs-you items; otherwise the menu bar, an editor (ACP) or `shard device approve` as before.
|
|
65
|
+
|
|
66
|
+
- `shard route <text...>` and `shard ask <question...>` (0.25.0+, SDK 0.28.0): the board's input bar in a terminal.
|
|
67
|
+
`shard route` prints where the input goes (its project or your home) and whether it is a task, a question or a steer
|
|
68
|
+
for an open task, with each task in your words and its title when the input asks for several; `shard ask` streams
|
|
69
|
+
the answer to a quick question about your work as it is written. `--task <task-id>` names the selected task, `--org`
|
|
70
|
+
and `--project` the scope (signed in: your organization's projects; with `SHARDFLUX_API_KEY` set: that key's
|
|
71
|
+
project), and `--json` prints the API's `RouterResult` or the whole answer.
|
|
72
|
+
- The board (0.25.0+, SDK 0.28.0): `shard board` shows what waits on you first, then every task in Now, Next and
|
|
73
|
+
Later with its state, title or words and project; `--follow` prints each change as it happens, until Ctrl-C
|
|
74
|
+
(`--json`: the board, then one feed answer per line). `shard task add <words...>` (`--next`, `--later`, `--first`,
|
|
75
|
+
`--after <task-id>`, `--home`, `--project`), `show`, `edit` (`--text`, `--title`, `--now|--next|--later`,
|
|
76
|
+
`--first|--after`, `--keep`, `--clear`), `rm`, `steer` and `clear-done` manage tasks in your own words, and `shard
|
|
77
|
+
task show` lists each report with its evidence. `shard needs-you` lists everything your agents wait on, and `shard
|
|
78
|
+
needs-you answer <id>` answers any of it (`allow|always|deny`, `--everywhere`, `--pick`, `--text`,
|
|
79
|
+
`land|keep|discard`, `--keep <task-id>`). `shard approvals` shows the approval mode and always-allow rules; `set
|
|
80
|
+
<ask|routine|trusted|default> [--project <id>|--default]`, `allow <tool> <pattern...> [--project <id>|--everywhere]`
|
|
81
|
+
and `remove <rule-id>` change them.
|
|
82
|
+
|
|
83
|
+
- Project drive (0.25.0+, SDK 0.28.0): `shard drive put <local-file> [<drive-path>]` saves a file to the project's
|
|
84
|
+
drive as a new version and prints its path and sha256 (the drive path defaults to the file's name; `-` reads standard
|
|
85
|
+
input; `--content-type`); `shard drive get <path>` writes its bytes to standard output or with `-o` to a file, checked
|
|
86
|
+
against their SHA-256, and `--sha256` reads exactly that version, also after the path was overwritten or removed;
|
|
87
|
+
`shard drive ls [prefix]` lists the current files (size, saved time, type, path; `--limit`, `--cursor`, `--all`);
|
|
88
|
+
`shard drive rm <path>`. The API key's project or `--project`; signed in, any of your projects by id or slug.
|
|
89
|
+
`--json` everywhere.
|
|
90
|
+
- Model template (0.25.0+, SDK 0.28.0): `shard models` prints which harness, model and effort each role of a task
|
|
91
|
+
(master, builder, hard, light, reviewer) runs with, until when a role waits for its account's next usage window and
|
|
92
|
+
what the other provider would run now; `--harness` and `--attempt` show a running task's and a retry's. `shard models
|
|
93
|
+
primary claude|codex|clear` sets the project's primary provider, `--org <id|slug>` the organization's default.
|
|
94
|
+
- `shard conversations list` and `shard conversations feed` (0.25.0+, SDK 0.28.0): signed in without an API key, every
|
|
95
|
+
project you work in, across your organizations, on one cursor; `--org <id|slug>` narrows them to one organization
|
|
96
|
+
(and uses your sign-in when you have one). With an API key they cover its project, as before.
|
|
97
|
+
|
|
98
|
+
- `shard conversations answer <id> <permission-id> --pick <option>` (0.25.0+) answers the agent's question (Claude Code's
|
|
99
|
+
AskUserQuestion) with exactly the picked option; repeat `--pick` for a multi-select question, `--pick
|
|
100
|
+
"<question>=<option>"` when it asks several; `deny` declines it.
|
|
101
|
+
|
|
102
|
+
- `shard acp`: a conversation computer on a newer template keeps the models the session offered until its live list
|
|
103
|
+
arrives, so the editor's first model choice is taken; before, the list went empty for a few seconds after
|
|
104
|
+
`session/new` and `session/set_model` answered "This model is no longer available".
|
|
105
|
+
|
|
106
|
+
- Codex accounts (0.25.0+, SDK 0.28.0): `shard agents open` of a Codex Cloud conversation checks the Codex app on this
|
|
107
|
+
computer first. When the app is signed out or signed in to another ChatGPT account than the thread's, it says so in
|
|
108
|
+
one line with the account to sign in as and the thread's web link, instead of opening a link the app cannot show.
|
|
109
|
+
Earlier threads are listed with their accounts (`Earlier history: <url> (account)`). `--json` adds `account`,
|
|
110
|
+
`codex_app_login`, `account_mismatch` (`line`, `sign_in_as`, `web_url`) and each earlier thread's `account`.
|
|
111
|
+
`shard agents accounts use` of a Codex account says when the Codex app here is signed in to another account
|
|
112
|
+
(`--json`: `codex_app`).
|
|
113
|
+
- Codex sign-in (0.25.0+, SDK 0.28.0): when Codex Cloud refuses the copied ChatGPT login, `shard setup --inspect`
|
|
114
|
+
says so in one line with the next step: `codex login` (Sign in to Codex again), then, once this computer has the new
|
|
115
|
+
sign-in, Copy sign-in (`shard agents credentials sync`); `--connect` copies it. `shard ./ codex` and
|
|
116
|
+
`shard agents codex enable` copy this computer's login and continue when it is new, or stop at once with
|
|
117
|
+
`codex_sign_in_required` and that line. The Codex remote device is never restarted for a sign-in (its Cloud threads
|
|
118
|
+
keep running), and one starting again with the new login reads as connecting.
|
|
119
|
+
|
|
120
|
+
- `shard conversations start` starts a conversation without a folder: from the project hub (`--repo`, `--branch`), or with `--home` a coordinator on your machine that spawns threads in the project's repositories. `--app`, `--model`, `--effort`, `--title`, `--project`; `--prompt` sends the first message, with `--file` attachments. Prints the conversation's id, key and state (`--json`: the conversation, its workspace and the message).
|
|
121
|
+
|
|
122
|
+
- `shard conversations send <id> <text> --file <path>` (repeatable, up to 20 files of 64 MiB each) puts each file in the conversation's computer before the message, which lists their paths, and prints `Attached <path>` for each. The text may be left out when files are attached, and unquoted words are sent as one message.
|
|
123
|
+
|
|
124
|
+
- Home conversations list as `home` in `shard conversations list` and `get`, and open without a repository in `/home/user`.
|
|
125
|
+
|
|
126
|
+
- `shard acp`: a permission prompt answered through the API (the Shard client, `shard conversations answer`, MCP)
|
|
127
|
+
while the editor shows it is withdrawn from the editor (`$/cancel_request`) and the turn goes on in the editor; before,
|
|
128
|
+
the editor saw nothing more of the turn until it answered its own prompt.
|
|
129
|
+
|
|
130
|
+
- Permission requests (0.25.0+, SDK 0.28.0): `shard conversations permissions <id>` lists what a conversation's agent
|
|
131
|
+
asked permission for before running a tool (Claude Code, Codex and ACP agents), oldest first, with `--state`,
|
|
132
|
+
`--all` and `--json`; `shard conversations answer <id> <permission-id> allow|always|deny` answers one.
|
|
133
|
+
`shard conversations get` names the requests a `needs_you` conversation waits on (`Waiting on: Run npm test`).
|
|
134
|
+
|
|
135
|
+
- `shard conversations watch <id>` shows a conversation's terminal live and read-only: its last 256 KiB, then the agent's
|
|
136
|
+
output as it works, until its session exits or Ctrl-C. It never types into the terminal and never keeps the computer
|
|
137
|
+
awake while the agent is idle.
|
|
138
|
+
- `shard conversations get <id>` prints one line per port a process listens on in the conversation's computer: the
|
|
139
|
+
port, the program, and its URL once exposed (or `127.0.0.1 only`). `--json` includes `pty_id`, `listening_ports` and
|
|
140
|
+
`listening_ports_at`.
|
|
141
|
+
|
|
142
|
+
- `shard conversations feed` (0.25.0+): each conversation of the project as it changes, until interrupted; `--json`
|
|
143
|
+
prints one `{conversation, cursor}` object per line, `--cursor` continues after one. `shard conversations list
|
|
144
|
+
--updated-after <time>` filters by `updated_at`.
|
|
145
|
+
- Conversation titles in human output are the agent's own short title (`title_short`) once it has one.
|
|
146
|
+
|
|
147
|
+
- `shard acp` opens a conversation by its id: `session/load` with a `conv_…` session id attaches an ACP client to that conversation's live session in its computer, with its history replayed by the agent and no local folder synced.
|
|
148
|
+
|
|
149
|
+
- `shard conversations transcript <id>` prints a conversation’s transcript, the agent’s own Claude Code or Codex JSONL byte for byte, for working, parked and finished conversations alike (`--offset`, `--session`; `--follow` keeps printing new lines). `shard conversations events <id>` follows it live: state changes, new transcript lines, tool calls and the reply as it streams; `--json` prints one event per line.
|
|
150
|
+
|
|
3
151
|
## 0.24.0
|
|
4
152
|
|
|
5
153
|
- Finish all active device port-forward cleanup and close the local listener and cell before returning the original tunnel-close error. Repeated stop and abort keep the same error and promise.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @shardflux/cli: `shard`
|
|
2
2
|
|
|
3
|
+
For error codes, retry timing, and plan recovery, see the [error reference](https://docs.shardflux.dev/reference/errors).
|
|
4
|
+
|
|
3
5
|
Historical template file lists: reads queue checksum-verified reconstruction when a cold list is absent from the SQL cache. TypeScript SDK 0.27.0+ / Python 0.23.0+ wait full Retry-After for retryable API 409 file_list_indexing on GET/HEAD within the admission timeout. Template objects and version history stay available.
|
|
4
6
|
|
|
5
7
|
Plan-derived API budgets (0.23.0+, SDK 0.27.0): `--json` error output includes `rate_limit` and `retry_after_seconds`; the text hint names the shared scope and delay. API request pacing follows the SDK admission timeout and preserves the request body. Reuse workspace credentials and reduce status polling when the returned budget asks for a delay.
|
|
@@ -144,6 +146,21 @@ shard ./ --on fix-login --review # a read-only Claude reviewer of it
|
|
|
144
146
|
the new thread. Codex threads are Codex Cloud threads, on the web and your phone too. `shard agents list` shows each
|
|
145
147
|
thread's conversation and computer.
|
|
146
148
|
|
|
149
|
+
Start a conversation without a folder (0.25.0+): its repository is checked out from the project's saved branches, or
|
|
150
|
+
with `--home` a coordinator starts on your machine and spawns threads in the project's repositories.
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
shard conversations start --prompt "Add CSV export to the invoices page" --file mockup.png
|
|
154
|
+
shard conversations start --home --title "Plan the billing work"
|
|
155
|
+
shard conversations send conv_6qz2dmu4kd3xa7v5l2hgmfnpjy "Here is the failing run" --file ci.log
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`--repo` and `--branch` choose the repository and the branch it starts from (default: the project's most recently
|
|
159
|
+
active repository, from `main`, then `master`); `--app`, `--model` and `--effort` work as for `shard ./`. It prints the
|
|
160
|
+
conversation's id, key and state; `shard agents open <id>` opens it. `--file` (repeatable, up to 20 files of 64 MiB
|
|
161
|
+
each) puts each file in the conversation's computer before the message and prints where it landed; `--json` returns
|
|
162
|
+
the stored paths.
|
|
163
|
+
|
|
147
164
|
Choose the model and reasoning effort a new thread starts with (0.17.0+):
|
|
148
165
|
|
|
149
166
|
```sh
|
|
@@ -235,6 +252,8 @@ shard conversations try <conversation>
|
|
|
235
252
|
Your branch opens in `.shard/worktrees/<name>`, syncs both ways, and its dev servers appear at localhost.
|
|
236
253
|
Ctrl-C stops local sync. Your main checkout stays available for your own work.
|
|
237
254
|
Device tools ask for approval on your computer before preparing the conversation’s local worktree. With CLI 0.15.0 and menu bar 0.3.0, Review shows the exact command, file direction, paths or port mapping; access outside the conversation folder only offers Allow once. Live transcripts stay in
|
|
255
|
+
|
|
256
|
+
From 0.25.0, an agent can also list a folder on your computer, make one of your projects from it, and move a file to or from anywhere on it by an absolute or `~/` path. Each asks first: **Allow once**, or **Always for this folder**, which covers that kind of request for that folder and everything inside it. `shard projects link <path> [--prompt <text>]` does the same from a terminal: the folder is prepared in the background, kept as this computer’s live copy, and `--prompt` starts a conversation there.
|
|
238
257
|
`~/.config/shardflux/conversations/`; ended sessions enter Claude Code’s or Codex’s native history. Transcript files up to 64 MiB are supported (0.14.0+).
|
|
239
258
|
From 0.14.3, transcript copying runs independently of device approvals. Unknown entries are skipped, and failed copies retry with backoff; diagnostics name the conversation and affected entry.
|
|
240
259
|
|
|
@@ -687,6 +706,8 @@ shows the status; `shard version --check` asks now (`--json`: `{"cli", "sdk", "u
|
|
|
687
706
|
| `version [--check]` | Print the CLI and SDK versions and the update status (`--check` asks the API now). |
|
|
688
707
|
| `usage [--org <id>] [--estimate \| --series \| --workspace <id\|key>] [--from T] [--to T] [--granularity hour\|day] [--meter M]` | Usage summary for the current period: plan, meters and allowances. `--estimate`: the bill so far and projected allowance use; `--series`: usage over time; `--workspace`: one workspace's usage over time (0.5.0+). The summary includes the [overage](#usage-and-overage) block (0.5.1+). |
|
|
689
708
|
| `feedback [--yes] [--category C] [--workspace W] [--request-id ID] [--error-code CODE] [--command TEXT] [--from-file F\|-] <message...>` | Preview feedback; `--yes` sends after explicit user authorization (0.22.0+). See [Feedback](#feedback-preview-and-user-approval). |
|
|
709
|
+
| `route [--task ID] [--org O] [--project P] <text...>`, `ask [--task ID] [--org O] [--project P] <question...>` | The board's input bar (0.25.0+): where a line of input goes (its project or your home; a task, a question or a steer, split per task), and a quick question about your work, answered as it is written. |
|
|
710
|
+
| `conversations delete <id> --yes` (`c delete`) | Delete a conversation everywhere at once (0.25.0+): its agent stops, its computer is deleted, and its messages, transcript and branch go with it. `--json` prints `{id, deleted, deleted_at, operation}`. See [Conversations](#conversations). |
|
|
690
711
|
| `workspaces open <key> --template <slug> [--secret NAME]... [--input NAME=value]... [--input-file F] [--lifetime persistent\|session] [--mode processful\|file-first] [--cpu-millis N --memory-mib N --disk-gib N] [--allocation-mode fixed\|elastic] [--memory-held N] [--no-wait] [--timeout 5m] [--timing]` | Open by key. Creates the workspace on first use and reconnects or resumes it afterwards, never resetting it. Waits until it is ready (the template's start commands and services included) unless you pass `--no-wait`. `--secret` binds secret names (replacing the binding of an existing workspace). `--input` (0.4.0+) passes the template's text inputs (replacing those of an existing workspace); `--input-file` reads `NAME=value` lines or a JSON object. `--lifetime session`: the workspace is discarded when the session ends (`workspaces close` or the idle timeout), and the key then opens a new workspace. `--mode file-first` (0.5.0+) opens a [file-first workspace](#file-first-workspaces); the default is processful for a new key and the stored mode for an existing one. `--allocation-mode elastic` (0.8.0+): [elastic memory](#elastic-memory-080). |
|
|
691
712
|
| `workspaces list [--state S] [--prefix P] [--lifetime persistent\|session\|any] [--purpose standard\|template_draft\|template_test\|any] [--include-deleted] [--all] [--limit N] [--cursor C]` | One page, or every page with `--all`. The next cursor is printed on stderr. By default only persistent standard workspaces are listed. A file-first workspace's state reads `running (file-first)` (0.5.0+). |
|
|
692
713
|
| `workspaces get <id\|key>` | One workspace (deleted ones included), with the startup of its template's start commands and services (0.4.0+): a failed step shows its exit code, reason and output tail. Its mode, and a file-first workspace's tree revision (0.5.0+). Its memory (0.8.0+): `fixed 4096 MiB`, or `elastic: promised …, held …, plugged +… MiB`. The template version whose [immutable paths](#immutable-paths-080) it has mounted (0.8.0+): `immutable paths v3 (mounted read-only)`. |
|
|
@@ -1446,7 +1467,7 @@ A message from claude.ai or the Claude app wakes a waiting Claude conversation a
|
|
|
1446
1467
|
|
|
1447
1468
|
Run `shard ./` in your project to start Claude Code or Codex, usable immediately while setup runs in the background.
|
|
1448
1469
|
|
|
1449
|
-
New project folders are ready to use: `shard ./` and `shard agents new` initialize Git on `main` when needed
|
|
1470
|
+
New project folders are ready to use: `shard ./` and `shard agents new` initialize Git on `main` when needed (CLI 0.14.2+). From 0.25.0 a folder `shard` makes a repository of gets its files as the first commit (`.gitignore` respected; large media stay untracked), so a conversation's work comes back by fast-forward; a repository of your own without commits keeps its staged and untracked files behind an empty initial commit. Repositories without commits keep their current branch. If Git identity is missing, that one commit uses `Shardflux <noreply@shardflux.dev>` without changing your Git configuration.
|
|
1450
1471
|
|
|
1451
1472
|
Machine saves require a machine source VM (`labels.shard_layer = "machine"`). On your computer, run
|
|
1452
1473
|
`shard machine open --json`, make changes in that VM, then `shard machine save --wait`. The computer's CLI
|
|
@@ -1559,6 +1580,40 @@ account, make another one active first; your own you can always remove. `--json`
|
|
|
1559
1580
|
|
|
1560
1581
|
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.
|
|
1561
1582
|
|
|
1583
|
+
Watch an agent work: `shard conversations watch <id>` shows the conversation's terminal live, read-only. It starts
|
|
1584
|
+
with the last 256 KiB the agent printed, then streams everything it prints, until its session exits or you press
|
|
1585
|
+
Ctrl-C. Nothing you type reaches the agent, and watching never keeps its computer awake while the agent is idle.
|
|
1586
|
+
`shard conversations get <id>` lists the servers running in the conversation's computer, one line per port, with
|
|
1587
|
+
each port's URL once exposed (`shard ws port expose`); `--json` returns them as `listening_ports`, and the terminal as
|
|
1588
|
+
`pty_id`.
|
|
1589
|
+
|
|
1590
|
+
```sh
|
|
1591
|
+
shard conversations watch conv_a7k2m4q6s3t5v7x2z4b6d3f5h7
|
|
1592
|
+
shard conversations get conv_a7k2m4q6s3t5v7x2z4b6d3f5h7
|
|
1593
|
+
# Fix login
|
|
1594
|
+
# working
|
|
1595
|
+
# shard/fix-login
|
|
1596
|
+
# 5173 node https://5173-<handle>.shardflux.app (exposed)
|
|
1597
|
+
# 5432 postgres 127.0.0.1 only
|
|
1598
|
+
```
|
|
1599
|
+
|
|
1600
|
+
`shard conversations transcript <id>` (0.25.0+) prints the conversation's transcript: the agent's own Claude Code or
|
|
1601
|
+
Codex JSONL, byte for byte, for a working, parked or finished conversation alike, without waking its VM. `--follow`
|
|
1602
|
+
keeps printing lines as the agent writes them; `--offset` starts at a byte offset and `--session` reads an earlier
|
|
1603
|
+
session. `shard conversations events <id>` (0.25.0+) follows the conversation live: its state, new transcript lines,
|
|
1604
|
+
tool calls and the reply as it streams; `--json` prints one event per line.
|
|
1605
|
+
|
|
1606
|
+
```sh
|
|
1607
|
+
shard c transcript conv_k3m5q7s2u4w6y3b5d7f2h4j6ln > session.jsonl
|
|
1608
|
+
shard c transcript conv_k3m5q7s2u4w6y3b5d7f2h4j6ln --follow | jq -c 'select(.type=="assistant")'
|
|
1609
|
+
shard c events conv_k3m5q7s2u4w6y3b5d7f2h4j6ln
|
|
1610
|
+
# state: working
|
|
1611
|
+
# Looking at the login test.
|
|
1612
|
+
# tool: Read login.test.ts (pending)
|
|
1613
|
+
# tool: Read login.test.ts (completed)
|
|
1614
|
+
# state: done
|
|
1615
|
+
```
|
|
1616
|
+
|
|
1562
1617
|
|
|
1563
1618
|
Desktop project connections (0.14.0+): `shard agents open codex-app <project>/<workspace>` and
|
|
1564
1619
|
`shard agents open claude-desktop <project>/<workspace>` register **Shardflux · <project>** in the app.
|
|
@@ -1568,6 +1623,78 @@ Conversation JSON includes `join_mode` and the worktree used by reviewers and wo
|
|
|
1568
1623
|
|
|
1569
1624
|
`shard conversations resume <id>` continues a saved conversation in a fresh VM under the same identity (0.14.0+). `shard ./ --resume` uses this same path. `shard conversations reader <project-id>` opens a small read-only workspace for saved branches and transcripts; the Mac transcript mirror opens it automatically when no project VM is live. Adaptive idle reclaims the reader.
|
|
1570
1625
|
|
|
1626
|
+
`shard conversations delete <id> --yes` (0.25.0+) deletes a conversation everywhere at once: its agent stops, its
|
|
1627
|
+
computer is deleted (a computer other conversations share stays for them), and its messages, transcript and branch go
|
|
1628
|
+
with it, on every device. From then on it leaves every list and reads not found; `shard c feed` shows it once as
|
|
1629
|
+
`deleted`. The person who started it and organization owners and admins delete conversations. `--json` prints the
|
|
1630
|
+
API's answer: `{id, deleted, deleted_at, operation}`, where `operation` is the deletion of its computer.
|
|
1631
|
+
|
|
1632
|
+
```sh
|
|
1633
|
+
shard c delete conv_k3m5q7s2u4w6y3b5d7f2h4j6ln --yes
|
|
1634
|
+
# Deleted: conv_k3m5q7s2u4w6y3b5d7f2h4j6ln
|
|
1635
|
+
```
|
|
1636
|
+
|
|
1637
|
+
### Route input and ask about your work (0.25.0+)
|
|
1638
|
+
|
|
1639
|
+
`shard route` reads a line of input the way the board's input bar does: which project it belongs to (or your home),
|
|
1640
|
+
whether it is a new task, a question or a steer for an open task, and each task in your own words when it asks for
|
|
1641
|
+
several. `shard ask` answers a quick question about your work from the board, printing the answer as it is written.
|
|
1642
|
+
|
|
1643
|
+
```sh
|
|
1644
|
+
shard route fix the hero image on the landing page and add a GPU row to the pricing table
|
|
1645
|
+
# 2 tasks in site
|
|
1646
|
+
# 1. Fix the landing page hero image
|
|
1647
|
+
# fix the hero image on the landing page
|
|
1648
|
+
# 2. Add a GPU pricing row
|
|
1649
|
+
# add a GPU row to the pricing table
|
|
1650
|
+
shard route --task task_healthzhealthzhealthzhealt return 503 instead of 500 when the database is down
|
|
1651
|
+
# steer task_healthzhealthzhealthzhealt in status-board
|
|
1652
|
+
# return 503 instead of 500 when the database is down
|
|
1653
|
+
shard ask what is the healthz work doing right now
|
|
1654
|
+
# Your “Add /healthz endpoint” agent is working on shard/healthz with 2 commits and was last active 4 minutes ago. …
|
|
1655
|
+
```
|
|
1656
|
+
|
|
1657
|
+
Signed in, both read every project of your organization (`--org <id|slug>` when you belong to several, `--project` to
|
|
1658
|
+
lean to one); with `SHARDFLUX_API_KEY` set they read that key's project. `--task` names the selected task. `--json`
|
|
1659
|
+
prints the API's object: the route (`kind`, `parts`, `task_ref`, `uncertain`, …) or the whole answer (`text`,
|
|
1660
|
+
`needs_work`, `sources`, …). An answer that needs work ends with "Make it a task?". Neither starts work or wakes a
|
|
1661
|
+
computer.
|
|
1662
|
+
|
|
1663
|
+
### Transcribe a recording (0.25.0+)
|
|
1664
|
+
|
|
1665
|
+
`shard transcribe <file>` prints what a recording says. `--words` adds each word with its start and end; `--json`
|
|
1666
|
+
prints the transcript (`text`, `words` with `w`, `start` and `end` in seconds, `language`, `duration`).
|
|
1667
|
+
|
|
1668
|
+
```sh
|
|
1669
|
+
shard transcribe note.webm
|
|
1670
|
+
# Take this sidebar, and move it over here, then make the header a bit taller, and change that color to blue.
|
|
1671
|
+
shard transcribe hello.wav --words
|
|
1672
|
+
# Move this button over here, then make that panel a little wider.
|
|
1673
|
+
# 0:00.00 0:00.18 Move
|
|
1674
|
+
# 0:00.18 0:00.44 this
|
|
1675
|
+
# …
|
|
1676
|
+
```
|
|
1677
|
+
|
|
1678
|
+
WebM/Opus and PCM WAV are read from the file; raw 16-bit mono PCM takes `--format pcm16 --sample-rate 16000`.
|
|
1679
|
+
`--language en` names the language when you know it. Up to 120 s of audio. Signed in, or with `SHARDFLUX_API_KEY`.
|
|
1680
|
+
|
|
1681
|
+
### Permission requests (0.25.0+)
|
|
1682
|
+
|
|
1683
|
+
When a conversation's agent asks before it runs a tool (Claude Code, Codex or an ACP agent), the conversation is
|
|
1684
|
+
`needs_you` and `shard conversations get` names what it waits on. Answer it from any terminal:
|
|
1685
|
+
|
|
1686
|
+
```sh
|
|
1687
|
+
shard c permissions <conversation-id> --state pending
|
|
1688
|
+
# 01a1300c-… pending Run npm test npm test
|
|
1689
|
+
shard c answer <conversation-id> <permission-id> allow # or always, deny
|
|
1690
|
+
# Allowed once: Run npm test
|
|
1691
|
+
```
|
|
1692
|
+
|
|
1693
|
+
Each line is the request id, its state, what the agent wants to do, the command, path or URL, and the decision once
|
|
1694
|
+
answered. Without `--state` every request is listed, oldest first; `--all` reads every page and `--json` prints `data`
|
|
1695
|
+
and `nextCursor`. `always` lets the agent's harness stop asking for this kind of call. The agent goes on with its turn
|
|
1696
|
+
as soon as you answer, and a parked computer wakes to take the answer.
|
|
1697
|
+
|
|
1571
1698
|
### Starting from your working state (0.22.0+)
|
|
1572
1699
|
|
|
1573
1700
|
A new conversation starts from your worktree as it is: committed history, uncommitted edits, untracked files and your
|
|
@@ -1608,6 +1735,56 @@ With CLI 0.23.0+, a full conversation key or id opens that same Claude or Codex
|
|
|
1608
1735
|
|
|
1609
1736
|
Use `shard agents open <workspace> --in auto --json` to resolve where a conversation opens: a saved target first; then, for Claude (0.15.1+), the conversation itself in Claude Desktop when it is installed (`{"target":"claude-desktop","url":"claude://code/session_…","app_bundle_id":…}`), else Claude Code in the terminal (`{"target":"terminal","command":["shard","agents","open","<workspace>"]}`; without `--json` it attaches in this terminal). Codex Cloud opens its current thread in your browser (CLI 0.23.0+). claude.ai opens with `--in web`. The caller opens the `url` or app, or runs the command in a terminal. Explicit `--in terminal` retains terminal attachment. The menu uses this resolver for new and existing conversations, without provider URLs in Swift.
|
|
1610
1737
|
|
|
1738
|
+
## The board (0.25.0+)
|
|
1739
|
+
|
|
1740
|
+
The board is one list of what you asked your agents for, the same on every device: what waits on you first, then every
|
|
1741
|
+
task in Now, Next and Later, each in your own words. The agent that does the work seals a report with its evidence, and
|
|
1742
|
+
reading the board never wakes a computer. The board commands use your project API key: the board is its project's.
|
|
1743
|
+
|
|
1744
|
+
```sh
|
|
1745
|
+
shard task add Fix the wake race in resume # your words, kept exactly; the project's master starts the work
|
|
1746
|
+
# task_h7g4d7tqyv2pz3a2npyo4rpgzq now queued
|
|
1747
|
+
shard board
|
|
1748
|
+
# Needs you
|
|
1749
|
+
# perm_01a1300c-… Run npm test? npm test
|
|
1750
|
+
#
|
|
1751
|
+
# Now
|
|
1752
|
+
# task_h7g4d7tqyv2pz3a2npyo4rpgzq working Fix the wake race in resume 01a1415f-…
|
|
1753
|
+
shard needs-you answer perm_01a1300c-… always # allow, always or deny
|
|
1754
|
+
# Always allowed: Run npm test (rule rule_ym4xywjgj7vvvrhkqlduotkvb4)
|
|
1755
|
+
shard task show task_h7g4d7tqyv2pz3a2npyo4rpgzq # the plan, then each report with its evidence
|
|
1756
|
+
shard board --follow # each change as it happens, until Ctrl-C
|
|
1757
|
+
```
|
|
1758
|
+
|
|
1759
|
+
**Tasks.** `shard task add <words...>` adds a task to Now (`--next`, `--later`), last in its bucket unless `--first` or
|
|
1760
|
+
`--after <task-id>` places it; `--home` runs a personal task on the project's machine home. `shard task edit <id>`
|
|
1761
|
+
changes the words (`--text`, and the task's master hears it), the title (`--title`), the bucket (`--now`, `--next`,
|
|
1762
|
+
`--later`) and the order (`--first`, `--after`), keeps an agent's suggestion as your own (`--keep`) or clears the task
|
|
1763
|
+
(`--clear`; `--no-clear` brings it back). `shard task steer <id> <words...>` sends steering words to the task's master,
|
|
1764
|
+
`shard task rm <id>` deletes the task, and `shard task clear-done` clears every finished one. `shard task show <id>`
|
|
1765
|
+
prints the task, its plan and each report: milestone, outcome and evidence (`tests 12/12 (pnpm test)`).
|
|
1766
|
+
`shard task land <id>` lands a finished task: its result (the branch `shard/<task id>`, where its master merged its
|
|
1767
|
+
workers' branches) goes into the project's default branch and into your folder on this computer the way finished
|
|
1768
|
+
conversations land there (your uncommitted edits stay), and the board shows it shipped once the commit is in the
|
|
1769
|
+
branch: `Landed in ~/code/best-todo · 3f2a1c9`.
|
|
1770
|
+
|
|
1771
|
+
**Needs you.** `shard needs-you` lists permission requests, questions, credential requests, finished work to land and
|
|
1772
|
+
Later tasks to keep, oldest first. `shard needs-you answer <id>` answers any of them: `allow`, `always` (also adds the
|
|
1773
|
+
always-allow rule for the project; `--everywhere` for every project) or `deny` for a permission request, `--pick` for an
|
|
1774
|
+
agent's question in one, `--text` for a question, `land` (as `shard task land`), `keep` or `discard` for finished work, and `--keep <task-id>`
|
|
1775
|
+
(or `keep`, `discard`) for Later tasks. The agent goes on as soon as you answer.
|
|
1776
|
+
|
|
1777
|
+
**Approvals.** The approval mode answers your agents' permission requests before they reach you: `ask` sends every one
|
|
1778
|
+
to you, `routine` (the default) approves tests, builds, reads and installs, `trusted` approves everything except
|
|
1779
|
+
deploys, pushes to main and spending. `shard approvals` shows the modes and rules. `shard approvals set <mode>` sets the
|
|
1780
|
+
project's mode (`--project <id>`; `default` puts it back on the default mode), `shard approvals allow <tool>
|
|
1781
|
+
<pattern...>` always allows a tool for commands that start with the pattern (`shard approvals allow Bash pnpm test`),
|
|
1782
|
+
and `shard approvals remove <rule-id>` removes a rule. Requests already waiting that a new mode or rule covers are
|
|
1783
|
+
answered at once.
|
|
1784
|
+
|
|
1785
|
+
Each line is one item, tab-separated, id first. `--json` prints the API's objects; `shard board --follow --json` prints
|
|
1786
|
+
the board on its first line, then one feed answer per line.
|
|
1787
|
+
|
|
1611
1788
|
## Codex Cloud (0.15.0+)
|
|
1612
1789
|
|
|
1613
1790
|
New Codex conversations use `shard agents new --app codex --path <directory>` or `shard ./ codex`. Each gets a fresh conversation VM and a genuine Codex Cloud thread. `shard agents open <conversation-id>` opens the existing thread without waking its VM. These paths create no SSH device entries and need no pairing.
|
|
@@ -1633,10 +1810,95 @@ Older clients read the same session response fields.
|
|
|
1633
1810
|
|
|
1634
1811
|
Cloud history (0.23.0+): `shard agents open <conversation-id> --original` opens the original chat; `--history <thread-id>` opens an earlier linked chat. `--json` includes `previous_threads` with each history URL. Sign in with the Codex account that owns the selected chat.
|
|
1635
1812
|
|
|
1813
|
+
Codex accounts (0.25.0+): before opening a Cloud thread, `shard agents open` checks which ChatGPT account the Codex app on this computer is signed in to. When it is not the thread's account, it names the account to sign in as and prints the thread's web link. Earlier threads are listed with their accounts.
|
|
1814
|
+
|
|
1636
1815
|
## Complete conversation lists (0.23.1+)
|
|
1637
1816
|
|
|
1817
|
+
`shard conversations feed` (0.25.0+) prints each conversation of the project the moment it changes, until you stop it:
|
|
1818
|
+
`<id> <title> <state>`, or with `--json` one `{conversation, cursor}` object per line (`--cursor` continues after
|
|
1819
|
+
it). `shard conversations list --updated-after <time>` lists only conversations changed since then. Titles show the
|
|
1820
|
+
agent's own short name for a conversation once it has one (`title_short`).
|
|
1821
|
+
|
|
1822
|
+
Signed in (`shard auth login`) without an API key, `shard conversations list` and `shard conversations feed` (0.25.0+)
|
|
1823
|
+
cover every project you work in, across your organizations, with one cursor; `--org <id|slug>` narrows them to one
|
|
1824
|
+
organization and `--project` to one project. With an API key they cover the key's project, and `--org` uses your
|
|
1825
|
+
sign-in when you have one:
|
|
1826
|
+
|
|
1827
|
+
```sh
|
|
1828
|
+
shard c list --org acme --state needs_you
|
|
1829
|
+
shard c feed --org acme --json
|
|
1830
|
+
```
|
|
1831
|
+
|
|
1638
1832
|
`shard conversations list --all` reads every page, keeping the selected project, state and parent filters. `--json` returns `data` and `nextCursor`. Linux desktop 0.1.11+ reads all conversation and computer pages and shows the selected project key’s organization, usage, spend and connector status in Settings.
|
|
1639
1833
|
|
|
1834
|
+
## Project drive (0.25.0+)
|
|
1835
|
+
|
|
1836
|
+
`shard drive` keeps a project's files: the screenshots, logs, reports and notes your agents and people save and read by
|
|
1837
|
+
path, the same from a phone, a script or another agent whether the project's computers are working, asleep or gone.
|
|
1838
|
+
Paths are relative to the project space root, the names agents see under `/shardflux/project`
|
|
1839
|
+
(`tasks/t_ab12/evidence/healthz.png`, `BOARD.md`).
|
|
1840
|
+
|
|
1841
|
+
```sh
|
|
1842
|
+
shard drive put ./out/healthz.png tasks/t_ab12/evidence/healthz.png
|
|
1843
|
+
# Saved tasks/t_ab12/evidence/healthz.png (48.2 KB, image/png)
|
|
1844
|
+
# sha256 <sha256>
|
|
1845
|
+
shard drive put BOARD.md # saved as BOARD.md
|
|
1846
|
+
git diff | shard drive put - tasks/t_ab12/review.diff
|
|
1847
|
+
shard drive ls tasks/t_ab12/
|
|
1848
|
+
# SIZE SAVED TYPE PATH
|
|
1849
|
+
# 48.2 KB 2026-10-15 23:13:47Z image/png tasks/t_ab12/evidence/healthz.png
|
|
1850
|
+
# 24 bytes 2026-10-15 23:13:48Z text/markdown; charset=utf-8 tasks/t_ab12/notes.md
|
|
1851
|
+
shard drive get tasks/t_ab12/evidence/healthz.png -o healthz.png
|
|
1852
|
+
shard drive get tasks/t_ab12/notes.md --sha256 <sha256> # exactly that version
|
|
1853
|
+
shard drive rm tasks/t_ab12/notes.md
|
|
1854
|
+
```
|
|
1855
|
+
|
|
1856
|
+
- Every `put` is a new version named by the SHA-256 of its bytes, printed after the path; saving the bytes that are
|
|
1857
|
+
already current keeps that version. `get --sha256` reads any version, also after its path was overwritten or
|
|
1858
|
+
removed, so a report that names a file's sha256 always opens the bytes it was written with.
|
|
1859
|
+
- `get` writes the bytes to standard output, or to a file with `-o`, once they match their SHA-256; with `--json` it
|
|
1860
|
+
returns `content_base64` with `sha256`, `size` and `content_type`.
|
|
1861
|
+
- `put <local-file> [<drive-path>]`: the drive path defaults to the file's name, and `-` reads standard input. The
|
|
1862
|
+
type comes from the extension (`.png` image/png, `.md` text/markdown) unless `--content-type` names one. `--json`
|
|
1863
|
+
returns the saved `file`.
|
|
1864
|
+
- `ls [prefix]` lists the current files by path, 200 to a page (`--limit` up to 1000, `--cursor`, `--all`); `--json`
|
|
1865
|
+
returns `data` (each file with its `sha256`) and `next_cursor`.
|
|
1866
|
+
- The drive is the API key's project, or `--project <id>`. Signed in (`shard auth login`), `--project` takes any of
|
|
1867
|
+
your projects by id or slug, and without an API key the drive is your default project's.
|
|
1868
|
+
|
|
1869
|
+
## Model template (0.25.0+)
|
|
1870
|
+
|
|
1871
|
+
`shard models` shows which harness, model and effort each role of a task runs with, from the Claude and Codex accounts
|
|
1872
|
+
your organization connected: master plans and coordinates, builder does the work, hard takes the hardest parts, light
|
|
1873
|
+
the small ones and reviewer reviews with a fresh context.
|
|
1874
|
+
|
|
1875
|
+
```sh
|
|
1876
|
+
shard models
|
|
1877
|
+
# Primary: claude (connected first), secondary: codex
|
|
1878
|
+
# Connected: claude (max), codex (pro)
|
|
1879
|
+
#
|
|
1880
|
+
# ROLE HARNESS MODEL EFFORT WAITS UNTIL
|
|
1881
|
+
# master claude opus medium (plans high) -
|
|
1882
|
+
# builder claude opus high -
|
|
1883
|
+
# hard claude fable high -
|
|
1884
|
+
# light codex gpt-6.1-sol low -
|
|
1885
|
+
# reviewer codex gpt-6.1-sol medium -
|
|
1886
|
+
shard models primary codex # this project's primary
|
|
1887
|
+
shard models primary claude --org acme # the organization's default
|
|
1888
|
+
shard models primary clear
|
|
1889
|
+
```
|
|
1890
|
+
|
|
1891
|
+
- A role's harness, model and effort go straight to `shard conversations start --app <harness> --model <model>
|
|
1892
|
+
--effort <effort>` (`default`: leave out `--effort`).
|
|
1893
|
+
- `--harness claude|codex` keeps a running task's master, builder and hard work on its provider; `--attempt <n>` (1 to
|
|
1894
|
+
10) shows the template for a retry, on the other provider or one tier up.
|
|
1895
|
+
- A role whose account waits for its next usage window shows until when, and what the other provider would run now,
|
|
1896
|
+
to offer the person; nothing switches on its own.
|
|
1897
|
+
- The primary provider is the project's choice when it has one, else the organization's, else the provider connected
|
|
1898
|
+
first. `shard models primary` sets the project's (owners and admins, or the project's API key), and with `--org` the
|
|
1899
|
+
organization's default (owners and admins, signed in); `clear` removes the choice. `--json` returns the template:
|
|
1900
|
+
`primary`, `primary_source`, `secondary`, `connected` and `roles`.
|
|
1901
|
+
|
|
1640
1902
|
## Default shared volumes (0.24.0+)
|
|
1641
1903
|
|
|
1642
1904
|
```sh
|
package/dist/account-args.js
CHANGED
|
@@ -269,6 +269,11 @@ export const ACCOUNT_COMMANDS = [
|
|
|
269
269
|
options: { confirm: { type: 'string', value: '<slug>', description: 'The organization’s slug, typed out (required).' }, ...YES('the deletion') },
|
|
270
270
|
},
|
|
271
271
|
{ path: ['projects', 'list'], summary: 'List the organization’s projects (* marks the default)', positionals: [], options: { ...ORG } },
|
|
272
|
+
{ path: ['projects', 'link'], summary: 'Make a local folder one of your projects, prepared in the background and kept as this computer’s live copy (0.25.0+)', positionals: [{ name: 'path', required: true }], options: {
|
|
273
|
+
prompt: { type: 'string', value: '<text>', description: 'Also start a conversation in that folder with this first message.' },
|
|
274
|
+
'prompt-file': { type: 'string', value: '<file|->', description: 'Read that first message from a UTF-8 file or stdin (-), up to 256 KiB.' },
|
|
275
|
+
app: { type: 'string', value: '<claude|codex>', description: 'Agent app of that conversation (default claude).' },
|
|
276
|
+
} },
|
|
272
277
|
{ path: ['projects', 'sync', 'list'], summary: 'Show selected local projects and their preparation state', positionals: [], options: {} },
|
|
273
278
|
{ path: ['projects', 'sync', 'add'], summary: 'Prepare and keep this selected local project synced', positionals: [{ name: 'path', required: true }], options: { wait: { type: 'boolean', description: 'Prepare now and wait for its published environment; otherwise the device helper prepares it in the background.' } } },
|
|
274
279
|
{ path: ['projects', 'sync', 'pause'], summary: 'Pause background preparation of this local project', positionals: [{ name: 'path', required: true }], options: {} },
|
package/dist/account-pool.js
CHANGED
|
@@ -2,6 +2,7 @@ import { out, resolveWorkspace } from "./commands.js";
|
|
|
2
2
|
import { UsageError } from "./errors.js";
|
|
3
3
|
import { claudeLoginUrls, requireClaudeTerminal, runWorkspaceLogin } from "./claude-cloud-login.js";
|
|
4
4
|
import { openMachine } from "./filesystem-commands.js";
|
|
5
|
+
import { codexAppAccountNotice } from "./codex-cloud.js";
|
|
5
6
|
const PROVIDERS = { claude: 'Claude', codex: 'ChatGPT / Codex' };
|
|
6
7
|
const WINDOW_LABELS = { five_hour: '5-hour', seven_day: 'Weekly', seven_day_opus: 'Weekly Opus', seven_day_sonnet: 'Weekly Sonnet', primary: 'Primary', secondary: 'Secondary' };
|
|
7
8
|
/** A window's length as a title, as Claude's windows read: "Weekly", "5-hour", "2-day", "90-minute". */
|
|
@@ -245,7 +246,10 @@ export const ACCOUNT_POOL_HANDLERS = {
|
|
|
245
246
|
const follows = account.provider === 'claude'
|
|
246
247
|
? 'New conversations start with it; running ones continue on it, and Remote Control turns back on by itself.'
|
|
247
248
|
: `New conversations and every running conversation VM use it; Codex Cloud moves to it${previous ? ` (Cloud threads started on ${name(previous)} stay in that ChatGPT account)` : ''}.`;
|
|
248
|
-
|
|
249
|
+
// codex_app (0.25.0+): the Codex app here opens the account's Cloud threads only once it is signed in to it.
|
|
250
|
+
const app = account.provider === 'codex' ? await codexAppAccountNotice(ctx, active) : null;
|
|
251
|
+
out(ctx, (previous || !isActive(account) ? `${name(active)} is the active ${PROVIDERS[account.provider]} account. ${follows}\n` : `${name(active)} is already the active ${PROVIDERS[account.provider]} account.\n`)
|
|
252
|
+
+ (app?.line ? `${app.line}\n` : ''), { ...list, account: active, ...(account.provider === 'codex' ? { codex_app: app ? { login: app.login, notice: app.line } : null } : {}) });
|
|
249
253
|
return 0;
|
|
250
254
|
},
|
|
251
255
|
};
|
package/dist/acp-journal.js
CHANGED
|
@@ -90,6 +90,28 @@ export class AcpJournal {
|
|
|
90
90
|
}
|
|
91
91
|
#wanted() { return !this.#signal.aborted && !this.rpc.closed && this.#paused === 0 && (this.rpc.busy || this.#cursor.prompt_id !== undefined); }
|
|
92
92
|
async #deliver(inputId, message) {
|
|
93
|
+
let failures = 0;
|
|
94
|
+
const started = performance.now();
|
|
95
|
+
while (true) {
|
|
96
|
+
this.#signal.throwIfAborted();
|
|
97
|
+
try {
|
|
98
|
+
return await this.#deliverOnce(inputId, message);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
// Guest restarts can refuse a new input command while its native
|
|
102
|
+
// supervisor keeps running. Its persisted receipt deduplicates this
|
|
103
|
+
// exact input id, including a command accepted before the refusal.
|
|
104
|
+
// An unverified receipt or a permanent error still stops delivery.
|
|
105
|
+
if (!(error instanceof ShardfluxApiError) || !error.retryable)
|
|
106
|
+
throw error;
|
|
107
|
+
const remaining = RECONNECT_BUDGET_MS - (performance.now() - started);
|
|
108
|
+
if (remaining <= 0)
|
|
109
|
+
throw new Error('ACP input reconnect timed out; load this session to continue.', { cause: error });
|
|
110
|
+
await delay(Math.min(reattachDelayMs(error, ++failures), remaining), undefined, { signal: this.#signal });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async #deliverOnce(inputId, message) {
|
|
93
115
|
const dir = `/home/user/.local/share/shardflux/acp/${this.#conversation}`;
|
|
94
116
|
const payload = Buffer.from(`{"mode":"input","input_id":${JSON.stringify(inputId)},"message":${message}}\n`);
|
|
95
117
|
if (payload.length <= ONE_SHOT_INPUT) {
|
|
@@ -133,7 +155,7 @@ export class AcpJournal {
|
|
|
133
155
|
finally {
|
|
134
156
|
await this.#cell.exec.cancel(session.session_id, 0).catch(() => undefined);
|
|
135
157
|
}
|
|
136
|
-
//
|
|
158
|
+
// Retries retain inputId: CVB persists its receipt before provider stdin.
|
|
137
159
|
}
|
|
138
160
|
start() {
|
|
139
161
|
this.#initial ??= this.#replay().then(() => { this.#ready = true; this.#follow(); }).catch(error => { this.rpc.close(error instanceof Error ? error : new Error(String(error))); throw error; });
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ConversationPermission } from '@shardflux/sdk';
|
|
2
|
+
import type { ObjectValue } from './acp-rpc.js';
|
|
3
|
+
/** The part of the SDK client the watch reads: GET /v1/conversations/{id}/permissions (0.28.0+). */
|
|
4
|
+
export interface PermissionsReader {
|
|
5
|
+
conversations: {
|
|
6
|
+
permissions(id: string, p: {
|
|
7
|
+
state?: ConversationPermission['state'];
|
|
8
|
+
limit?: number;
|
|
9
|
+
cursor?: string;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
data: ConversationPermission[];
|
|
12
|
+
nextCursor: string | null;
|
|
13
|
+
}>;
|
|
14
|
+
permission(id: string, permissionId: string): Promise<ConversationPermission>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** How often the watch reads the API while the editor's permission prompt is open (it never touches the VM). */
|
|
18
|
+
export declare const ELSEWHERE_POLL_MS = 1500;
|
|
19
|
+
/** The tool and command, path or URL the guest records for an ACP permission request (services/guest-agent ACPPermissionAsk). */
|
|
20
|
+
export declare function requestIdentity(params: ObjectValue): {
|
|
21
|
+
tool: string | null;
|
|
22
|
+
detail: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* While the editor shows the agent's permission prompt, the journal relay is paused, so nothing else of the turn reaches
|
|
26
|
+
* the editor. The same request is listed through the API, where a person can answer it too (the Shard client, the CLI,
|
|
27
|
+
* MCP). This resolves with the request once it leaves `pending` that way (answered through the API, or closed because
|
|
28
|
+
* the agent no longer waits), so the relay can withdraw the editor's prompt and go on with the turn. The request is the
|
|
29
|
+
* newest one of the conversation with the prompt's tool and command, path or URL that was reported as the prompt opened
|
|
30
|
+
* or still waits. It resolves null on an API without permission requests (404, 503) or when `signal` ends the prompt;
|
|
31
|
+
* other errors are retried.
|
|
32
|
+
*/
|
|
33
|
+
export declare function answeredElsewhere(client: PermissionsReader, conversationId: string, params: ObjectValue, openedAt: number, signal: AbortSignal, pollMs?: number): Promise<ConversationPermission | null>;
|
|
34
|
+
/**
|
|
35
|
+
* The editor-side answer matching a request answered elsewhere: the option of its decision's kind (as the guest picks
|
|
36
|
+
* it), or a cancelled outcome. The agent already has the first answer; this one only completes the relayed request.
|
|
37
|
+
*/
|
|
38
|
+
export declare function outcomeFor(p: ConversationPermission, params: ObjectValue): ObjectValue;
|