@rness/cli 0.11.0 → 0.12.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
@@ -20,7 +20,7 @@ Inside a workspace, every `rness` delegates to the copy pinned in
20
20
 
21
21
  ## Commands
22
22
 
23
- rness create [<org>] [--repos a,b] [--agent claude] [--pm npm|pnpm|yarn|bun] [--ssh|--https] [--skip-install] -y
23
+ rness create [<org>] [--provider github] [--repos a,b] [--agent claude] [--pm npm|pnpm|yarn|bun] [--ssh|--https] [--skip-install] -y
24
24
  rness create <name> --blank [--agent claude] [--pm npm|pnpm|yarn|bun] [--skip-install] -y
25
25
  rness add <repo> [--scopes apps/web,packages/ui] [--ssh|--https] -y
26
26
  rness sync [--all] [--scope <name>] [--check] [--pull] [--agent <name>] -y
@@ -29,6 +29,8 @@ Inside a workspace, every `rness` delegates to the copy pinned in
29
29
  rness logout
30
30
  rness context [--scope <name>] [--json]
31
31
  rness status [<tab>]
32
+ rness pulse create [-y]
33
+ rness pulse sync
32
34
  rness validate
33
35
  rness mcp
34
36
 
@@ -87,7 +89,7 @@ the files a given agent needs, for the agents the team declares in
87
89
  applies it once the repository has been trusted interactively. Verified
88
90
  with Claude Code 2.1.284 on 2026-09-29. Each clone also gets `.mcp.json`,
89
91
  which registers the MCP server; see "MCP server". The same settings file
90
- carries two hooks, and so does `.claude/settings.json` at the workspace
92
+ carries three hooks, and so does `.claude/settings.json` at the workspace
91
93
  root, which `sync` writes on every machine; see "Hooks". Both places also
92
94
  get a Claude Code plugin, `.claude/skills/rness/`, with one command:
93
95
  `/rness:status [tab]`, the tables of `rness status`. rness owns those
@@ -104,7 +106,7 @@ the files a given agent needs, for the agents the team declares in
104
106
  ### Hooks
105
107
 
106
108
  With `claude` in `agents`, each clone's `.claude/settings.json` and the
107
- workspace root's carry two Claude Code hooks, both run by the pinned copy:
109
+ workspace root's carry three Claude Code hooks, all run by the pinned copy:
108
110
 
109
111
  - **At session start** (`SessionStart`, every source): a line for the
110
112
  developer — `rness 0.10.0 · acme · scope web — 3 standards, 2 decisions`
@@ -116,7 +118,10 @@ workspace root's carry two Claude Code hooks, both run by the pinned copy:
116
118
  - **After an edit** (`PostToolUse` on `Edit|Write`): when the file is under
117
119
  `.rness/`, its front-matter problems — or those of `rness.json` — go back
118
120
  to the model, which fixes them in the same turn. Any other edit costs one
119
- path check. Stale blocks are left to `sync`.
121
+ path check. Stale blocks are left to `sync`. With a pulse declared, the
122
+ edit is then marked on the board, broken or not; see "Pulse".
123
+ - **At session end** (`SessionEnd`): with a pulse declared, clears the marks
124
+ this session set and syncs the board; see "Pulse". Without one, nothing.
120
125
 
121
126
  Each hook is one fixed `sh` line: it runs
122
127
  `<.rness>/node_modules/@rness/cli/dist/bin/rness.js hook <event>` when that
@@ -127,12 +132,119 @@ hand counts as missing, and the next `sync` adds a second one. The team's
127
132
  own hooks stay where they are.
128
133
 
129
134
  Claude Code runs hooks from a committed settings file without asking each
130
- developer, including in `claude -p`. These two read `.rness/` and nothing
131
- else: they write no file, run no install and reach no network. Review a
132
- change to them like code. Verified with Claude Code 2.1.284 on 2026-09-29:
133
- in a clone and at the root, the model received the context; after an edit
134
- that broke a status, it received the problem. The `sh` line is not verified
135
- on Windows.
135
+ developer, including in `claude -p`. These three read `.rness/`, write
136
+ nothing in the workspace and run no install. Only with a pulse declared do
137
+ they reach the network, through a detached `rness` process that uses your
138
+ login; when that process fails, it writes why to `pulse.json` in rness's
139
+ configuration directory (`~/.config/rness/` by default), which the next
140
+ session start reads, says once and deletes. See "Pulse". Review a change to
141
+ them like code. Verified with Claude Code 2.1.284 on 2026-09-29: in a clone
142
+ and at the root, the model received the context; after an edit that broke a
143
+ status, it received the problem. The `sh` line is not verified on Windows.
144
+
145
+ ### Pulse
146
+
147
+ rness pulse create # once per organization: the board, then a first sync
148
+ rness pulse sync # as often as wanted
149
+
150
+ A projection of rness's state on the organization's GitHub Projects: a
151
+ project named **Agent Pulse**, where the team sees every document of
152
+ `.rness/` and when an agent is at work on one. rness writes the board and
153
+ never reads it back; if it is not in rness, it does not belong there.
154
+
155
+ - **Layout**: one item per document (a draft issue: its title, its path and a
156
+ link to it in `<org>/.rness`), and the fields `Status` (the union of the
157
+ collection fields' options: every contract status plus the ones found in
158
+ `.rness/`, in lifecycle order, at most 50), `Collection` (one option per tab of
159
+ `rness status`; not `Type`, which is GitHub's own issue-type field and
160
+ filter), `Agent` (`working`), `Session` (`claude · 1a2b3c4d`, plus the
161
+ agent type for a subagent) and `Path`. A board per directory, named as
162
+ `rness status` names its tab, filtered on its `Collection`, its columns
163
+ that collection's own steps: each collection has its own status field
164
+ (`ADR status`, `Specs status`, …; a directory without statuses is columned
165
+ by `Status`, which holds them all for the `All` table). `pulse sync`
166
+ remakes a board built by an earlier version (its URL changes once); a `Working` table, filtered on `Agent: working`. A first view named `View 1` (GitHub's default) becomes `All` when no `All` exists, on create and on sync, showing Title, Collection, Status and Session. Options are coloured (statuses by lifecycle: blue proposed, purple approved, yellow in progress, red blocked, green done, gray dropped; collections and `working` too); a sync recolours rness's options and leaves other options' colours alone. rness does
167
+ not set the project's visibility: the project gets GitHub's default for a
168
+ new organization project, which is private (`public: false`). Verified
169
+ with Claude Code 2.1.284 on 2026-09-29.
170
+ - **Login**: the pulse needs the `project` scope. `rness login` asks for it
171
+ when the workspace declares a pulse, or when `pulse create` needs it (in a
172
+ terminal it offers to log in; with `-y` or off a terminal it stops with
173
+ `the pulse needs a GitHub login: run rness login` or
174
+ `the pulse needs the project scope: run rness login`). A developer who
175
+ never uses the pulse grants nothing more than `repo read:org`. When GitHub
176
+ cannot be asked, the pulse says so (`cannot reach GitHub: …`, or GitHub's
177
+ own answer) instead of asking for a login. A classic `GITHUB_TOKEN` works
178
+ if it carries the scope; a fine-grained or GitHub App token reports no
179
+ scope, so the pulse refuses it whatever its permissions. An organization
180
+ that restricts OAuth apps must approve "Rness", as for its private
181
+ repositories.
182
+ - **`pulse create`** needs an `org` in `rness.json` (a blank workspace is
183
+ refused) and no pulse yet. It creates the project and at once writes
184
+ `"pulse": { "project": <number> }` (and the `provider`) into `rness.json`,
185
+ then adds the fields, options and views, and runs a first sync; its
186
+ `created` lines say what it added. If a step after the project fails, it
187
+ exits 1 with the pulse declared, and `rness pulse sync` completes the
188
+ layout. Commit `rness.json` in `.rness`. The number is that of the
189
+ project in the organization. A CLI older than 0.12.0 refuses the key, so
190
+ the pin moves first (`rness upgrade`). A workspace without a `provider`
191
+ whose repositories look like GitLab is refused before anything is
192
+ created: write `"provider": "github"` if the organization is on GitHub.
193
+ - **`pulse sync`**: creates the items that are missing, updates those whose
194
+ title, status or collection changed, archives those whose document is
195
+ gone, and adds the option or the board a new status or directory needs. It
196
+ says `synced 49 items: 2 updated, 47 unchanged`. An item converted to an
197
+ issue by hand is the team's: left alone, and its document gets a new
198
+ draft.
199
+ - **One way**: the board is only read to find rness's items. What someone
200
+ changes there by hand is overwritten at the next sync.
201
+ - **Hooks**, with `claude` in `agents` and a pulse declared: session start
202
+ marks the `In progress` plans of the session's scope `Agent: working`, with
203
+ the session; an edit of a document of `.rness/` marks it; session end clears
204
+ the marks of that session (its subagents' included) and syncs. Each one
205
+ starts a detached `rness` process and answers at once, so a slow network
206
+ never holds Claude Code; the session-end sync outlives Claude Code's exit.
207
+ Verified with Claude Code 2.1.284 on 2026-09-29: the detached process wrote
208
+ its file 3 s after `/exit`. It uses your login: with none, without the
209
+ scope, or when GitHub cannot be reached, nothing is sent, and the next
210
+ session start's banner says why, once:
211
+ `rness: pulse not updated — <reason>`, such as
212
+ `the pulse needs the project scope: run rness login` or
213
+ `cannot reach GitHub: …`. Two sessions marking one plan both write; the
214
+ last wins.
215
+ - **Rate**: rness sends its requests one after another, without pausing. A
216
+ first sync makes a draft and sets up to three fields per document — about
217
+ 200 requests for fifty documents; whether that stays under GitHub's
218
+ limits for creating content is to be confirmed on GitHub. Later syncs
219
+ touch only what changed.
220
+ - **Not yet**: GitLab and Atlassian. `create` lists them, disabled; a
221
+ workspace whose `rness.json` names one is refused by `pulse`. `Waiting`
222
+ and `Review` statuses, several agents on one board and hooks for agents
223
+ other than Claude Code are not built.
224
+
225
+ ### Provider
226
+
227
+ `rness.json` records where the organization lives:
228
+ `"provider": "github"`, between `contract` and `org`. Every command talks to
229
+ it through one adapter; `git` still does what git does (clone, pull, push,
230
+ credentials), and the provider's API the rest (organizations, creating a
231
+ repository, the board).
232
+
233
+ - `rness create` asks `Where does your organization live?`: GitHub, and
234
+ GitLab and Atlassian (Bitbucket + Jira) shown disabled, coming later.
235
+ `--provider github` answers it off a terminal. A blank workspace asks
236
+ nothing. Joining an organization asks first as well, then takes the
237
+ provider its `rness.json` names.
238
+ - A workspace without the key is read from its first repository URL: a
239
+ GitLab host reads as `gitlab`, any other host — or no repository — as
240
+ `github`. Nothing to change: `pulse create` writes it, and refuses a
241
+ detected provider this version cannot talk to. The order of keys is
242
+ `contract`, `provider`, `org`, `agents`, `pulse`, `repos`, `scopes`.
243
+ - A provider _written_ in `rness.json` that this version cannot talk to
244
+ (`gitlab`) is refused by `validate`, `create`, `login` and `pulse`:
245
+ `provider "gitlab" is not supported by @rness/cli 0.12.0 (supported:
246
+ github)`. `add`, `sync` and the local commands never refuse. `null` is not a
247
+ value: an absent key means none.
136
248
 
137
249
  ### MCP server
138
250
 
@@ -184,7 +296,8 @@ anonymously.
184
296
  hours and is renewed on its own. `GITHUB_TOKEN`, then `GH_TOKEN`, win over
185
297
  it — CI needs no login.
186
298
  - rness asks for `repo` and `read:org`: GitHub has no read-only scope for
187
- private repositories. It only lists and clones.
299
+ private repositories. It only lists and clones. Where the workspace
300
+ declares a pulse it asks for `project` too; see "Pulse".
188
301
  - A new workspace has to reach GitHub before teammates can join it. Logged
189
302
  in, the `create` wizard offers to do it: it creates the private repository
190
303
  `<org>/.rness` and pushes the context with `git`. Declined, refused by
@@ -306,6 +419,29 @@ per repository, the files to commit there.
306
419
  Exit codes: 0 success, 1 failure, 2 usage — or a refusal without a TTY.
307
420
  `RNESS_DEBUG=1` adds stack traces; `RNESS_NO_DELEGATE=1` skips the delegation.
308
421
 
422
+ ## 0.12.0 — `rness pulse`; the provider
423
+
424
+ - `rness pulse create` and `rness pulse sync`: the Agent Pulse board on the
425
+ organization's GitHub Projects, a projection of `.rness/`. See "Pulse".
426
+ `rness login` asks for the `project` scope where the workspace declares a
427
+ pulse.
428
+ - `rness.json` gains two optional keys of contract 1: `provider` (`github`;
429
+ `gitlab` and `atlassian` are listed as not available) and
430
+ `pulse: { "project": <number> }`. A CLI older than 0.12.0 refuses them:
431
+ move the pin (`rness upgrade`) before either is written. `create` asks
432
+ `Where does your organization live?`, or takes `--provider github`. See
433
+ "Provider".
434
+ - With `claude` in `agents`, `sync` adds a third hook, `SessionEnd`
435
+ (`rness hook session-end`), to each clone's `.claude/settings.json` and to
436
+ the workspace root's. `rness upgrade` syncs, so it adds it; then commit
437
+ `.claude/settings.json` in each repository, as its next steps list. Until
438
+ then `sync --check` and `validate` report the hook missing. The two
439
+ existing hook lines do not change.
440
+ - With a pulse declared, the hooks mark and clear the plans an agent works
441
+ on, through a detached process. See "Hooks".
442
+ - One status field per collection (`ADR status`, `Specs status`, `Plans status`, …); each board's columns are that collection's steps and only them. `rness pulse sync` remakes a board built by an earlier version (its URL changes once) and renames a first view named `View 1` to `All` when no `All` exists.
443
+ - Blocks are unchanged.
444
+
309
445
  ## 0.11.0 — `rness status`; `/rness:status` in Claude Code
310
446
 
311
447
  - `rness status [tab]`: every decision, specification and plan — and any
package/dist/bin/rness.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  findDelegate,
7
7
  reportError,
8
8
  run
9
- } from "../chunk-LW4S5OLI.js";
9
+ } from "../chunk-AEW7ZDFS.js";
10
10
 
11
11
  // src/bin/rness.ts
12
12
  import { pathToFileURL } from "url";