@ashrlabs/ashr 0.1.0 → 0.2.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/README.md CHANGED
@@ -1,22 +1,57 @@
1
1
  # ashr
2
2
 
3
- The Ashr terminal interface. By default it connects to the same hosted Manifold
4
- tasks, chats, files, skills, memory, command queue and approvals as the browser.
5
- Use `--local` for the separate agent that runs in your repository on your machine.
3
+ The Ashr terminal for post-training models. The npm package is `ashr init`, which
4
+ connects a Docker host (your laptop or a cloud VM) and your ChatGPT plan to your Ashr
5
+ workspace, and the terminal to the hosted agent. The agent, its harness and its
6
+ built-in skills run on Ashr's side and are not in the package. The local agent
7
+ described below is in source and `ASHR_LOCAL=1 npm run build` builds only.
6
8
 
7
9
  ## Install
8
10
 
9
11
  ```
10
- npm i -g @ashrlabs/ashr # then run: ashr
11
- npx @ashrlabs/ashr # try it without installing
12
+ npm i -g @ashrlabs/ashr # then run: ashr init, then ashr
12
13
  ```
13
14
 
14
- Needs Node 22.19 or newer.
15
+ The npm package needs Node 22.19 or newer. To build a standalone executable from
16
+ this checkout, use an official Node binary with single executable support
17
+ (Homebrew's Node does not provide it):
18
+
19
+ ```sh
20
+ cd cli
21
+ npm ci
22
+ ASHR_SEA_NODE=/path/to/official/node npm run build:binary
23
+ ```
24
+
25
+ `ASHR_SEA_NODE` defaults to the Node running the build. The build targets that
26
+ binary's platform and architecture and writes `dist-bin/ashr-<platform>-<arch>`.
27
+ Copy that executable into a directory on your `PATH` as `ashr`; it bundles the
28
+ Node runtime, JavaScript dependencies and subscription sign-in flows, so no
29
+ separate Node installation is needed to run it. Optional native clipboard and
30
+ image helpers are excluded. macOS builds also require `codesign`.
31
+
32
+ `ashr update` reruns the public install script into the directory of the running
33
+ binary (through symlinks), replacing it in place; restart ashr afterwards. It
34
+ refuses on npm or source installs, which update through npm or git. In a running
35
+ session, `/update` does the same and shows the installer's output. The binary
36
+ checks at most once a day whether the latest build's checksum differs from the
37
+ one the installer recorded, and if so shows a one-line notice at startup; a
38
+ failed check is silent.
39
+
40
+ Both the local agent and hosted workspace use the same TUI components: tool
41
+ arguments, highlighted code, file diffs, live command output and Markdown
42
+ subagent reports. Ctrl-T hides or shows reasoning. Ctrl-O expands or collapses
43
+ the most recently completed tool output or subagent report.
15
44
 
16
45
  ## Hosted Manifold
17
46
 
47
+ The npm package always reaches Ashr's hosted workspace, where plain `ashr`
48
+ opens it (no `--hosted` needed). The standalone binary reaches it only when
49
+ built with `ASHR_HOSTED=1`; otherwise it uses these commands only against a
50
+ [self-hosted server](#self-hosted-server).
51
+
18
52
  ```
19
- ashr sign in (first run only) and open the hosted workspace
53
+ ashr --hosted sign in (first run only) and open the hosted workspace
54
+ ashr --hosted -c reopen the most recently updated hosted chat
20
55
  ashr --task support select a task
21
56
  ashr --task support --chat ID open the same chat as the browser
22
57
  ashr --service require MANIFOLD_API_KEY or a saved key; never opens a browser
@@ -25,13 +60,14 @@ ashr login --key ask_… save a service key instead
25
60
  ashr logout forget the saved sign-in
26
61
  ```
27
62
 
28
- On first launch `ashr` opens the dashboard's `/terminal` page. Sign in, pick
63
+ On first launch `ashr --hosted` (or `ashr login`) opens the dashboard's `/terminal` page. Sign in, pick
29
64
  the organization, and click **Connect terminal**. The dashboard mints a key for
30
65
  this terminal (labelled `Terminal · <hostname>` under API keys) and hands it
31
66
  back once to a loopback listener. The terminal saves it to
32
- `~/.ashr/credentials.json` (mode 600), and you can close the tab. Later launches
33
- open the workspace directly. If the key is revoked, `ashr` asks you to sign in
34
- again. If the browser doesn't open, use the printed URL.
67
+ `~/.ashr/credentials.json` (mode 600), and you can close the tab. Later hosted
68
+ launches reuse the saved key; outside the npm package, plain `ashr` starts the local agent.
69
+ If the key is revoked, a hosted launch asks you to sign in again. If the browser
70
+ doesn't open, use the printed URL.
35
71
 
36
72
  `--api-url`/`MANIFOLD_API_URL` and `--dashboard-url`/`MANIFOLD_DASHBOARD_URL`
37
73
  select matching deployments. `MANIFOLD_API_KEY` or `--key` override the saved
@@ -42,6 +78,17 @@ settings in the browser. `/login` signs in again (for example to switch
42
78
  organization) and clears the old task/chat selection. `/logout` forgets the
43
79
  saved key.
44
80
 
81
+ `/github` opens GitHub's fine-grained token form to connect a repository for
82
+ cloning, branch pushes and pull requests. Select the repository, generate the
83
+ token and paste it into the terminal prompt. `/github off` removes the agent's
84
+ access; revoke the token in GitHub to invalidate the token itself.
85
+
86
+ A hosted launch opens the chat selected with `--chat ID`, or the most recently
87
+ updated chat in scope with `--continue` (`-c`). Otherwise the first message
88
+ starts a new chat named after its first line. `--chat` and `--continue` cannot
89
+ be combined. `/chats` opens a searchable picker; `/model`, `/thinking` and
90
+ `/fork` without arguments also open pickers.
91
+
45
92
  Use `/help` for the complete command reference. Hosted controls include:
46
93
 
47
94
  - `/tasks`, `/task NAME`, `/chats SEARCH`, `/new NAME`, `/open ID`, `/rename NAME`, `/fork NAME [SEQ]`.
@@ -51,18 +98,101 @@ Use `/help` for the complete command reference. Hosted controls include:
51
98
  - `/pipelines`, `/sources`, `/datasets`, `/evals`, `/benchmarks`, `/experiments`, `/models`, `/monitoring`, `/interactions`, `/uploads`, `/artifacts`, `/serving`, `/sdk`.
52
99
 
53
100
  Hosted `!COMMAND` runs in the hosted workspace; `!!COMMAND` excludes its output
54
- from model context. Escape stops active hosted work or pauses a local transfer.
101
+ from model context.
102
+ Escape stops active hosted work or pauses a local transfer.
55
103
  Ctrl-C stops active hosted work; when idle it disconnects. `/quit` disconnects
56
104
  while leaving hosted jobs running. `/pending` and `/retry` recover uncertain
57
- submissions without changing their request IDs. Upload receipts support resume.
105
+ submissions without changing their request IDs. A busy-chat `409 Chat changed`
106
+ response is retried automatically with the same request ID. Upload receipts support resume.
58
107
 
59
108
  Dashboard writes require the command's explicit `--confirm` flag. The terminal
60
109
  covers serving, training and evaluation environments. Organization, member and
61
110
  API-key administration stay in the dashboard; `/org` opens it.
62
111
 
63
- ## Local model keys
112
+ ## Your own machines
113
+
114
+ To have the Ashr agent work on your own Docker host (your repo, data, checkpoints
115
+ and GPUs stay there), run this on that host; it needs no ashr CLI:
116
+
117
+ ```
118
+ curl -fsSL https://api.manifold.ashr.io/v1/runner/install.sh | ASHR_API_KEY=ask_… sh
119
+ ```
120
+
121
+ or, with the CLI installed:
122
+
123
+ ```
124
+ ashr init # uses ASHR_API_KEY, your `ashr login` key, else your personal workspace
125
+ ashr init --yes # no questions (no sign-in or ChatGPT connection), GPUs used if found
126
+ ```
64
127
 
65
- ashr uses your own model provider key. Set it in your shell, or store it once:
128
+ With no organization key, `ashr init` uses your personal workspace through this
129
+ terminal's ashr account (signing in first) and connects your ChatGPT plan, which
130
+ its agent runs on ([`docs/personal-workspaces.md`](../docs/personal-workspaces.md)).
131
+ It checks Docker, Compose v2 and any NVIDIA GPUs, registers the host as the
132
+ workspace's runner, writes `~/.ashr/runner/` (`docker-compose.yml` and a
133
+ mode-0600 `.env` with the runner's token), pulls the runner and sandbox images
134
+ at this ashr's version from Ashr's private registry, starts the runner, and
135
+ checks one sandbox command end to end. The agent stays on Ashr; the runner dials
136
+ out to it and runs the agent's sandboxes on this host. Run it again with a newer
137
+ ashr to upgrade in place. Details in [`deploy/runner/README.md`](../deploy/runner/README.md).
138
+
139
+ ## Self-hosted server (air-gapped)
140
+
141
+ The full server on one host, for deployments that cannot reach Ashr at all, is set
142
+ up from a checkout by agreement: [`deploy/selfhost/README.md`](../deploy/selfhost/README.md).
143
+ ashr can also talk to an Ashr server running on your own host; a standalone
144
+ binary built without `ASHR_HOSTED=1` talks to no other. The server listens on `127.0.0.1:8080`
145
+ only, so from another machine forward the port first, then sign in once with the
146
+ server's admin key (`docker compose -p ashr exec -T api cat /state/admin-key` on
147
+ the host):
148
+
149
+ ```
150
+ ssh -L 8080:localhost:8080 <host> # keep this open
151
+ ashr login --key ask_… --api-url http://localhost:8080
152
+ ashr # opens the server's workspace
153
+ ashr --local # the local agent instead (not in the npm package)
154
+ ```
155
+
156
+ Once signed in, plain `ashr` opens the server's workspace, and the hosted
157
+ commands above (`--task`, `--chat`, `-c`, `/chats`, …) work against it.
158
+ `MANIFOLD_API_URL` works in place of `--api-url`. Plain `http` is refused for
159
+ anything but `localhost`: use the port-forward, or put TLS in front of the
160
+ server and pass its `https` URL. There is no browser sign-in, and `/github` is
161
+ not available on self-hosted servers yet.
162
+
163
+ ## Your account
164
+
165
+ The first time you run `ashr` in a terminal it opens your browser to sign in (any email; no organization). The
166
+ terminal keeps its own key in `~/.ashr/credentials.json` and doesn't ask again. The account page,
167
+ https://manifold.ashr.io/cli (or `/account` in a session), shows your sessions, turns, tokens and cost over the last
168
+ 30 days, and has a button for booking an upgrade call. Print mode (`ashr -p`) and scripts without a terminal never
169
+ stop to sign in.
170
+
171
+ Over SSH the browser can't reach the terminal, so `ashr` prints a link to open on any machine instead; after you
172
+ connect, the page shows a code to paste back into the terminal. In a container or any other terminal the browser
173
+ can't reach, press Enter while `ashr` waits to switch to that link and code. If sign-in fails (offline, say), `ashr` starts
174
+ without an account and asks again next run.
175
+
176
+ The account is who you are, not your model: sign in to a model below. Usage on the account page comes from the usage
177
+ data ashr sends (see [Usage data](#usage-data)); with it off, nothing is recorded there.
178
+
179
+ ## Your model
180
+
181
+ Sign in with the subscription you already have:
182
+
183
+ ```
184
+ ashr login chatgpt # ChatGPT Plus/Pro, through OpenAI's Sign in with ChatGPT
185
+ ashr login codex # ChatGPT through the Codex sign-in
186
+ ashr login claude # Claude Pro/Max
187
+ ashr logout chatgpt
188
+ ```
189
+
190
+ The sign-in stays on your machine (`~/.ashr/agent/auth.json`) and goes only to the provider.
191
+ With a ChatGPT sign-in ashr runs GPT-6 Astra; with Claude or an Anthropic key, Claude Fable.
192
+ If your ChatGPT workspace blocks third-party apps but allows Codex, use
193
+ `ashr login codex`. Saved sign-ins are available when the local agent starts.
194
+
195
+ Or use a provider key. Set it in your shell, or store it once:
66
196
 
67
197
  ```
68
198
  export ANTHROPIC_API_KEY=sk-… # or OPENAI_API_KEY, GEMINI_API_KEY
@@ -71,34 +201,78 @@ ashr login --provider anthropic # stores it in ~/.ashr/credentials.json (
71
201
 
72
202
  A key set in your shell always wins over a stored one. Keys are never passed to the commands the agent runs.
73
203
 
74
- `ashr login` opens a human Manifold workspace. It does not store a provider key.
204
+ `ashr login` without a provider does not store a model key: the published builds
205
+ refuse it with exit 2 and point at the model sign-ins above.
75
206
 
76
207
  ## Using the local agent
77
208
 
78
209
  ```
79
- ashr --local new session in this repo
210
+ ashr new local session in this repo (--local is also accepted)
80
211
  ashr -c continue the latest session here
81
212
  ashr -r pick a session to resume
82
- ashr -p "<prompt>" one turn, printed (for scripts and CI)
213
+ ashr -p "<prompt>" one turn, printed (for scripts and CI); waits for its subagents
214
+ ashr -c -p "<prompt>" continue the latest session in print mode
215
+ ashr init run the agent's sandboxes on this Docker host; see Your own machines
83
216
  ```
84
217
 
85
- While the agent works, Enter steers it, Option-Enter queues a message for when it finishes, and Esc stops it. When an approval is waiting, `a` approves, `r` rejects and `A` always allows; Tab switches to the input box so you can type a message instead. Ctrl-O shows the full output of the last tool. Type `/` for commands: `/usage`, `/permissions` (and `/permissions remove <rule>`), `/resume`, `/fork`, `/rewind`, `/compact`, `/model`, `/mode`, `/add-dir`, `/help`.
218
+ To set a repo up, run `ashr` in it and type `/init`: the agent reads the repo, checks
219
+ this machine against the environment probe, asks you once for what it could not find,
220
+ and writes `## Commands` and `## Setup` in `ASHR.md`. It asks before installing
221
+ anything, creating environments, downloading models or data, or submitting jobs
222
+ (`/init` is refused while the agent is working).
223
+
224
+ The local agent is the same durable harness as the hosted one. A session's transcript is a SQLite file, so a session
225
+ you quit (or that was killed) picks up where it stopped with `ashr -c`, work in flight included.
226
+
227
+ ### Subagents
228
+
229
+ The agent can hand independent pieces of work to subagents that run in parallel on your machine. Each subagent works
230
+ in its own git worktree, a snapshot of the agent's working tree (uncommitted and untracked files included, ignored files
231
+ left out) on its own branch `ashr/<session>-<name>-<id>`, so subagents change code without touching your checkout or each
232
+ other's. Each one commits on its branch and reports back; the agent reviews the branches and merges what works. The
233
+ worktrees live under `~/.ashr/worktrees/`, outside your repo; `git worktree list` shows them and `git worktree remove`
234
+ cleans one up. Subagents need the repo to be a git repository. A subagent runs the executor model of the agent's
235
+ maker (Claude Sonnet under Claude, GPT-6.1 Sol under ChatGPT or OpenAI), on the same subscription or key. `/rewind`
236
+ stops the subagents of the turns it drops, and `/fork` is refused until the agent and its subagents are done.
237
+
238
+ While the agent works, Enter steers it, Option-Enter queues a message for when it finishes, and Esc stops it. When an approval is waiting, `a` approves, `r` rejects and `A` always allows; Tab switches to the input box so you can type a message instead. Type `/` for commands: `/init`, `/usage`, `/account`, `/permissions` (and `/permissions remove <rule>`), `/resume`, `/fork`, `/rewind`, `/compact`, `/model`, `/mode`, `/add-dir`, `/update`, `/help`.
239
+
240
+ ### Skills and GPU setup
241
+
242
+ Local sessions include the hosted skill catalog in the CLI bundle; no separate
243
+ skill installation is needed. Add your own skills as `<name>/SKILL.md` inside
244
+ your repo's `.ashr/skills/` or `~/.ashr/skills/` (`$ASHR_HOME/skills/` when set).
245
+ For the same name, the repo wins over your personal directory, which wins over
246
+ the built-in skill, including references from other built-in skills. The agent
247
+ receives each available skill's name, description and `SKILL.md` path; subagents
248
+ use the same skill roots. Built-in files are unpacked into a private temporary
249
+ directory (mode `0700`) for each session and removed when it closes.
250
+
251
+ At session start, the agent receives an environment summary of local GPUs
252
+ (via `nvidia-smi` or Apple Silicon detection), profilers, job launchers and cloud
253
+ CLIs on `PATH`, and concrete host names in `~/.ssh/config`. Discovery does not
254
+ log in to cloud services or contact SSH hosts. Before the first GPU, training or
255
+ profiling run, the agent is instructed to check `ASHR.md` for your setup. If it
256
+ is missing, it asks one short question based on the probe and records your
257
+ answer under `## Setup` in `ASHR.md`; later sessions reuse that answer.
86
258
 
87
259
  ## Local permissions
88
260
 
89
- Like pi, ashr runs the agent's tools without asking by default (Auto mode). It still stops and asks before:
261
+ Like pi, ashr runs the agent's tools without asking by default (Auto mode),
262
+ including outside-repo access, `git push`, force operations, `sudo` and downloaded
263
+ scripts. Deny rules still block matching actions. Spending money on Manifold
264
+ (data copies, GPU runs, evaluations, deploys) always requires approval.
90
265
 
91
- - anything that spends money on Manifold (data copies, GPU runs, evaluations, deploys)
92
- - reading or writing outside the repo, including a shell redirect to a file outside it
93
- - `git push`, force operations, `sudo`, and running a downloaded script
94
-
95
- Outside the repo covers shell commands too: a command that names a path outside the repo (for example `cat ~/.ssh/id_rsa` or `--out=/tmp/x`) asks in every mode, unless it's a directory you added with `/add-dir` or a device file under `/dev`.
266
+ In ask and edit modes, outside-repo reads and writes require approval, as do
267
+ dangerous shell commands. Outside-repo checks cover shell paths and redirects
268
+ (for example `cat ~/.ssh/id_rsa` or `--out=/tmp/x`), except directories you added
269
+ with `/add-dir` or device files under `/dev`.
96
270
 
97
271
  Prefer to approve more? Shift-Tab cycles the mode:
98
272
 
99
273
  | Mode | Runs without asking | Asks first |
100
274
  |---|---|---|
101
- | auto (default) | everything inside the repo | the stops above |
275
+ | auto (default) | everything not denied, except spending | spending on Manifold |
102
276
  | ask | reading and read-only commands (`ls`, `cat`, `grep`, `git log` …) | edits, other shell commands, connector tools |
103
277
  | edit | reads, read-only commands and edits inside the repo | other shell commands, connector tools |
104
278
 
@@ -120,17 +294,36 @@ Answering `A` on an approval saves an "always allow" rule. Rules live in three f
120
294
 
121
295
  A repo's committed rules apply only after you trust them; ashr asks the first time and again whenever they change.
122
296
 
123
- In print mode nothing can be approved interactively: a run that needs approval exits 3 and names the rule to add, for example `--allow "edit:a.txt"` (one `--allow` per part of a compound shell command), or the mode that would allow it (`--mode edit|auto` for edits, `--mode auto` otherwise). Actions that ask in every mode (spending, outside the repo, dangerous shell commands) need an interactive run.
297
+ In print mode nothing can be approved interactively: a run that needs approval exits 3 and names the rule to add, for example `--allow "edit:a.txt"` (one `--allow` per part of a compound shell command), or the mode that would allow it (`--mode edit|auto` for edits, `--mode auto` otherwise). Spending needs an interactive run because it asks in every mode.
124
298
 
125
299
  ## Where local things live
126
300
 
127
- - Sessions: `~/.ashr/sessions/<org>/<repo>/` (one JSONL file per session, plus full tool outputs and file snapshots for `/fork` and `/rewind`)
301
+ - Sessions: `~/.ashr/sessions/<org>/<repo>/<session>/` (`session.sqlite`, the transcript of the agent and its subagents; `meta.json`; file snapshots for `/fork` and `/rewind`)
302
+ - Subagent worktrees: `~/.ashr/worktrees/<repo>/<session>/<name>-<id>/`
128
303
  - `ASHR.md` in your repo and `~/.ashr/memory.md` are read into every session.
129
304
  - Set `ASHR_HOME` to keep all of this somewhere else.
130
305
 
306
+ ## Usage data
307
+
308
+ ashr sends usage data so we can see which features work and where runs fail: the commands you run, which tools the agent used and for how long, token counts and cost, errors, the model, your ashr version and OS, and a random install id. Once you are signed in, it is also sent with your account key so the account page can add up your daily totals; only those totals are kept with your account. It never sends your prompts, the agent's replies, tool arguments or tool output unless you turn each one on:
309
+
310
+ | Setting | Sends |
311
+ |---|---|
312
+ | `ASHR_TELEMETRY_LOG_PROMPTS=1` | your prompts and the agent's replies |
313
+ | `ASHR_TELEMETRY_LOG_TOOL_DETAILS=1` | tool arguments (commands, paths) |
314
+ | `ASHR_TELEMETRY_LOG_TOOL_OUTPUT=1` | tool output and subagent reports |
315
+
316
+ The same switches can go in `~/.ashr/settings.json` as `"telemetry": { "logPrompts": true, … }`. Before anything leaves your machine, ashr removes the secrets in its environment, API keys and tokens, emails, phone numbers, card numbers, IP addresses and your home directory; the Ashr API removes them again before storing anything.
317
+
318
+ - `ashr telemetry` says what is sent and where; `ashr telemetry show` prints what was last sent.
319
+ - `ashr telemetry off`, `ASHR_TELEMETRY=off` or `DO_NOT_TRACK=1` turns it off.
320
+ - `ASHR_TELEMETRY_ENDPOINT` (and `ASHR_TELEMETRY_HEADERS`, `name=value,…`) sends the same OpenTelemetry traces to your own collector, Langfuse, Arize or Datadog instead of Ashr.
321
+
131
322
  ## Parity checks
132
323
 
133
- Run `npm test`, `npm run typecheck`, and `npm run build` from `cli/`.
324
+ Run `npm test`, `npm run typecheck`, and `npm run build` from `cli/`. `npm run build`
325
+ makes the published package and fails if it would bundle agent code;
326
+ `ASHR_LOCAL=1 npm run build` makes the full ashr with the local agent.
134
327
  `npm run test:parity` starts a disposable SQLite backend and verifies both
135
328
  client contracts against real routes. Set `MANIFOLD_TEST_PYTHON` to a Python
136
329
  environment with the repository's backend test dependencies installed.