humanish 0.81.0 → 0.82.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -621
- package/dist/actor-contract.d.ts +14 -0
- package/dist/actor-contract.js.map +1 -1
- package/dist/computer-use.d.ts +8 -2
- package/dist/computer-use.js +50 -2
- package/dist/computer-use.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +13 -2
- package/dist/cua-actor-lab.js +59 -28
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/e2b-desktop-executor.d.ts +9 -1
- package/dist/e2b-desktop-executor.js +67 -4
- package/dist/e2b-desktop-executor.js.map +1 -1
- package/dist/e2b-desktop-launch.d.ts +8 -0
- package/dist/e2b-desktop-launch.js.map +1 -1
- package/dist/e2b-desktop-resources.d.ts +11 -0
- package/dist/e2b-desktop-resources.js +33 -0
- package/dist/e2b-desktop-resources.js.map +1 -0
- package/dist/e2b-terminal-lab.d.ts +2 -0
- package/dist/e2b-terminal-lab.js +64 -3
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lab-config.d.ts +4 -0
- package/dist/lab-config.js +9 -0
- package/dist/lab-config.js.map +1 -1
- package/dist/observer-data.d.ts +2 -0
- package/dist/observer-data.js +10 -1
- package/dist/observer-data.js.map +1 -1
- package/dist/openai-responses-cu.js +7 -1
- package/dist/openai-responses-cu.js.map +1 -1
- package/dist/pricing.d.ts +19 -1
- package/dist/pricing.js +43 -10
- package/dist/pricing.js.map +1 -1
- package/dist/program.js +1 -1
- package/dist/program.js.map +1 -1
- package/dist/redaction.js +9 -2
- package/dist/redaction.js.map +1 -1
- package/dist/run.d.ts +14 -2
- package/dist/run.js.map +1 -1
- package/dist/terminal-runtime.d.ts +16 -0
- package/dist/terminal-runtime.js +42 -0
- package/dist/terminal-runtime.js.map +1 -0
- package/dist/terminal-token-usage.d.ts +2 -1
- package/dist/terminal-token-usage.js +3 -2
- package/dist/terminal-token-usage.js.map +1 -1
- package/docs/architecture/state-driven-executor.md +10 -1
- package/docs/architecture/terminal-product-lane.md +35 -0
- package/docs/contracts/run-bundle.md +5 -1
- package/docs/contracts/schemas.md +17 -8
- package/docs/goals/current.md +24 -1
- package/docs/ramp/README.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,145 +21,78 @@ local checkout. Every lane is a real computer-use session on a hosted desktop;
|
|
|
21
21
|
the captions are each persona's own final report. drawDB is the application
|
|
22
22
|
studied; it is not a Humanish adopter or endorser.
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Every design decision in humanish is checked against the three people a study
|
|
27
|
-
actually involves ([docs/principles/three-roles.md](docs/principles/three-roles.md)):
|
|
28
|
-
|
|
29
|
-
- **The researcher** (usually a coding agent driving the CLI) declares the
|
|
30
|
-
protocol: personas, discrete tasks with success criteria the participant
|
|
31
|
-
never sees, and a budget set once at the study level, the way recruiting
|
|
32
|
-
decisions are made.
|
|
33
|
-
- **The stakeholder** watches through Observer, drives from `humanish tui`, and
|
|
34
|
-
reads results that carry their denominator: `2/2 reached the goal, 1 reported
|
|
35
|
-
friction; tasks: reach-signup 2/2 · read-verification-mail 2/2`.
|
|
36
|
-
- **The participant** is the persona: the subject of the study, never its
|
|
37
|
-
instrument. A participant abandoning a task is a finding about the product,
|
|
38
|
-
not a harness failure.
|
|
39
|
-
|
|
40
|
-
In practice: a two-participant study of an email-gated signup on a public
|
|
41
|
-
open-source document app completed end to end (signup, verification mail read
|
|
42
|
-
in a captured inbox, signed-in dashboard), and the keyboard-first participant
|
|
43
|
-
reported, unprompted, that the signature step could not be completed without a
|
|
44
|
-
mouse. The panel cost about $1.50 and the receipts are committed under
|
|
45
|
-
[docs/goals/email-gated-signup/receipts/](docs/goals/email-gated-signup/receipts/).
|
|
24
|
+
[Quickstart](https://humanish.dev/docs) · [Study your app](https://humanish.dev/docs/your-app) · [CLI reference](https://humanish.dev/docs/cli) · [Limits and evidence](https://humanish.dev/failure-modes)
|
|
46
25
|
|
|
47
26
|
## Install
|
|
48
27
|
|
|
28
|
+
Use **Node.js 20 or newer**, in a project directory:
|
|
29
|
+
|
|
49
30
|
```bash
|
|
50
|
-
npm
|
|
51
|
-
npx humanish init --yes
|
|
52
|
-
npx humanish run first-run # a study with no keys and no spend — about a minute
|
|
53
|
-
npx humanish run try-live # a REAL study on a hosted desktop, capped at $2
|
|
31
|
+
npm install --save-dev humanish @e2b/desktop
|
|
32
|
+
npx humanish init --yes
|
|
54
33
|
```
|
|
55
34
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
keyboard-first participants and none of the others; and, on a phone-sized desktop, a drawDB
|
|
63
|
-
relationship drag intercepted by a popover that both phone participants hit (one stopped) and no
|
|
64
|
-
desktop participant reported; in the then-shipped mobile-emulation input path, 4 of 4 TodoMVC
|
|
65
|
-
phone participants could not rename while 4 of 4 desktop newcomers finished, and Excalidraw read
|
|
66
|
-
12 of 12. **Correction, 2026-09-05:** two conformance probes found the SDK double click reset click
|
|
67
|
-
counts while direct touch opened the original TodoMVC editor in both. The historical mobile
|
|
68
|
-
failures describe Humanish's input path, not established touch-device app behavior
|
|
69
|
-
([input-fidelity receipt](docs/goals/computer-use-actor/receipts/mobile-input-conformance-2026-09-05.md)).
|
|
70
|
-
Each file states its own caveats.
|
|
71
|
-
|
|
72
|
-
`try-live` studies a real public app so that your first live run works without
|
|
73
|
-
configuring anything; point its `subject` at your own app once you have seen it
|
|
74
|
-
run. It needs `E2B_API_KEY`, and a model: either a provider key or a coding
|
|
75
|
-
agent you are already signed in to (see below). Measured on 2026-09-01 from
|
|
76
|
-
three fresh directories against the published 0.65.0: 3 of 3 reached the goal,
|
|
77
|
-
108 to 111 s each, about $0.16 each, and all three reported the same two
|
|
78
|
-
frictions in the demo app
|
|
79
|
-
([receipt](docs/goals/computer-use-actor/receipts/cold-install-try-live-2026-09-01.md)).
|
|
80
|
-
|
|
81
|
-
**Install it, do not one-shot it.** A live run needs the optional peer
|
|
82
|
-
`@e2b/desktop`, and Node resolves that relative to humanish itself, so a
|
|
83
|
-
one-shot `npx humanish@latest` can never find it, no matter what your project
|
|
84
|
-
has installed. `npm i -D humanish @e2b/desktop` once, then `npx humanish …`
|
|
85
|
-
resolves the local copy and works. The dry-run path (`humanish run first-run`)
|
|
86
|
-
needs none of this.
|
|
87
|
-
|
|
88
|
-
The package is `humanish`; the installed binary is `humanish`. For a one-shot
|
|
89
|
-
command before installation, use `npx --package humanish humanish ...` to
|
|
90
|
-
guarantee the binary comes from the `humanish` registry package rather than a
|
|
91
|
-
same-named command already on your PATH.
|
|
92
|
-
|
|
93
|
-
For coding agents, install the repo skill first:
|
|
35
|
+
`@e2b/desktop` is the optional peer for live hosted desktops. Install it alongside
|
|
36
|
+
Humanish so the CLI can resolve it; a one-shot `npx humanish@latest` can miss the
|
|
37
|
+
peer. The keyless preview needs only `humanish`.
|
|
38
|
+
|
|
39
|
+
**Run a live study.** Set the desktop and model keys with hidden prompts, then
|
|
40
|
+
send one synthetic participant into the included drawDB study:
|
|
94
41
|
|
|
95
42
|
```bash
|
|
96
|
-
npx
|
|
43
|
+
npx humanish keys set e2b
|
|
44
|
+
npx humanish keys set openai
|
|
45
|
+
npx humanish doctor
|
|
46
|
+
npx humanish lab preflight try-live
|
|
47
|
+
npx humanish run try-live
|
|
48
|
+
npx humanish observe --run latest --open
|
|
97
49
|
```
|
|
98
50
|
|
|
99
|
-
|
|
100
|
-
|
|
51
|
+
Existing `E2B_API_KEY` and `OPENAI_API_KEY` environment variables also work.
|
|
52
|
+
`try-live` clones and studies drawDB, not your project. Its **$2 cap covers
|
|
53
|
+
estimated model spend**; hosted desktop time is additional. Caps are checked
|
|
54
|
+
between turns and are not provider billing ceilings. Allow a few minutes for
|
|
55
|
+
the app to build and the participant to work. See [budgets and privacy](https://humanish.dev/docs/budgets-and-privacy).
|
|
101
56
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
A live study normally needs a provider API key. If you already have a coding
|
|
105
|
-
agent signed in (Codex on a ChatGPT plan, Claude Code on a Max plan), humanish
|
|
106
|
-
can use it as the participant's brain instead, and then the only credential it
|
|
107
|
-
needs is `E2B_API_KEY`.
|
|
57
|
+
**Preview without keys.** To see the evidence format before connecting providers:
|
|
108
58
|
|
|
109
59
|
```bash
|
|
110
|
-
humanish
|
|
60
|
+
npx humanish run first-run
|
|
61
|
+
npx humanish observe --run latest --open
|
|
111
62
|
```
|
|
112
63
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
64
|
+
This generates an evidence preview with no provider spend. It does not open
|
|
65
|
+
your app, run an actor, or validate product behavior. To study your own product,
|
|
66
|
+
follow the complete [own-app lab](https://humanish.dev/docs/your-app).
|
|
67
|
+
|
|
68
|
+
For coding agents, install the companion skill:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx skills add danielgwilson/humanish --skill humanish
|
|
119
72
|
```
|
|
120
73
|
|
|
121
|
-
humanish
|
|
122
|
-
**exists**, spawns the CLI tool-restricted (`--sandbox read-only` for Codex,
|
|
123
|
-
`--allowedTools Read` for Claude Code) in a scratch directory, and hands it one
|
|
124
|
-
screenshot per turn. The agent only **decides**; humanish performs the action
|
|
125
|
-
inside the E2B sandbox, so nothing the persona chooses ever runs on your machine.
|
|
126
|
-
|
|
127
|
-
Three things to know before you rely on it:
|
|
128
|
-
|
|
129
|
-
- **It is not free.** Subscription usage consumes your own plan. Runs driven this
|
|
130
|
-
way record `estimatedCostUsd: null` with `reason: "no_token_usage"` rather than
|
|
131
|
-
`$0`, because `$0` would be untrue. Rate limits on those plans are built for
|
|
132
|
-
interactive coding; humanish fails closed with the CLI's own message and does
|
|
133
|
-
not retry into them.
|
|
134
|
-
- **It is slower.** Roughly 9 seconds per turn against about 3 for a direct API
|
|
135
|
-
call, so give the lane a longer `execution.timeoutMs` than you would otherwise.
|
|
136
|
-
- **The evidence says which brain ran it.** The trace records
|
|
137
|
-
`ids.model: "codex app-server (local, operator-authenticated)"` or
|
|
138
|
-
`"claude (local, operator-authenticated, one session per run)"`, so a
|
|
139
|
-
local-agent run is never silently compared against an API one.
|
|
140
|
-
- **Both agents keep one conversation for the whole run.** Codex through an
|
|
141
|
-
app-server thread, Claude Code through one `claude -p` stream-json session.
|
|
142
|
-
A participant that starts every turn cold cannot remember trying the menu
|
|
143
|
-
and tries it again; measured on one lab, that was 188 actions over 90 turns
|
|
144
|
-
and no finish against 21 actions over 8 turns. `HUMANISH_LOCAL_AGENT_ONE_SHOT=1`
|
|
145
|
-
keeps the cold-start path for the Claude agent as a measurement switch, so
|
|
146
|
-
"remembers" can be compared against "does not" on your own lab; the trace's
|
|
147
|
-
`ids.model` says which ran.
|
|
74
|
+
Source: [`skills/humanish/SKILL.md`](skills/humanish/SKILL.md).
|
|
148
75
|
|
|
149
|
-
##
|
|
76
|
+
## How It Works
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
humanish/ committed labs, personas, scenarios, policy, adapters
|
|
80
|
+
.humanish/ ignored run evidence, Observer output, reviews, local state
|
|
81
|
+
```
|
|
150
82
|
|
|
151
|
-
|
|
152
|
-
worked, roughly how long it took) so the maintainers can tell whether anyone
|
|
153
|
-
reaches a working first run. It never sends your labs, subjects, personas, paths,
|
|
154
|
-
or evidence, and there is no field in the payload that could.
|
|
83
|
+
After a run, read its findings and verification grade:
|
|
155
84
|
|
|
156
85
|
```bash
|
|
157
|
-
humanish
|
|
158
|
-
humanish
|
|
86
|
+
npx humanish runs --json
|
|
87
|
+
npx humanish review --run latest --json
|
|
88
|
+
npx humanish verify --run latest --json
|
|
89
|
+
npx humanish feedback issue --run latest --repo owner/repo --format markdown
|
|
159
90
|
```
|
|
160
91
|
|
|
161
|
-
|
|
162
|
-
|
|
92
|
+
`feedback issue` prints a draft and requires `share_ready` evidence. A live run
|
|
93
|
+
with raw screenshots can be valid local evidence and still fail that sharing
|
|
94
|
+
gate. [Read results](https://humanish.dev/docs/read-results) explains the
|
|
95
|
+
participant's report, task outcomes, costs, and how to turn a finding into an issue.
|
|
163
96
|
|
|
164
97
|
## Public-Safety Boundary
|
|
165
98
|
|
|
@@ -172,12 +105,13 @@ allowlist, over both tracked files and the packed npm payload) plus a
|
|
|
172
105
|
full-history gitleaks scan. That protects what we ship; it does not scan your
|
|
173
106
|
repo.
|
|
174
107
|
|
|
175
|
-
**2.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
whatever was on screen
|
|
108
|
+
**2. Persisted text is scrubbed for known values and secret patterns.** Humanish
|
|
109
|
+
uses literal matching for provisioned secret values and pattern redaction for
|
|
110
|
+
secret-shaped text in logs, errors, and model narration. Environment provenance
|
|
111
|
+
records variable names. These checks have coverage limits: unknown values,
|
|
112
|
+
unrecognized formats, and implementation defects can escape them. Raw
|
|
113
|
+
screenshots contain whatever was on screen. Use synthetic data, verify the
|
|
114
|
+
bundle, and review the actual text and pixels before sharing.
|
|
181
115
|
|
|
182
116
|
**3. Run bundles are local by default.** Evidence lands under gitignored
|
|
183
117
|
`.humanish/`, and no command publishes it for you. Sharing evidence (committing
|
|
@@ -204,158 +138,24 @@ certified free of PII or PHI. A first-class PII/PHI detector is on the roadmap
|
|
|
204
138
|
Feedback commands require `share_ready`. A valid local run can still be
|
|
205
139
|
reviewed in Observer without being promoted into a public issue draft.
|
|
206
140
|
|
|
207
|
-
## How It Works
|
|
208
|
-
|
|
209
|
-
```text
|
|
210
|
-
humanish/ committed source plane: labs, personas, scenarios, policy, adapters
|
|
211
|
-
.humanish/ ignored runtime plane: runs, Observer output, reviews, local state
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
The first-run path does not require credentials:
|
|
215
|
-
|
|
216
|
-
```bash
|
|
217
|
-
npx humanish doctor
|
|
218
|
-
npx humanish watch
|
|
219
|
-
npx humanish verify --run latest --json
|
|
220
|
-
npx humanish feedback issue --run latest --repo owner/repo --format markdown
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
`humanish watch` starts a fresh four-lane synthetic run, renders the Observer,
|
|
224
|
-
opens it in the browser, serves it over localhost, and keeps the shell attached.
|
|
225
|
-
After `humanish init`, named lab manifests can be run the same way:
|
|
226
|
-
|
|
227
|
-
```bash
|
|
228
|
-
npx humanish watch first-run
|
|
229
|
-
npx humanish lab list
|
|
230
|
-
npx humanish lab inspect first-run
|
|
231
|
-
npx humanish lab preflight first-run
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
The CI-safe equivalent is:
|
|
235
|
-
|
|
236
|
-
```bash
|
|
237
|
-
npx humanish watch --json --no-open
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## The Terminal Surface
|
|
241
|
-
|
|
242
|
-
Every other humanish command is built so an agent can drive it. `humanish tui`
|
|
243
|
-
takes the screen and waits for a person.
|
|
244
|
-
|
|
245
|
-
```bash
|
|
246
|
-
npx humanish tui
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
Arrow keys move, `enter` opens, `esc` goes back, `q` quits. There are three
|
|
250
|
-
screens, and you move between objects rather than between states: the set of
|
|
251
|
-
labs, one lab, one run. A run's lifecycle
|
|
252
|
-
renders in place, so a run you are watching changes from running to its verdict
|
|
253
|
-
without the screen moving under you.
|
|
254
|
-
|
|
255
|
-
- **labs**: every lab in the project, whether or not it has ever run. Labs with
|
|
256
|
-
something running now sort first. Each row carries what to expect from a live
|
|
257
|
-
run of it; a lab with no live history says `no live runs yet` and does not
|
|
258
|
-
quote a median from dry runs, which spend nothing and take no time.
|
|
259
|
-
- **lab**: that lab's history, and two ways to start it. A dry run starts on one
|
|
260
|
-
keypress because it cannot cost anything; a live run is armed by the first
|
|
261
|
-
`enter` and committed by the second, restating the cost in between.
|
|
262
|
-
- **run**: who is in the run, what they are currently thinking, and how far they
|
|
263
|
-
have got, with time and money underneath. A terminal cannot show screenshots,
|
|
264
|
-
so the run's self-contained Observer artifact is named for you to open.
|
|
265
|
-
|
|
266
|
-
A run you start from the surface is detached: it keeps going if you quit the
|
|
267
|
-
TUI, and it survives losing the SSH session you started it over. The surface
|
|
268
|
-
follows it by reading `.humanish/runs/<id>/status.json`, holding no handle on
|
|
269
|
-
it, so you can quit mid-run, reopen, and find it still there.
|
|
270
|
-
|
|
271
|
-
Requires an interactive terminal and Node 22 or newer. It refuses anything else
|
|
272
|
-
with a structured error rather than rendering escape codes into a pipe:
|
|
273
|
-
|
|
274
|
-
```console
|
|
275
|
-
$ humanish tui --json < /dev/null
|
|
276
|
-
{
|
|
277
|
-
"schema": "humanish.tui-result.v1",
|
|
278
|
-
"ok": false,
|
|
279
|
-
"error": {
|
|
280
|
-
"code": "HUMANISH_TUI_REQUIRES_TTY",
|
|
281
|
-
"message": "humanish tui needs an interactive terminal. For scripted or agent use, `humanish runs --json` lists the same runs and `humanish lab run --json` starts one."
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
Every other command still works on Node 20; only this surface needs 22.
|
|
287
|
-
|
|
288
|
-
## Serve the Library
|
|
289
|
-
|
|
290
|
-
`humanish watch` follows one attached run; `humanish serve` serves the whole
|
|
291
|
-
local run library under `.humanish/runs/`, a library index plus every run's
|
|
292
|
-
Observer page:
|
|
293
|
-
|
|
294
|
-
```bash
|
|
295
|
-
npx humanish serve
|
|
296
|
-
npx humanish serve --expose --tunnel ngrok --oauth google --allow-email you@example.com
|
|
297
|
-
npx humanish serve --safe --expose --tunnel ngrok
|
|
298
|
-
npx humanish serve --expose --public-url https://observer.example.com
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
The first serves the library on loopback only. The second is the phone path:
|
|
302
|
-
ngrok's edge authenticates viewers with Google OAuth (restricted to your
|
|
303
|
-
`--allow-email`/`--allow-domain` allow rules) before any request reaches the
|
|
304
|
-
loopback server; humanish carries no in-process auth. The third is a secretless
|
|
305
|
-
safe observer: no login, but only runs whose `humanish verify` shareSafety is
|
|
306
|
-
`share_ready` exist at all; everything else is absent and 404s. The fourth
|
|
307
|
-
trusts an edge you already secure (Cloudflare Access, Tailscale, a proxy you own)
|
|
308
|
-
and just binds loopback behind it.
|
|
309
|
-
|
|
310
|
-
In every mode the server binds `127.0.0.1`; exposure only ever happens through
|
|
311
|
-
an authenticated edge forwarding to the loopback port. Exposure is fail-closed:
|
|
312
|
-
`--expose` always needs a reachable public origin (a `--tunnel` or a `--public-url`,
|
|
313
|
-
even under `--safe`), and then requires either edge auth (`--oauth` on the tunnel,
|
|
314
|
-
or a `--public-url` you secure) or `--safe`. `--oauth google` with no allow rule
|
|
315
|
-
lets any Google account in and warns loudly.
|
|
316
|
-
|
|
317
|
-
### Watch a live run from your phone
|
|
318
|
-
|
|
319
|
-
`humanish watch <cua-lab> --expose --tunnel ngrok --oauth google --allow-email
|
|
320
|
-
you@example.com` streams the live desktop of a computer-use run to an
|
|
321
|
-
edge-authenticated remote viewer while it plays. The attached server comes up
|
|
322
|
-
during the run and survives a timed-out/failed run, so you can inspect a failed
|
|
323
|
-
run's evidence too. A live run is never `share_ready`, so `watch --expose` always
|
|
324
|
-
requires edge auth; `--safe` is a `serve` library filter and is rejected on watch
|
|
325
|
-
(`HUMANISH_WATCH_SAFE_NOT_APPLICABLE`). An exposed watch serves only the attached
|
|
326
|
-
run (its history lists just that run and every other run id 404s), so a remote
|
|
327
|
-
viewer can never reach your other runs' raw evidence.
|
|
328
|
-
|
|
329
|
-
Live E2B desktop stream URLs are served only on `watch --expose`, and only behind
|
|
330
|
-
edge auth; `serve` never injects them (remote viewers of the library see only
|
|
331
|
-
persisted evidence: screenshots, events, terminal tails). See
|
|
332
|
-
[Serve architecture](docs/architecture/serve.md).
|
|
333
|
-
|
|
334
141
|
## Commands
|
|
335
142
|
|
|
143
|
+
Use `npx humanish` from your project. Full arguments and options are generated
|
|
144
|
+
from the shipped CLI in the [command reference](https://humanish.dev/docs/cli).
|
|
145
|
+
|
|
336
146
|
| Command | Purpose |
|
|
337
147
|
| --- | --- |
|
|
338
|
-
| `humanish init` | Scaffold
|
|
339
|
-
| `humanish doctor` |
|
|
340
|
-
| `humanish
|
|
341
|
-
| `humanish
|
|
342
|
-
| `humanish
|
|
343
|
-
| `humanish
|
|
344
|
-
| `humanish
|
|
345
|
-
| `humanish
|
|
346
|
-
| `humanish
|
|
347
|
-
| `humanish
|
|
348
|
-
| `humanish
|
|
349
|
-
| `humanish verify` | Validate a run bundle and public-safety gates. |
|
|
350
|
-
| `humanish cleanup` | Inspect recorded resource evidence and write `cleanup.json`; stored IDs do not authorize provider mutation. |
|
|
351
|
-
| `humanish review` | Read review evidence for a run. |
|
|
352
|
-
| `humanish runs` | List local runs and latest pointers. |
|
|
353
|
-
| `humanish export` | One self-contained `.html` of a run's Observer with screenshots inlined; verify and the share_ready gate run inside, `--local-only` watermarks a raw-screenshot bundle. |
|
|
354
|
-
| `humanish stats` | Cost, outcome, and duration roll-ups across run history; `--lab`, `--since`. Estimates stay labelled; unknown costs count as unknown. |
|
|
355
|
-
| `humanish feedback list` | List a run's draft state and every feedback candidate (one per participant finding), with the ids `--candidate` takes. |
|
|
356
|
-
| `humanish feedback issue` | Print a public-safe GitHub issue draft without API mutation. `--candidate <id>` chooses which finding; default is the first. |
|
|
357
|
-
| `humanish lab run oss` | Repo-maintainer contract example: dry-run Observer-of-Observers for authorized repo selections. |
|
|
358
|
-
| `humanish lab run oss-smoke` | Repo-maintainer dogfood example: disposable clone smoke test against public OSS repos. |
|
|
148
|
+
| `humanish init --yes` | Scaffold study source and ignored runtime state. |
|
|
149
|
+
| `humanish doctor --json` | Check setup without exposing key values. |
|
|
150
|
+
| `humanish lab list --json` | List available labs. |
|
|
151
|
+
| `humanish lab inspect <lab> --json` | Read a lab before running it. |
|
|
152
|
+
| `humanish lab preflight <lab> --json` | Check configuration and route warnings. |
|
|
153
|
+
| `humanish run <lab>` | Run the named preview or live study. |
|
|
154
|
+
| `humanish watch <lab>` | Run a lab with an attached Observer. |
|
|
155
|
+
| `humanish runs --json` | List local run history. |
|
|
156
|
+
| `humanish review --run latest --json` | Read an existing run's evidence. |
|
|
157
|
+
| `humanish verify --run latest --json` | Check evidence and share-safety gates. |
|
|
158
|
+
| `humanish feedback issue --run latest --repo owner/repo` | Print an eligible feedback draft. |
|
|
359
159
|
|
|
360
160
|
## Exit Codes
|
|
361
161
|
|
|
@@ -366,360 +166,72 @@ persisted evidence: screenshots, events, terminal tails). See
|
|
|
366
166
|
| `2` | Humanish domain or validation failure. Check the JSON envelope's `error.code` for detail. |
|
|
367
167
|
| `128+N` | Terminated by signal `N`: `130` for SIGINT, `143` for SIGTERM, `129` for SIGHUP. |
|
|
368
168
|
|
|
369
|
-
##
|
|
370
|
-
|
|
371
|
-
Labs are authored as `.yaml` source:
|
|
372
|
-
|
|
373
|
-
```text
|
|
374
|
-
humanish/labs/*.yaml committed public-safe labs
|
|
375
|
-
.humanish/labs/*.yaml ignored local labs
|
|
376
|
-
.humanish/local/labs/*.yaml ignored private or machine-specific labs
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
Committed labs should be useful to anyone who clones the project. Private repo
|
|
380
|
-
targets, token-backed provider settings, and local-only dogfood variants belong
|
|
381
|
-
in ignored `.humanish/` lab manifests and can be run explicitly:
|
|
382
|
-
|
|
383
|
-
```bash
|
|
384
|
-
npx humanish watch .humanish/labs/local-dogfood.yaml --env-file .humanish/local/provider.env
|
|
385
|
-
npx humanish lab run .humanish/labs/local-dogfood.yaml --json --no-open
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
`--env-file` loads values for the current process only. Humanish reports loaded
|
|
389
|
-
env var names, never values, and does not persist those values into run bundles
|
|
390
|
-
or Observer data.
|
|
391
|
-
|
|
392
|
-
### Computer-Use Labs
|
|
393
|
-
|
|
394
|
-
A computer-use lab dispatches a **registered computer-use actor** (`actors[0].type`,
|
|
395
|
-
resolved against the actor registry, e.g. `openai-computer-use`) to drive an app in
|
|
396
|
-
a hosted E2B desktop browser and emit an evidence bundle under gitignored
|
|
397
|
-
`.humanish/` (full-fidelity screenshots by default, see below; length-only typed
|
|
398
|
-
text; provider-neutral `humanish.actor-trace.v1` on the stream). Two subjects route
|
|
399
|
-
here:
|
|
400
|
-
|
|
401
|
-
- **`subject.source: clone`** (+ `execution.target: e2b-desktop` + a computer-use
|
|
402
|
-
actor): the lab clones your repo into the sandbox, runs your declared
|
|
403
|
-
`serve.install`/`serve.build`/`serve.start` commands (detached, with readiness
|
|
404
|
-
probing), and drives the served app at `serve.url`. Subject env var names declared
|
|
405
|
-
in `subject.env` are provisioned from `--env-file` (names land in evidence; values
|
|
406
|
-
never do). The bundle records provenance: repo, cloned commit, env names.
|
|
407
|
-
- **`subject.source: app-url`**: you (a library caller) provision the app yourself
|
|
408
|
-
via the `prepareDesktop` hook (`runLab(config, { cuaHooks: { prepareDesktop } })`)
|
|
409
|
-
and the actor drives the URL you declared.
|
|
410
|
-
|
|
411
|
-
```yaml
|
|
412
|
-
subject:
|
|
413
|
-
source: clone
|
|
414
|
-
repos: [example-org/example-app]
|
|
415
|
-
serve:
|
|
416
|
-
install: pnpm install --frozen-lockfile
|
|
417
|
-
build: pnpm build
|
|
418
|
-
start: pnpm start
|
|
419
|
-
url: http://127.0.0.1:3000/
|
|
420
|
-
actors:
|
|
421
|
-
- type: openai-computer-use
|
|
422
|
-
mission: Explore the app as a first-time visitor and complete its primary flow.
|
|
423
|
-
execution: { target: e2b-desktop }
|
|
424
|
-
scenario: { mode: live }
|
|
425
|
-
```
|
|
169
|
+
## The Terminal Surface
|
|
426
170
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
171
|
+
`humanish tui` is for a person browsing labs and runs. It needs Node 22+ and an
|
|
172
|
+
interactive stdin/stdout, and refuses detected coding-agent sessions even with
|
|
173
|
+
a TTY. Agents should use `lab list --json`, `lab inspect <lab> --json`, and
|
|
174
|
+
`runs --json`. Read [TUI behavior and JSON alternatives](https://humanish.dev/docs/review-surfaces#for-coding-agents-and-scripts).
|
|
430
175
|
|
|
431
|
-
|
|
432
|
-
`--env-file`) and the optional peer dependency: `npm i -D @e2b/desktop`. A cloned
|
|
433
|
-
subject is served **inside** the sandbox on loopback; to instead drive a deployment
|
|
434
|
-
you own (a Vercel preview, staging), use an `app-url` subject with
|
|
435
|
-
`policies.allowPublicTargets: true`. The actor's API key never enters the sandbox;
|
|
436
|
-
only declared subject env names do. `humanish init` scaffolds an example at
|
|
437
|
-
`humanish/labs/cua-browser.yaml`.
|
|
438
|
-
|
|
439
|
-
**Off-app email/SMS verification (`comms`).** When a flow is gated behind an email or
|
|
440
|
-
SMS the app itself sends (a signup verification link, a one-time code, a magic link),
|
|
441
|
-
add a `comms:` block to the lab. Humanish redirects the app's email-API sends (via
|
|
442
|
-
one adopter-named env var: with the official Resend SDK it is `RESEND_BASE_URL`,
|
|
443
|
-
which the SDK reads on its own, so nothing in the app has to change; other providers
|
|
444
|
-
need the app to actually pass the env through, and a run whose catch captures zero
|
|
445
|
-
sends warns at teardown) into a catch **inside** the sandbox, so nothing leaves the
|
|
446
|
-
machine. Every lane gets a deterministic inbox address automatically, and each
|
|
447
|
-
persona's prompt carries the full handoff: the address to sign up with, the inbox URL
|
|
448
|
-
to open, and that waiting for an email is a next step, not a blocker. The run bundle
|
|
449
|
-
gets a digest-only `humanish.comms-thread.v1` artifact (from/to/subject/link
|
|
450
|
-
digests + an OTP count; no raw address, link, or code persists); the readable proof a
|
|
451
|
-
persona saw the email is its inbox-page screenshots. Hosted on the clone/local-tree
|
|
452
|
-
computer-use lanes and the concurrent shared-world route (warned inert elsewhere),
|
|
453
|
-
vendor-neutral (Resend/SendGrid shaped, or a custom profile).
|
|
454
|
-
See `docs/contracts/schemas.md` for the full `comms:` shape.
|
|
455
|
-
|
|
456
|
-
**Screenshots are full-fidelity by default.** Run bundles live in gitignored
|
|
457
|
-
`.humanish/`, so the Observer shows exactly what the persona saw. Set
|
|
458
|
-
`policies.redactScreenshots: true` to persist blurred thumbnails at capture instead
|
|
459
|
-
(for unowned subjects, or bundles you intend to share as-is). Raw bundles stay local
|
|
460
|
-
in gitignored `.humanish/`; nothing scans the pixels, so review them before sharing
|
|
461
|
-
anywhere. A redact-on-export step is planned. The frame sent to the model is always
|
|
462
|
-
full-resolution regardless. (Doctrine: `docs/principles/invariants-and-defaults.md`.
|
|
463
|
-
Redaction binds the publish boundary, not capture.) `humanish verify` reports
|
|
464
|
-
raw-screenshot bundles as `shareSafety.status: local_only`; `humanish feedback issue`
|
|
465
|
-
refuses them until the run is share-ready.
|
|
466
|
-
|
|
467
|
-
**Device presets.** `execution.desktop.device` picks the hosted desktop screen size:
|
|
468
|
-
`mobile` (414×896), `small-mobile` (360×740), `narrow-mobile` (320×700), `tablet`
|
|
469
|
-
(820×1180), `desktop` (1440×950, default), or `wide` (1920×1080). The values are copied
|
|
470
|
-
from the mature in-house sims. **Honest fidelity:** on the computer-use / E2B-desktop
|
|
471
|
-
route width/height size the virtual display and browser outer window. The actual page
|
|
472
|
-
viewport is smaller because browser chrome occupies space; Chromium-family live bundles
|
|
473
|
-
measure it through CDP and record it separately from requested/verified screen geometry.
|
|
474
|
-
Browsers without that measurement seam omit the viewport rather than guessing. A
|
|
475
|
-
site's width-based responsive CSS still fires, and the model is *told* its device in the
|
|
476
|
-
prompt, matching how those sims run organic mobile lanes. Without the block below there is no
|
|
477
|
-
touch input, the device-pixel-ratio isn't rendered, and the user-agent stays desktop on this
|
|
478
|
-
route. Device is run-wide today; per-*persona* device (N personas × devices) lands with fan-out.
|
|
479
|
-
`execution.desktop.resolution` is a raw escape hatch that overrides the preset.
|
|
480
|
-
|
|
481
|
-
**Mobile emulation.** `execution.desktop.fidelity: { mobileEmulation: true }` turns every hosted
|
|
482
|
-
Chrome/Chromium computer-use lane on a mobile preset (`mobile`, `small-mobile`, `narrow-mobile`)
|
|
483
|
-
into a mobile-emulated browser before the participant arrives, and leaves desktop, tablet and
|
|
484
|
-
wide lanes in the same run untouched: the lane's preset width/height become the CSS viewport (414 px for `mobile`, where the
|
|
485
|
-
X screen itself cannot go below 500), the preset's device pixel ratio applies (`deviceScaleFactor`
|
|
486
|
-
overrides it), touch events are on (`touch: false` turns them off) and the browser presents a
|
|
487
|
-
mobile user agent (`userAgent` replaces the default iPhone Safari string). The run bundle records
|
|
488
|
-
`desktopGeometry.fidelity` with `tier: mobile-emulated`, the request, the CDP methods applied,
|
|
489
|
-
and `resolved`: what the page itself reported afterwards (`navigator.userAgent`,
|
|
490
|
-
`devicePixelRatio`, `innerWidth`, `maxTouchPoints`, coarse pointer). A page without a viewport
|
|
491
|
-
meta lays out at 980 px, as it would on a phone, and the bundle says so. Firefox cannot be
|
|
492
|
-
emulated, so the lane fails closed instead of shipping a desktop run labelled mobile. The
|
|
493
|
-
viewport and DPR override cover the launch tab (the user agent and touch flags are browser-wide);
|
|
494
|
-
if an observation reads a tab the participant opened later, the lane records one warning saying
|
|
495
|
-
so, because that tab laid out at the window width. A bundle without a `fidelity` block is a
|
|
496
|
-
responsive-viewport study whatever its preset is called.
|
|
497
|
-
|
|
498
|
-
**Desktop browser choice.** Hosted computer-use lanes and shared-world actor seats use the
|
|
499
|
-
route's historical opener unless you set `execution.desktop.browser` to `chrome`, `chromium`,
|
|
500
|
-
or `firefox`. A concrete value means "launch this browser or fail"; it never silently
|
|
501
|
-
falls back to whatever the image prefers. When configured, run bundles record the requested
|
|
502
|
-
browser and the resolved in-sandbox command as `desktopBrowser`.
|
|
503
|
-
|
|
504
|
-
**Deterministic stop conditions.** Freeform computer-use actors can keep acting after the
|
|
505
|
-
app has already reached the state you care about. Add `stopWhen` to the actor or a lane to
|
|
506
|
-
stop immediately after a deterministic browser observation matches. Conditions inside one
|
|
507
|
-
rule are ANDed together; rules under `any` are ORed. Lane-level `stopWhen` overrides the
|
|
508
|
-
actor default.
|
|
509
|
-
|
|
510
|
-
```yaml
|
|
511
|
-
actors:
|
|
512
|
-
- type: openai-computer-use
|
|
513
|
-
mission: Complete the assigned browser task.
|
|
514
|
-
stopWhen:
|
|
515
|
-
any:
|
|
516
|
-
- id: dashboard-visible
|
|
517
|
-
urlPathEquals: /dashboard
|
|
518
|
-
textIncludes: Dashboard
|
|
519
|
-
lanes:
|
|
520
|
-
- id: reviewer
|
|
521
|
-
entry: /items/123
|
|
522
|
-
instruction: Review the item and return to the queue.
|
|
523
|
-
stopWhen:
|
|
524
|
-
any:
|
|
525
|
-
- id: returned-to-queue
|
|
526
|
-
urlPathEquals: /items
|
|
527
|
-
textIncludes: Queue
|
|
528
|
-
```
|
|
176
|
+
## Serve the Library
|
|
529
177
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
`.y4m` file of yours, uploaded). The browser's own permission dialog stays in the way by default
|
|
533
|
-
(`policies.mediaPermission: prompt`), because the gate is where a real person hesitates or
|
|
534
|
-
refuses; `granted` bypasses it for studies about what happens after. The bundle records the
|
|
535
|
-
feed and the exact launch flags under `desktopBrowser.media`. A microphone needs an image with
|
|
536
|
-
an audio stack (`execution.desktop.template`); the stock desktop has none, so a declared
|
|
537
|
-
microphone without a template is refused before any spend.
|
|
538
|
-
**A declared observation window.** Some findings are "time passed and nothing broke": a call
|
|
539
|
-
both participants stay on, an import that finishes, a dashboard that updates. A freeform
|
|
540
|
-
participant with nothing to do keeps acting, so `dwell` lets the study hold instead. Once
|
|
541
|
-
`when` matches (or after the first observation, when there is no `when`), the harness holds the
|
|
542
|
-
page for `ms`, captures a frame every `everyMs` (default 10 s), takes no action and requests no
|
|
543
|
-
model turn, then hands control back (`then: continue`, the default) or ends the session
|
|
544
|
-
(`then: stop`). The window is recorded in the trace as deliberate, and it never outlasts the
|
|
545
|
-
session budget. Lane-level `dwell` overrides the actor default.
|
|
546
|
-
|
|
547
|
-
```yaml
|
|
548
|
-
actors:
|
|
549
|
-
- type: openai-computer-use
|
|
550
|
-
mission: Join the room, stay a while, then leave.
|
|
551
|
-
dwell:
|
|
552
|
-
when:
|
|
553
|
-
any:
|
|
554
|
-
- id: in-room
|
|
555
|
-
urlIncludes: /room/
|
|
556
|
-
ms: 120000
|
|
557
|
-
everyMs: 10000
|
|
558
|
-
then: continue
|
|
559
|
-
```
|
|
178
|
+
`humanish serve` serves your run library on loopback. The [Observer and terminal guide](https://humanish.dev/docs/review-surfaces#serve-the-run-library)
|
|
179
|
+
covers local viewing, authenticated remote access, and share-safe public exposure.
|
|
560
180
|
|
|
561
|
-
|
|
562
|
-
`appStatePathEquals`. URL and text observations are runtime-only and are not persisted into
|
|
563
|
-
the run bundle; the trace stores only the matched rule id and primitive names. Browser URL
|
|
564
|
-
and text observation requires a Chrome/Chromium CDP session in the desktop. For deterministic
|
|
565
|
-
browser-observed stops, set `execution.desktop.browser: chrome` or `chromium`.
|
|
566
|
-
|
|
567
|
-
**Cost tracking (estimated).** Computer-use run bundles carry an advisory `cost` block: a
|
|
568
|
-
per-lane token-derived model estimate plus one aggregate E2B desktop-minute estimate. Every
|
|
569
|
-
dollar figure is an estimate, never a provider charge. It is a rate-table multiply, always
|
|
570
|
-
surfaced as "~$X estimated (rates as of `<date>`)" in the Observer and the run library, and it
|
|
571
|
-
carries the pricing date + source so a token-derived number is never mistaken for an
|
|
572
|
-
authoritative bill. Unknown model/rate is declared absent (`null` + a reason), never guessed or
|
|
573
|
-
silently zeroed; dry-runs invent no spend. The rates live in
|
|
574
|
-
[`src/pricing.ts`](src/pricing.ts) as **operator-editable, dated estimates**. The E2B desktop
|
|
575
|
-
rate is still a `placeholder` stand-in; update the numbers and the `asOf` date when providers
|
|
576
|
-
change pricing. On models that bill prompt-cache writes and long-context requests at their own
|
|
577
|
-
rates (OpenAI's 5.6 family), the estimate prices both exactly from the trace's per-request
|
|
578
|
-
usage ledger.
|
|
579
|
-
|
|
580
|
-
**Choosing the model.** Computer-use lanes default to `gpt-5.6-sol` (the 5.6-generation
|
|
581
|
-
flagship; `gpt-5.6` is OpenAI's alias for the same model). Configure it per lab with
|
|
582
|
-
`actors[0].model`. Any id in the rate table prices cleanly (`gpt-5.6-terra` and
|
|
583
|
-
`gpt-5.6-luna` are the cheaper tiers; `gpt-5.5` stays priced for pinned labs). A run with a
|
|
584
|
-
spend cap (`execution.caps`) refuses an unpriced model at preflight, so add a dated rate to
|
|
585
|
-
`src/pricing.ts` before capping a model the table does not know.
|
|
586
|
-
|
|
587
|
-
**Fail-closed spend cap.** Set `execution.caps.maxUsd` on a computer-use lab to abort a session
|
|
588
|
-
the moment its running estimated spend crosses the cap, a runaway-retry guard that mirrors the
|
|
589
|
-
terminal lane's `scenario.caps.maxUsd`. It is a **per-lane** cap: enforced inside each lane's loop,
|
|
590
|
-
so an N-lane fan-out can spend up to N × `maxUsd` before any lane aborts (the run bundle warns with
|
|
591
|
-
the true ~N × cap ceiling; a shared run-level budget is future work). A lane that did real work then
|
|
592
|
-
hits its cap passes (`budget_reached`); a zero-action runaway that crosses it fails (`gave_up`).
|
|
593
|
-
Absent = uncapped (the historical CUA behavior); `maxUsd: 0` = no-spend. A cap on a model
|
|
594
|
-
`src/pricing.ts` cannot price is refused at preflight (`HUMANISH_CUA_LAB_UNPRICED_CAP`)
|
|
595
|
-
rather than run uncapped: an unenforceable cap is more dangerous than none, so add a rate
|
|
596
|
-
or drop the cap.
|
|
597
|
-
|
|
598
|
-
**Failed-lane reruns.** Multi-lane CUA fan-out can be rerun surgically without mutating
|
|
599
|
-
the source run:
|
|
181
|
+
### Watch a live run from your phone
|
|
600
182
|
|
|
601
|
-
|
|
602
|
-
npx humanish lab run cua-browser --rerun-failed-from latest --json --no-open
|
|
603
|
-
npx humanish lab run cua-browser --rerun-failed-from <run-id> --lanes lane-02,lane-04
|
|
604
|
-
```
|
|
183
|
+
See [authenticated live viewing](https://humanish.dev/docs/review-surfaces#watch-a-live-run-from-your-phone).
|
|
605
184
|
|
|
606
|
-
|
|
607
|
-
(or the explicit `--lanes` selection). The new `run.json` records `rerun.sourceRunId`,
|
|
608
|
-
selected lane ids, and previous lane statuses; the source run's verdict is left unchanged.
|
|
609
|
-
This is intentionally not automatic retry; a passing rerun is evidence of a
|
|
610
|
-
nondeterminism candidate and does not license erasing the original red lane.
|
|
185
|
+
## Lab Manifests
|
|
611
186
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
cleanup command writes a durable inspection receipt until Humanish has a
|
|
615
|
-
verified resource-lease contract. Resources already recorded as killed become
|
|
616
|
-
`already_clean`; recorded live or unknown resources become `failed`, which
|
|
617
|
-
makes cleanup and verification fail closed:
|
|
187
|
+
See the [lab manifest reference](https://humanish.dev/docs/lab-manifests) for
|
|
188
|
+
source directories, route selection, and ignored private labs.
|
|
618
189
|
|
|
619
|
-
|
|
620
|
-
npx humanish cleanup --run latest
|
|
621
|
-
npx humanish verify --run latest
|
|
622
|
-
```
|
|
190
|
+
### Computer-Use Labs
|
|
623
191
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
192
|
+
The [computer-use reference](https://humanish.dev/docs/computer-use) covers
|
|
193
|
+
subjects, screenshots, devices, mobile emulation, stop rules, dwell windows,
|
|
194
|
+
and failed-lane reruns. The [cost model](https://humanish.dev/docs/budgets-and-privacy#how-cost-estimates-work)
|
|
195
|
+
explains model selection, dated estimates, and study/per-participant caps.
|
|
628
196
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
registered computer-use actor routes here and requires `serve`; on earlier
|
|
634
|
-
versions that shape routed to the meta lab.)
|
|
197
|
+
Mobile viewport and touch flags do not certify gesture equivalence. The
|
|
198
|
+
[2026-09-05 input-conformance correction](docs/goals/computer-use-actor/receipts/mobile-input-conformance-2026-09-05.md)
|
|
199
|
+
qualifies the historical phone-lane results: they describe Humanish's measured input path,
|
|
200
|
+
not established physical-device app behavior.
|
|
635
201
|
|
|
636
202
|
#### Adapters: drive a local app via its JS state contract (no E2B, no vision)
|
|
637
203
|
|
|
638
|
-
|
|
639
|
-
**already-running local dev server** (`subject.source: local-app`) and drive it
|
|
640
|
-
through its in-process JS contract (`window.app.getState()` etc.) with a custom
|
|
641
|
-
`CuaExecutor` (screenshot optional, `appState` as the progress signal) paired with a
|
|
642
|
-
**non-vision** `CuaProvider` (`requiresFrame` falsey), keeping personas, the
|
|
643
|
-
Observer, the evidence bundle, redaction, and the friction loop, with **no E2B
|
|
644
|
-
desktop and no clone**. Supply `cuaHooks.buildExecutor` + `buildProvider` to
|
|
645
|
-
`runLab` (a config-only run with no hooks fails closed with a structured error). See
|
|
646
|
-
[State-driven executor](docs/architecture/state-driven-executor.md).
|
|
204
|
+
See [state-driven local adapters](https://humanish.dev/docs/computer-use#state-driven-local-adapters).
|
|
647
205
|
|
|
648
206
|
## Browser Scenario Manifests
|
|
649
207
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
falls back to the built-in two-step browser persona proof. Browser steps are
|
|
653
|
-
public-safe source, so use synthetic fixture values and committed relative app
|
|
654
|
-
paths only.
|
|
655
|
-
|
|
656
|
-
```yaml
|
|
657
|
-
schema: humanish.scenario.v1
|
|
658
|
-
id: todo-onboarding
|
|
659
|
-
title: Todo onboarding
|
|
660
|
-
persona: synthetic-new-user
|
|
661
|
-
goal: Create the first synthetic todo and verify the list updates.
|
|
662
|
-
mode: browser
|
|
663
|
-
browser:
|
|
664
|
-
startPath: /
|
|
665
|
-
steps:
|
|
666
|
-
- id: open-home
|
|
667
|
-
label: Open the todo app
|
|
668
|
-
action: goto
|
|
669
|
-
path: /
|
|
670
|
-
expect:
|
|
671
|
-
text: Add todo
|
|
672
|
-
- id: enter-todo
|
|
673
|
-
label: Enter synthetic todo text
|
|
674
|
-
action: fill
|
|
675
|
-
selector: input[name="todo"]
|
|
676
|
-
value: Synthetic onboarding task
|
|
677
|
-
- id: create-todo
|
|
678
|
-
label: Create the todo
|
|
679
|
-
action: click
|
|
680
|
-
selector: button[type="submit"]
|
|
681
|
-
expect:
|
|
682
|
-
text: Synthetic onboarding task
|
|
683
|
-
stateChanged: true
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
Supported actions are `goto`, `fill`, `click`, `assertText`, `waitForText`,
|
|
687
|
-
and `waitForSelector`. Supported expectations are `text`, `selectorVisible`,
|
|
688
|
-
`urlIncludes`, and `stateChanged`. Generated traces are stored as JSON under
|
|
689
|
-
`.humanish/runs/<run>/traces/` and summarized in the Observer.
|
|
208
|
+
See [scripted browser scenarios](https://humanish.dev/docs/lab-manifests#scripted-browser-scenarios)
|
|
209
|
+
for executable steps against a running local app.
|
|
690
210
|
|
|
691
|
-
##
|
|
211
|
+
## A First Live Run Without a Provider API Key
|
|
692
212
|
|
|
693
|
-
|
|
213
|
+
A [signed-in local Codex or Claude Code](https://humanish.dev/docs/local-agents)
|
|
214
|
+
can supply the participant's model. It consumes your existing plan; E2B still
|
|
215
|
+
requires a key and bills for desktops.
|
|
694
216
|
|
|
695
|
-
|
|
696
|
-
pnpm humanish -- watch oss
|
|
697
|
-
pnpm humanish -- lab run oss --dry-run --repos CorentinTh/it-tools,drawdb-io/drawdb,maciekt07/TodoApp,lissy93/dashy
|
|
698
|
-
```
|
|
217
|
+
## Three Roles
|
|
699
218
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
219
|
+
The researcher declares the study, the participant tries the product, and the
|
|
220
|
+
stakeholder reads what happened. [Three roles](docs/principles/three-roles.md)
|
|
221
|
+
explains the design; the [email-gated signup receipts](docs/goals/email-gated-signup/receipts/)
|
|
222
|
+
show a completed two-participant study and a reported keyboard-accessibility finding.
|
|
703
223
|
|
|
704
|
-
|
|
705
|
-
cloning repos, launching a provider sandbox, or forwarding credentials. Use:
|
|
224
|
+
## Maintainer OSS Meta-Lab Example
|
|
706
225
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
226
|
+
The bundled `oss` lab is a dry-run contract. Live OSS meta-lab execution is
|
|
227
|
+
unavailable until repository instructions have an isolated credential boundary.
|
|
228
|
+
See the [maintainer reference](https://humanish.dev/docs/lab-manifests#maintainer-oss-meta-lab-example).
|
|
710
229
|
|
|
711
|
-
|
|
712
|
-
have an isolated credential boundary. A live manifest fails closed with
|
|
713
|
-
`HUMANISH_OSS_META_LIVE_ISOLATION_REQUIRED` before callbacks, filesystem writes,
|
|
714
|
-
network access, or provider launch.
|
|
230
|
+
## Telemetry
|
|
715
231
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
not need or use private-repository credentials. Private-repository execution
|
|
720
|
-
remains unavailable while the live lane is disabled. Local bundles remain
|
|
721
|
-
ignored under `.humanish/`; do not publish private screenshots, logs, or
|
|
722
|
-
upstream details.
|
|
232
|
+
Humanish collects anonymous command usage by default, excluding labs, subjects,
|
|
233
|
+
personas, paths, and evidence. `humanish telemetry disable` or `DO_NOT_TRACK=1`
|
|
234
|
+
turns it off. See [TELEMETRY.md](TELEMETRY.md) for the exact fields.
|
|
723
235
|
|
|
724
236
|
## Development
|
|
725
237
|
|
|
@@ -741,29 +253,17 @@ pnpm humanish:lab:list
|
|
|
741
253
|
|
|
742
254
|
## Docs
|
|
743
255
|
|
|
744
|
-
[
|
|
745
|
-
|
|
746
|
-
Start with the current safety and capability state. Dated design documents may
|
|
747
|
-
preserve historical mechanisms and carry explicit amendments near the top.
|
|
748
|
-
|
|
256
|
+
- [User guides and generated CLI reference](https://humanish.dev/docs)
|
|
749
257
|
- [Current safety state and goals](docs/goals/current.md)
|
|
750
|
-
- [
|
|
751
|
-
- [Project layout](docs/architecture/project-layout.md)
|
|
752
|
-
- [Observer architecture](docs/architecture/observer.md)
|
|
753
|
-
- [Serve: the run library surface](docs/architecture/serve.md)
|
|
754
|
-
- [Actor contract (first-party registry and extension direction)](docs/architecture/actor-contract.md)
|
|
755
|
-
- [State-driven executor (drive a local app, no E2B/vision)](docs/architecture/state-driven-executor.md)
|
|
756
|
-
- [OSS lab design record (historical; see its current safety amendment)](docs/architecture/oss-lab-poc.md)
|
|
258
|
+
- [Contributor and agent ramp](docs/ramp/README.md)
|
|
259
|
+
- [Project layout and architecture](docs/architecture/project-layout.md)
|
|
757
260
|
- [Feedback contract](docs/contracts/feedback.md)
|
|
758
|
-
- [
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
- [Open-source release readiness](docs/release/open-source-readiness.md)
|
|
763
|
-
- [Public readiness standard](docs/release/public-readiness-standard.md)
|
|
261
|
+
- [Release readiness and gates](docs/release/open-source-readiness.md)
|
|
262
|
+
|
|
263
|
+
Dated design documents may preserve historical mechanisms. Start with the
|
|
264
|
+
current goals and the executable CLI when checking what is supported.
|
|
764
265
|
|
|
765
266
|
## Release Status
|
|
766
267
|
|
|
767
|
-
The package is published on npm.
|
|
768
|
-
|
|
769
|
-
maintainer explicitly approves it in the current context.
|
|
268
|
+
The package is published on npm. Publishing a new version requires explicit
|
|
269
|
+
maintainer authorization; see the [release procedure](docs/release/open-source-readiness.md#publish-procedure).
|