@wrktr/cli 0.2.0 → 0.4.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.
Files changed (2) hide show
  1. package/README.md +420 -8
  2. package/package.json +8 -8
package/README.md CHANGED
@@ -1,14 +1,426 @@
1
1
  # @wrktr/cli
2
2
 
3
- Agent-first git on Cloudflare: give each agent a branch and a worktree, keep them synced, and land them
4
- through review and CI.
3
+ Agent-first git on Cloudflare. Each agent gets a branch and a worktree of its own; a daemon commits and pushes
4
+ its work as it goes; every push runs your checks and a review agent; and a branch lands when its checks pass, its
5
+ review approves and no thread is open.
6
+
7
+ The CLI is headless first: everything you can do in the web app that an agent needs, it can do from here, with
8
+ `--json` output and no clone required (`--project`).
9
+
10
+ - [Install](#install)
11
+ - [Sign in](#sign-in)
12
+ - [The everyday loop](#the-everyday-loop)
13
+ - [Global flags](#global-flags)
14
+ - [Commands](#commands)
15
+ - [JSON output and exit codes](#json-output-and-exit-codes)
16
+ - [Environment variables](#environment-variables)
17
+ - [Files](#files)
18
+
19
+ ## Install
20
+
21
+ ```sh
22
+ npm i -g @wrktr/cli
23
+ # or, without Node:
24
+ curl -fsSL https://wrktr.com/install | sh
25
+ ```
26
+
27
+ Either way you get a standalone binary for your platform; it needs `git`. The install script puts it in
28
+ `~/.wrktr/bin` (`WRKTR_INSTALL_DIR` to change that) and installs the latest release (`WRKTR_VERSION` to pin one).
29
+
30
+ ## Sign in
31
+
32
+ On your own machine:
5
33
 
6
34
  ```sh
7
- npm i -g @wrktr/cli # or: curl -fsSL https://wrktr.com/install | sh
8
- wrktr login
9
- wrktr clone <org>/<project> # or, in a repo you have: wrktr init
10
- wrktr branch new <name>
11
- wrktr daemon install
35
+ wrktr login # approve the sign-in in your browser; saves a token in ~/.wrktr/config.json
36
+ wrktr whoami # who the CLI acts as
12
37
  ```
13
38
 
14
- A standalone binary per platform (no Node or Bun needed to run it); needs git. https://wrktr.com
39
+ In CI, containers and other agents, skip `login` and set a token instead:
40
+
41
+ ```sh
42
+ wrktr token create --name ci-deploy # run once, on your machine; you approve it in the browser
43
+ export WRKTR_TOKEN=<the token it printed>
44
+ ```
45
+
46
+ A token can't create tokens by itself: only a person signed in to the web app can approve a new one.
47
+
48
+ ## The everyday loop
49
+
50
+ ```sh
51
+ wrktr init # put the repo you're in on wrktr (or: wrktr clone <org>/<project>)
52
+ wrktr daemon install # keep worktrees committed, pushed and up to date, as a login service
53
+ wrktr branch new fix-login # a branch in its own worktree, under .wrktr/worktrees/fix-login
54
+ cd .wrktr/worktrees/fix-login # ...and just edit: the daemon commits and pushes after a quiet moment
55
+ wrktr status # checks, the review, open threads, conflicts
56
+ wrktr ci show --wait # wait for the checks; exits 1 unless they passed
57
+ wrktr feedback show # what the review asked for
58
+ wrktr feedback reply <id> "Fixed: the token now refreshes before it expires."
59
+ wrktr land --when-ready # lands by itself once checks, the review and threads allow it
60
+ ```
61
+
62
+ ## Global flags
63
+
64
+ Every command takes these, before or after the subcommand.
65
+
66
+ | Flag | |
67
+ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
68
+ | `--project <org>/<name>` | Act on that project on wrktr instead of the clone you're in. No clone is needed, so name the branch too (`--branch`, or the command's branch argument). Commands that act on this machine or your account (`login`, `whoami`, `token`, `init`, `clone`, `branch new`, `branch rm`, `branch ls` without `--all`, `skill`, `daemon`) refuse it. |
69
+ | `--json` | Print the result as JSON on stdout, and a failure as JSON on stderr. See [JSON output](#json-output-and-exit-codes). |
70
+ | `--help`, `-h` | Help for any command. |
71
+ | `--version`, `-v` | The CLI's version and build. |
72
+ | `--log-level <level>` | `all`, `trace`, `debug`, `info`, `warn`, `error`, `fatal` or `none`. |
73
+ | `--completions <shell>` | Print a completion script for `bash`, `zsh`, `fish` or `sh`. |
74
+ | `--wizard` | Build a command interactively. |
75
+
76
+ ## Commands
77
+
78
+ Where a command takes a branch and you leave it out, it uses the branch of the worktree you're standing in.
79
+
80
+ ### Account
81
+
82
+ #### `wrktr login`
83
+
84
+ Sign this machine in. By default it shows a code and opens the browser to approve it; the token it receives is
85
+ saved in `~/.wrktr/config.json`, readable only by you.
86
+
87
+ | Flag | |
88
+ | ------------------- | ---------------------------------------------------------------------------------------- |
89
+ | `--env <prod\|dev>` | Which wrktr to sign in to (default `prod`). Use a separate `WRKTR_HOME` per environment. |
90
+ | `--api <url>` | The API's base URL (overrides `--env`). |
91
+ | `--token <token>` | Use an existing access token, or an `op://` 1Password reference, instead of the browser. |
92
+
93
+ #### `wrktr whoami`
94
+
95
+ Who the CLI acts as, and the organizations they belong to with their role in each.
96
+
97
+ #### `wrktr token ls`
98
+
99
+ Your access tokens: name, prefix, when each was created and last used, and when it expires. Never the values.
100
+
101
+ #### `wrktr token create --name <name>`
102
+
103
+ Mint an access token for CI or another agent. It opens the browser so you can approve it (the page shows
104
+ `<name>`), then prints the token once on stdout, alone, so `wrktr token create --name ci | pbcopy` captures just
105
+ the token. Use it as `WRKTR_TOKEN`.
106
+
107
+ #### `wrktr token revoke <id>`
108
+
109
+ Revoke a token. Whatever uses it stops working at once. `<id>` can be the start of an id from `token ls`.
110
+
111
+ ### Projects
112
+
113
+ #### `wrktr init`
114
+
115
+ Create a wrktr project for the repo you're in and push it, or link the repo to an existing one. It registers the
116
+ repo with the daemon.
117
+
118
+ | Flag | |
119
+ | --------------- | -------------------------------------------------------------------------------- |
120
+ | `--name <name>` | The project's name (defaults to the repo folder's name). |
121
+ | `--org <org>` | The organization to put it in (defaults to the one it's linked to, or your own). |
122
+
123
+ #### `wrktr clone <org>/<project> [<directory>]`
124
+
125
+ Clone a project (into `<directory>`, by default the project's name) and register it with the daemon.
126
+
127
+ ### Branches
128
+
129
+ #### `wrktr branch new <name>`
130
+
131
+ Create a branch in its own worktree under `.wrktr/worktrees/<name>`, copy the files listed in `wrktr.json` `copy`
132
+ into it, run its `install` command, and push it. The daemon keeps it in sync from then on. A name used before is
133
+ reused only if that branch is fully merged.
134
+
135
+ | Flag | |
136
+ | -------------- | ----------------------------------------------------------- |
137
+ | `--from <ref>` | Where to start it (defaults to the default branch). |
138
+ | `--experiment` | A spike or prototype: it stays in progress and never lands. |
139
+
140
+ #### `wrktr branch ls`
141
+
142
+ The branches that have a worktree on this machine. With `--all`, every branch in progress on wrktr instead (its
143
+ head, state and when it last moved, newest first), from anywhere: it takes `--project`.
144
+
145
+ | Flag | |
146
+ | ---------- | --------------------------------------------------- |
147
+ | `--all` | List the branches on wrktr, not the worktrees here. |
148
+ | `--landed` | With `--all`, include branches that landed. |
149
+ | `--closed` | With `--all`, include branches that were closed. |
150
+
151
+ #### `wrktr branch show [<name>]`
152
+
153
+ What a branch does: the review agent's description of it (a title, a summary, the changes by area, risks and how
154
+ to check it), its head and its state. The description follows the branch as it moves; it says so when it was
155
+ written for an older head.
156
+
157
+ #### `wrktr branch rm <name>`
158
+
159
+ Remove a branch's worktree. Alias: `wrktr branch remove`.
160
+
161
+ | Flag | |
162
+ | ---------- | ----------------------------------------------------------------------- |
163
+ | `--force` | Remove it even with uncommitted changes (they're lost). |
164
+ | `--delete` | Also delete the branch, on wrktr and locally. Its review history stays. |
165
+
166
+ #### `wrktr branch experiment [<name>]`
167
+
168
+ Mark a branch as an experiment that never lands. `--off` lets it land again.
169
+
170
+ #### `wrktr branch close [<name>]`
171
+
172
+ Close a branch without landing it (a spike, an abandoned approach). Its agents and checks stop; its history and
173
+ reviews stay.
174
+
175
+ #### `wrktr branch reopen [<name>]`
176
+
177
+ Reopen a closed branch.
178
+
179
+ ### Code
180
+
181
+ Read a project's history and changes from wrktr, no clone needed.
182
+
183
+ #### `wrktr log [<ref>]`
184
+
185
+ Commits, newest first: short sha, date, author and subject. `<ref>` is a branch or a commit; it defaults to the
186
+ worktree's branch, or the default branch outside a clone. `--limit <n>` for how many (default 20).
187
+
188
+ #### `wrktr diff [<branch>]`
189
+
190
+ What a branch changes against its base: by default a stat, one line per file (`A`dded, `M`odified, `D`eleted,
191
+ `+added -deleted` lines), then the totals.
192
+
193
+ | Flag | |
194
+ | ----------------- | ---------------------------------------------------------- |
195
+ | `--patch`, `-p` | Every file's changes as a unified diff, like `git diff`. |
196
+ | `--file <path>` | Only this file's changes, as a unified diff. |
197
+ | `--base <branch>` | Compare against this branch (default: the default branch). |
198
+
199
+ ### Where a branch stands
200
+
201
+ #### `wrktr status`
202
+
203
+ The branch's head (and whether this worktree has commits not pushed yet), its state (in progress, landing when
204
+ ready, landed, closed, an experiment), its checks, the review agent's verdict, open threads, and whether it
205
+ conflicts with the default branch or the daemon can't sync it.
206
+
207
+ | Flag | |
208
+ | ----------------- | -------------------------------------------------------------------------- |
209
+ | `--branch <name>` | The branch. |
210
+ | `--watch` | Refresh every 10 seconds. With `--json`, prints one JSON line per refresh. |
211
+
212
+ #### `wrktr feedback show`
213
+
214
+ The branch's open reviews, their threads and failing checks: what an agent works through. `--branch <name>` for
215
+ another branch.
216
+
217
+ #### `wrktr feedback reply <id> <body>`
218
+
219
+ Reply to a review thread, as the agent: what you did, or why not. `--branch <name>` for another branch.
220
+
221
+ #### `wrktr feedback resolve <id>`
222
+
223
+ Mark a thread resolved. `--branch <name>` for another branch.
224
+
225
+ ### Reviews
226
+
227
+ #### `wrktr review ls <branch>`
228
+
229
+ A branch's reviews, newest first.
230
+
231
+ #### `wrktr review submit <branch>`
232
+
233
+ Review a branch, yours or another agent's: a summary, a verdict and line comments, in one go. Line numbers refer
234
+ to the branch's head.
235
+
236
+ | Flag | |
237
+ | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
238
+ | `--verdict <approve\|changes\|comment>` | Approve, request changes, or leave notes without a verdict. |
239
+ | `--summary <markdown>` | What you found. |
240
+ | `--comments <file.json>` | Line comments: `[{"path": "src/a.ts", "line": 12, "body": "..."}]`, or `{"comments": [...], "notes": ["..."]}` to add points that aren't about one line. |
241
+
242
+ #### `wrktr review dismiss <branch> <id>`
243
+
244
+ Set a review aside so it no longer counts. `<id>` can be the start of an id from `review ls`.
245
+
246
+ #### `wrktr review request [<branch>]`
247
+
248
+ Ask the review agent to review the branch's head now, replacing a review of it. It reviews by itself after each
249
+ push once checks pass; this is for a review that failed, or a fresh look at the same head.
250
+
251
+ ### CI
252
+
253
+ Each push runs the checks in `wrktr.json` `ci`. The review agent reads their results, and `land` waits for the
254
+ required ones to pass.
255
+
256
+ #### `wrktr ci show [<run>]`
257
+
258
+ A CI run: each check's state, time and notes (optional, cached, exit code, a retry), and the last lines of the
259
+ ones that failed. Without `<run>`, the branch head's run. `<run>` can be the start of an id from `ci runs`.
260
+
261
+ | Flag | |
262
+ | --------------------- | -------------------------------------------------------------------------------------------------------- |
263
+ | `--branch <name>` | The branch. |
264
+ | `--wait` | Wait until the head's run is over, then exit `1` unless it passed: `wrktr ci show --wait && wrktr land`. |
265
+ | `--timeout <seconds>` | With `--wait`, give up after this long (default 1800), exiting `1`. |
266
+
267
+ #### `wrktr ci runs`
268
+
269
+ The project's CI runs, newest first: status, branch, commit, how long each took. `--branch <name>` for one
270
+ branch's; `--limit <n>` for how many (default 10).
271
+
272
+ #### `wrktr ci log <check>`
273
+
274
+ A check's full log, as stored when it finished (`ci show` prints only the last lines of a failed one). Defaults
275
+ to the branch head's run: `--run <id>` for another, `--branch <name>` for another branch's head.
276
+
277
+ #### `wrktr ci rerun`
278
+
279
+ Run the branch head's checks again, ignoring results reused from an identical tree (for a flaky check, or one
280
+ that depends on something outside the repo). `--branch <name>` for another branch.
281
+
282
+ ### Landing
283
+
284
+ #### `wrktr land [<branch>]`
285
+
286
+ Land a branch on the default branch with a merge commit, made by the server. It lands only if checks pass, the
287
+ review agent approved the current head and no blocking thread is open (nits never block); otherwise it says
288
+ what's missing. Run from the branch's worktree, it refuses uncommitted changes and a head the daemon hasn't
289
+ pushed yet.
290
+
291
+ | Flag | |
292
+ | -------------- | ------------------------------------------------------------------------------------------------ |
293
+ | `--when-ready` | Don't land now: the server lands it (as you) as soon as it's ready. Nothing has to keep running. |
294
+ | `--cancel` | Stop waiting to land it (undoes `--when-ready`). |
295
+ | `--force` | Land even though checks, threads or the review say it isn't ready. |
296
+ | `--rm` | Remove the branch's worktree after landing, if it has no uncommitted changes. |
297
+
298
+ ### Deploys
299
+
300
+ Environments are declared in `wrktr.json` under `environments`. An `on: land` environment deploys every land by
301
+ itself; an `on: promote` one deploys the commit someone promotes.
302
+
303
+ #### `wrktr env ls`
304
+
305
+ The project's environments: what's live in each, what's running, and what a promotion would ship.
306
+
307
+ #### `wrktr env runs <environment>`
308
+
309
+ An environment's runs, newest first. `--limit <n>` for how many (default 10).
310
+
311
+ #### `wrktr env show <environment> <run>`
312
+
313
+ One run: every step (done or not) with its command and state, the last lines of a failed step's log, and the
314
+ commits it ships.
315
+
316
+ #### `wrktr env promote <environment> [<commit>]`
317
+
318
+ Deploy a commit to a promote environment: by default what its `from` environment has live. The commit must be
319
+ the full 40 characters. An older commit than what's live is a rollback.
320
+
321
+ #### `wrktr env rerun <environment> <run>`
322
+
323
+ Run an environment's newest run again, once it's over.
324
+
325
+ #### `wrktr env cancel <environment> <run>`
326
+
327
+ Stop a queued or running run.
328
+
329
+ ### Secrets
330
+
331
+ Values an environment's steps use, listed under `environments.<name>.secrets` in `wrktr.json`. They're stored
332
+ encrypted and only reach a deploy while it runs.
333
+
334
+ #### `wrktr secret set <name>`
335
+
336
+ Set a secret from stdin, never from the command line (so it isn't in your shell history): `pbpaste | wrktr secret
337
+ set CLOUDFLARE_API_TOKEN`. Owners only. Names are capitals, digits and `_`, starting with a letter.
338
+
339
+ #### `wrktr secret ls`
340
+
341
+ The project's secrets: names, who set each and when. Never the values.
342
+
343
+ #### `wrktr secret rm <name>`
344
+
345
+ Remove a secret. Owners only.
346
+
347
+ ### The daemon
348
+
349
+ The daemon keeps every worktree of every registered repo in sync: it commits after a quiet moment, pushes, merges
350
+ the default branch in, and writes the [files](#files) agents read.
351
+
352
+ #### `wrktr daemon`
353
+
354
+ Run it in the foreground.
355
+
356
+ | Flag | |
357
+ | ----------------- | ------------------------------------------------------------------------------------ |
358
+ | `--quiet-ms <ms>` | Commit after this long without file changes (overrides `wrktr.json`; default 30000). |
359
+ | `--poll-ms <ms>` | How often to check the remote (default 5000). |
360
+
361
+ #### `wrktr daemon install` / `upgrade` / `restart` / `uninstall`
362
+
363
+ Run it as a login service from a stable copy of the CLI; move the service to this CLI's build and restart it;
364
+ restart it; stop it and remove it. The service is a macOS LaunchAgent; elsewhere, run `wrktr daemon` under your
365
+ own supervisor (systemd, a container's entrypoint).
366
+
367
+ #### `wrktr daemon status`
368
+
369
+ What the running daemon is syncing, repo by repo and worktree by worktree, with any errors.
370
+
371
+ #### `wrktr daemon logs`
372
+
373
+ The service's log. `--follow` (`-f`) keeps printing; `--lines <n>` (`-n`) for how many lines (default 50).
374
+
375
+ ### Agent skill
376
+
377
+ #### `wrktr skill install`
378
+
379
+ Install the wrktr skill, which teaches coding agents (Claude Code and others) to work the wrktr way. `--dir
380
+ <path>` for another skills directory (defaults to `~/.claude/skills` and `~/.agents/skills`).
381
+
382
+ #### `wrktr skill show`
383
+
384
+ Print the skill (`SKILL.md`).
385
+
386
+ ## JSON output and exit codes
387
+
388
+ With `--json`:
389
+
390
+ - **stdout** carries exactly one JSON value: the command's result. Progress lines, and the output of a new
391
+ worktree's `install` command, go to stderr instead. `status --watch --json` is the exception: one JSON value
392
+ per line, one line per refresh. `wrktr daemon` (in the foreground) and `wrktr daemon logs` stream, so they
393
+ refuse `--json`.
394
+ - **A failure** prints `{"error": {"tag": "...", "message": "..."}}` on stderr. `tag` names the kind of failure
395
+ when there is one (`ProjectNotFound`, `Unauthorized`, `InvalidProjectFlag`, `ProjectFlagNotAllowed`,
396
+ `JsonNotSupported`, ...).
397
+
398
+ Exit codes: `0` when the command did what it was asked, `1` when it didn't (including a refusal, such as `land`
399
+ when the branch isn't ready). Act on the exit code, not the wording.
400
+
401
+ ```sh
402
+ wrktr status --project acme/api --branch fix-login --json | jq -r '.review.verdict'
403
+ wrktr land fix-login --project acme/api --json || echo "not landed yet"
404
+ ```
405
+
406
+ ## Environment variables
407
+
408
+ | Variable | |
409
+ | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
410
+ | `WRKTR_TOKEN` | An access token. When set, the CLI uses it instead of `~/.wrktr/config.json`, so no `login` is needed. |
411
+ | `WRKTR_API_URL` | The API to use with `WRKTR_TOKEN` (default `https://api.wrktr.com`). |
412
+ | `WRKTR_HOME` | Where the CLI keeps its config, state and the daemon's files (default `~/.wrktr`). Use one per wrktr environment. |
413
+ | `WRKTR_DEBUG` | Set to `1` to print a failure's full cause instead of one line. |
414
+ | `WRKTR_INSTALL_DIR`, `WRKTR_VERSION` | For the install script: where to put the binary, and which release. |
415
+
416
+ ## Files
417
+
418
+ | File | |
419
+ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
420
+ | `~/.wrktr/config.json` | The API and the access token (or an `op://` reference), written by `login`. |
421
+ | `wrktr.json` | At the repo root, committed. `copy`: gitignored files to copy into each new worktree (such as `.env`). `install`: a command run in each new worktree. `quietMs`: how long the daemon waits before committing. `maxFileBytes`: files larger than this are never committed. `ci`: the checks each push runs. `environments`: where the project deploys. |
422
+ | `.wrktr/worktrees/<branch>/` | Each branch's worktree. `.wrktr/` is kept out of git. |
423
+ | `.wrktr/FEEDBACK.md` | In a worktree: the branch's open review threads and failing checks. |
424
+ | `.wrktr/BEHIND.md` | Merging the default branch in conflicts: what to do. |
425
+ | `.wrktr/DAEMON.md` | The daemon can't sync this worktree: why. |
426
+ | `.wrktr/CONFLICT.json` | A rebase onto the remote stopped on conflicts: resolve them, then `git rebase --continue`. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrktr/cli",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Agent-first git on Cloudflare: a branch and a worktree per agent, live review, CI and landing.",
5
5
  "homepage": "https://wrktr.com",
6
6
  "bin": {
@@ -10,12 +10,12 @@
10
10
  "bin"
11
11
  ],
12
12
  "optionalDependencies": {
13
- "@wrktr/cli-darwin-arm64": "0.2.0",
14
- "@wrktr/cli-darwin-x64": "0.2.0",
15
- "@wrktr/cli-linux-x64": "0.2.0",
16
- "@wrktr/cli-linux-arm64": "0.2.0",
17
- "@wrktr/cli-linux-x64-musl": "0.2.0",
18
- "@wrktr/cli-linux-arm64-musl": "0.2.0",
19
- "@wrktr/cli-windows-x64": "0.2.0"
13
+ "@wrktr/cli-darwin-arm64": "0.4.0",
14
+ "@wrktr/cli-darwin-x64": "0.4.0",
15
+ "@wrktr/cli-linux-x64": "0.4.0",
16
+ "@wrktr/cli-linux-arm64": "0.4.0",
17
+ "@wrktr/cli-linux-x64-musl": "0.4.0",
18
+ "@wrktr/cli-linux-arm64-musl": "0.4.0",
19
+ "@wrktr/cli-windows-x64": "0.4.0"
20
20
  }
21
21
  }