rl-workspaces 0.0.0-stage → 0.6.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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +735 -2
  3. package/bin/rl +54 -0
  4. package/config.example.zsh +9 -0
  5. package/dist/access.js +40 -0
  6. package/dist/activity.js +90 -0
  7. package/dist/agent-claude.js +16 -0
  8. package/dist/agent-codex.js +22 -0
  9. package/dist/agent-launch.js +74 -0
  10. package/dist/agent-presets.js +70 -0
  11. package/dist/agent-registry.js +8 -0
  12. package/dist/agent-resume.js +96 -0
  13. package/dist/agent-runner.js +386 -0
  14. package/dist/agent-workflows.js +275 -0
  15. package/dist/agents.js +73 -0
  16. package/dist/automation-config.js +381 -0
  17. package/dist/base.js +66 -0
  18. package/dist/cleanup-path.js +33 -0
  19. package/dist/cli.js +57 -0
  20. package/dist/codex-sessions.js +188 -0
  21. package/dist/command-context.js +67 -0
  22. package/dist/common.js +262 -0
  23. package/dist/delete.js +113 -0
  24. package/dist/display.js +134 -0
  25. package/dist/doctor.js +145 -0
  26. package/dist/git-safety.js +24 -0
  27. package/dist/git-workflow.js +89 -0
  28. package/dist/help.js +726 -0
  29. package/dist/hooks.js +159 -0
  30. package/dist/json.js +34 -0
  31. package/dist/mcp.js +336 -0
  32. package/dist/picker.js +182 -0
  33. package/dist/pr-discovery.js +223 -0
  34. package/dist/pr-update.js +419 -0
  35. package/dist/pr-workflow.js +161 -0
  36. package/dist/repos.js +537 -0
  37. package/dist/review-policy.js +150 -0
  38. package/dist/session-workflows.js +650 -0
  39. package/dist/session.js +12 -0
  40. package/dist/state.js +250 -0
  41. package/dist/storage.js +366 -0
  42. package/dist/store.js +379 -0
  43. package/dist/summary.js +164 -0
  44. package/dist/task-state.js +65 -0
  45. package/dist/task.js +192 -0
  46. package/dist/templates.js +4 -0
  47. package/dist/workflow-collaboration.js +531 -0
  48. package/dist/workflow-config.js +177 -0
  49. package/dist/workflow.js +211 -0
  50. package/lib/rl.zsh +329 -0
  51. package/node_modules/graceful-fs/LICENSE +15 -0
  52. package/node_modules/graceful-fs/README.md +143 -0
  53. package/node_modules/graceful-fs/clone.js +23 -0
  54. package/node_modules/graceful-fs/graceful-fs.js +448 -0
  55. package/node_modules/graceful-fs/legacy-streams.js +118 -0
  56. package/node_modules/graceful-fs/package.json +53 -0
  57. package/node_modules/graceful-fs/polyfills.js +355 -0
  58. package/node_modules/proper-lockfile/LICENSE +21 -0
  59. package/node_modules/proper-lockfile/README.md +183 -0
  60. package/node_modules/proper-lockfile/index.js +40 -0
  61. package/node_modules/proper-lockfile/lib/adapter.js +85 -0
  62. package/node_modules/proper-lockfile/lib/lockfile.js +342 -0
  63. package/node_modules/proper-lockfile/lib/mtime-precision.js +55 -0
  64. package/node_modules/proper-lockfile/package.json +71 -0
  65. package/node_modules/retry/.npmignore +3 -0
  66. package/node_modules/retry/.travis.yml +15 -0
  67. package/node_modules/retry/License +21 -0
  68. package/node_modules/retry/Makefile +18 -0
  69. package/node_modules/retry/README.md +227 -0
  70. package/node_modules/retry/equation.gif +0 -0
  71. package/node_modules/retry/example/dns.js +31 -0
  72. package/node_modules/retry/example/stop.js +40 -0
  73. package/node_modules/retry/index.js +1 -0
  74. package/node_modules/retry/lib/retry.js +100 -0
  75. package/node_modules/retry/lib/retry_operation.js +158 -0
  76. package/node_modules/retry/package.json +32 -0
  77. package/node_modules/retry/test/common.js +10 -0
  78. package/node_modules/retry/test/integration/test-forever.js +24 -0
  79. package/node_modules/retry/test/integration/test-retry-operation.js +258 -0
  80. package/node_modules/retry/test/integration/test-retry-wrap.js +101 -0
  81. package/node_modules/retry/test/integration/test-timeouts.js +69 -0
  82. package/node_modules/signal-exit/LICENSE.txt +16 -0
  83. package/node_modules/signal-exit/README.md +39 -0
  84. package/node_modules/signal-exit/index.js +202 -0
  85. package/node_modules/signal-exit/package.json +38 -0
  86. package/node_modules/signal-exit/signals.js +53 -0
  87. package/package.json +57 -4
  88. package/shell/rl.zsh +11 -0
package/README.md CHANGED
@@ -1,3 +1,736 @@
1
- # Temporary Holding Version
1
+ # rl
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Git workspaces for Codex and Claude Code.
4
+
5
+ Create a workspace, start an agent, and keep task notes and sessions together.
6
+ Switch projects, prepare local dependencies, check PRs, and merge finished work
7
+ without losing your place.
8
+
9
+ Requires macOS or Linux, Git, zsh, and Node.js 22+. Bash users can use the Bash
10
+ integration. Install `fzf` for pickers, `gh` for PR commands, and whichever agent
11
+ you use.
12
+
13
+ ## Install
14
+
15
+ Install from npm:
16
+
17
+ ```sh
18
+ npm install --global rl-workspaces
19
+ ```
20
+
21
+ See Development below to build and try unpublished changes.
22
+
23
+ Add one line to your shell configuration, then open a new terminal:
24
+
25
+ ```sh
26
+ eval "$(command rl setup shell zsh)" # ~/.zshrc
27
+ # or
28
+ eval "$(command rl setup shell bash)" # ~/.bashrc
29
+ ```
30
+
31
+ Shell integration lets `rl` change your terminal's directory. Direct executable
32
+ calls print the selected path. The integration loads the current runtime on
33
+ each call, so an npm upgrade does not leave you using old commands.
34
+
35
+ ## Get started
36
+
37
+ ```sh
38
+ rl repo add . --base origin/test
39
+ rl switch feature/login -c --agent codex
40
+ # or: rl switch feature/login -c --agent claude
41
+
42
+ rl notes append progress implementation-notes.md
43
+ rl list
44
+ rl switch @ # main checkout
45
+ rl switch - # previous workspace in this shell
46
+ rl switch feature/login
47
+ rl resume codex
48
+ ```
49
+
50
+ The default base is `origin/test`. Use `--base`, `RL_DEFAULT_BASE`, or a registered
51
+ repository's base setting to choose another branch. Creation fetches origin first,
52
+ then branches from the refreshed remote base (including an explicit `--base origin/<branch>`).
53
+ A failed fetch stops creation. This refreshes remote refs without merging into a local
54
+ branch; add `--no-fetch` to work offline using cached refs. Notes and session links
55
+ survive workspace deletion.
56
+
57
+ ## Commands and help
58
+
59
+ `rl help` shows a short list of command families. Arguments, options and examples
60
+ live in command-specific help, which works even outside a configured repository:
61
+
62
+ ```sh
63
+ rl help
64
+ rl help pr
65
+ rl help pr update
66
+ rl workflow run --help
67
+ ```
68
+
69
+ Invalid arguments show usage for that command instead of the full command list.
70
+ Git helpers live under `rl git`, shared documents under `rl notes`, saved sessions
71
+ under `rl agent`, cleanup under `rl storage`, and project/shell setup under
72
+ `rl setup`. Review policies remain separate from agent profiles and workflows.
73
+
74
+ | Command | Use |
75
+ | --- | --- |
76
+ | `rl` | Pick a workspace |
77
+ | `rl checkout` | Switch to a repository |
78
+ | `rl switch` | Open or create a workspace |
79
+ | `rl list` | List workspaces, optionally across repositories |
80
+ | `rl status` | Inspect the selected repository (`--workspace` for workspace details) |
81
+ | `rl delete` | Remove workspaces |
82
+ | `rl storage` | Inspect disk usage and clean generated files |
83
+
84
+ `rl help switch` also documents the specialized `new`, `open`, and `path`
85
+ helpers. `rl help exec` describes running an arbitrary command in a workspace.
86
+
87
+ Switching installs hooks and preserves existing notes. Creation validates names
88
+ and refuses path escapes or an already checked-out branch. `switch -c` requires a
89
+ new checkout; `new` and `open` can reopen an existing checkout. `open` flattens
90
+ slashes in directory names; `new` and `switch -c` retain nested names.
91
+
92
+ Pickers show cached PR state, commits ahead/behind the base, and recent use.
93
+ The `COMMITS + / −` column counts commits ahead/behind, rather than changed lines.
94
+ The picker compares with its displayed base; the status overview compares with the
95
+ displayed upstream. `CHANGES` reports changed files separately.
96
+ PR discovery uses `gh`; `RL_PR_OFFLINE=1` disables it. Status is offline by default.
97
+ `--fetch` explicitly refreshes tracking refs.
98
+
99
+ ## Project setup
100
+
101
+ ```sh
102
+ rl setup init
103
+ # Edit .rl/workflows.json in the main checkout.
104
+ rl setup --dry-run
105
+ rl setup
106
+ # Or: rl switch feature/login -c --setup
107
+ ```
108
+
109
+ Example configuration:
110
+
111
+ ```json
112
+ {
113
+ "copy": [".env", ".cache"],
114
+ "clean": ["node_modules", ".next", ".turbo"],
115
+ "env": { "APP_MODE": "development" },
116
+ "onCreate": [["npm", "ci"]],
117
+ "onOpen": []
118
+ }
119
+ ```
120
+
121
+ Setup runs only when explicitly requested. Commands are argument arrays, executed
122
+ in order without a shell; a failure stops setup and preserves the workspace.
123
+ `rl setup` runs both command lists. `switch --setup` runs `onCreate` for a new
124
+ checkout and `onOpen` whenever it opens one.
125
+
126
+ Copy entries must be ignored, untracked regular files or directories in both
127
+ checkouts. RL validates the complete copy plan before writing, skips existing
128
+ files, and copies independently using filesystem cloning where available.
129
+ Symlinks, tracked files, path escapes, and Git/agent/state configuration paths
130
+ are rejected.
131
+
132
+ Setup, `exec`, and agent launch receive the configured environment,
133
+ `RL_WORKSPACE`, and a stable `RL_PORT` derived from the repository and workspace.
134
+ Use `RL_PORT` in your development server command. It is a suggested port, not a
135
+ reservation; another process can occupy it. Project environment keys are limited
136
+ to `APP_*`, `PUBLIC_*`, `VITE_*`, `NEXT_PUBLIC_*`, `REACT_APP_*`, `PORT`,
137
+ `NODE_ENV`, `DATABASE_URL`, and `REDIS_URL`. Runtime loader, executable search,
138
+ agent configuration, and permission variables cannot be overridden by the project.
139
+
140
+ ## Storage and cleanup
141
+
142
+ These commands operate only on the current adopted RL workspace, including when
143
+ run from a directory inside it. They reject workspace selectors and cross-repository
144
+ routing. They do not scan or clean sibling worktrees.
145
+
146
+ ```sh
147
+ rl storage # disk usage, largest paths, and cleanup suggestions
148
+ rl storage --json # structured usage report
149
+ rl storage clean --dry-run # preview configured generated directories and savings
150
+ rl storage clean # remove those generated directories
151
+ ```
152
+
153
+ Add a `clean` array to `.rl/workflows.json` in the current workspace:
154
+
155
+ ```json
156
+ { "clean": ["node_modules", ".next", ".turbo"] }
157
+ ```
158
+
159
+ The default list is empty. Entries must be literal, ignored directory paths.
160
+ Cleanup validates the complete plan before deleting anything and refuses tracked
161
+ files, credentials such as `.env`, Git/agent/task metadata, and symlink targets.
162
+ Links inside generated directories are unlinked without traversing their targets.
163
+ Code changes, branches, notes, sessions, and task handoffs stay in place. Close
164
+ development servers before cleaning their dependencies; use your project's install
165
+ and build commands to regenerate them later.
166
+
167
+ Storage reports approximate allocated sizes, deduplicating hard links within the
168
+ workspace. Cleanup estimates exclude hard-linked file data retained outside the
169
+ selected directories; filesystem clones and snapshots can also reduce actual
170
+ savings. Suggestions use the current workspace's last-access time (14 days by
171
+ default, configurable with `--older-than 30d`) and its cached PR state. Nothing is
172
+ deleted automatically.
173
+
174
+ ## Finish a feature
175
+
176
+ Use Git directly to inspect changes, commit, rebase, or squash feature history.
177
+ RL handles merging across checkouts and removing the finished workspace:
178
+
179
+ ```sh
180
+ rl git merge test --dry-run
181
+ rl git merge test --cleanup
182
+ ```
183
+
184
+ Merge targets a checked-out local branch in the main or a managed checkout.
185
+ It requires clean source and target workspaces and defaults to fast-forward only.
186
+ For an explicit squash merge, use `rl git merge test --squash -m "Add login"`.
187
+ Conflicts are left available for normal Git resolution. Nothing implicitly
188
+ stashes changes or force-pushes.
189
+
190
+ `--cleanup` removes the clean source checkout only after successful integration.
191
+ An unmerged source branch is retained if Git refuses safe branch deletion,
192
+ including after a squash merge. The main checkout cannot be removed.
193
+
194
+ ```sh
195
+ rl delete old-task another-task
196
+ rl delete --dry-run old-task
197
+ rl delete --force abandoned-task
198
+ ```
199
+
200
+ Default deletion refuses dirty workspaces and branches not merged into their
201
+ upstream, or the main checkout when no upstream exists. `--force` explicitly
202
+ discards uncommitted work and unmerged local branches. Remote branches are never
203
+ deleted. Locked worktrees remain protected. Deletion supports the multi-select
204
+ picker and `--jobs 1..32` (default 4), retaining notes and session history.
205
+
206
+ ## Pull requests
207
+
208
+ ```sh
209
+ rl pr # open this branch's PR in your browser
210
+ rl pr sync # save this branch's PR state
211
+ rl pr show # readable saved snapshot with the full PR link
212
+ rl pr show --json # saved metadata for scripts
213
+ rl pr checks [--json] # query checks and preserve gh's exit status
214
+ rl pr checkout 123 # new managed pr-123 workspace
215
+ rl pr checkout 123 --name review/login
216
+ rl pr update --base test # select your RL session PRs behind test, then update them
217
+ rl pr update 123 456 --base test --dry-run # preview an explicit selection
218
+ ```
219
+
220
+ `rl status --workspace` groups Git, PR, session, and task details with aligned labels,
221
+ relative cache times, and terminal colors (`NO_COLOR=1` disables colors);
222
+ use `rl status --workspace --json` for scripts. `rl pr sync --json` keeps machine-readable
223
+ refresh output. `rl pr show` works offline. `rl pr` uses the saved URL when
224
+ available; if the browser cannot open, that link remains in its output. With no
225
+ saved PR, it looks up the current branch through `gh pr view --web`.
226
+
227
+ Opening, refreshing, checks, and checkout require authenticated `gh`. Checkout verifies the origin repository,
228
+ PR identity, and fetched commit before creating a workspace. Fork PR checkout
229
+ is currently rejected. It does not change your current branch, publish, or merge
230
+ a PR. Failed refreshes retain the previous snapshot.
231
+
232
+ `rl pr update` brings selected PR branches up to date by merging the latest base
233
+ branch into them on GitHub. Run it from your current adopted RL workspace; it
234
+ uses that repository's configured base by default, or `--base test` / `origin/test`.
235
+ Only PR branches belonging to your active RL session workspaces in this repository
236
+ are eligible. Deleted session records and unrelated PRs are excluded. Saved Codex
237
+ or Claude conversations and a cached PR link are not required: RL matches the
238
+ live PR's head branch to its workspace records. Explicit PR numbers follow the
239
+ same restriction, and session ownership is checked again before each update.
240
+ PRs remain open. This command updates remote branches and requires authenticated
241
+ `gh` with permission to update those PRs. Local branches, edits, sessions, and
242
+ sibling worktrees are left in place; it creates no additional worktrees.
243
+
244
+ Without PR numbers, `fzf` lets you select multiple open PRs from your RL sessions
245
+ targeting the chosen base and missing some of its commits. Tab selects, Ctrl-A
246
+ selects all displayed rows, and Enter updates the selection. The picker checks up
247
+ to 100 matching session PRs by default;
248
+ `--limit` accepts 1–200, and a single batch accepts at most 50 selections. Explicit
249
+ numbers avoid the picker. `--dry-run` performs read-only checks and reports what
250
+ would be updated. If GitHub hasn't calculated mergeability yet, the preview says so.
251
+
252
+ Each result includes the PR link, branch, behind count in commits, and an outcome:
253
+ updated, already up to date, conflict, changed since selection, failed, pending,
254
+ or skipped. RL continues after individual failures and prints a final summary;
255
+ `--json` provides structured results. GitHub's update request checks the expected
256
+ PR head commit so concurrent changes are rejected. RL verifies that the base is
257
+ included before reporting an update as complete; accepted updates that cannot
258
+ yet be verified stay pending. Conflicts and other incomplete outcomes return a
259
+ nonzero exit status. Closed, retargeted, and fork PRs are skipped.
260
+
261
+ ## Codex and Claude
262
+
263
+ ### Pause a task and continue later
264
+
265
+ Tell your agent “pause this task” once it has RL hooks or the RL MCP tools.
266
+ It saves a handoff containing the current session, concrete changes, reported
267
+ validation results, next steps, and blockers. The hook context tells agents how
268
+ to do this; MCP exposes `rl_task_pause` for a structured save.
269
+
270
+ ```sh
271
+ rl continue # most recently paused task in the selected repository
272
+ rl continue feature/login # choose a specific branch or workspace
273
+ rl continue --no-agent # open it and print the handoff without launching an agent
274
+ ```
275
+
276
+ With shell integration, `continue` changes your terminal's directory. It resumes
277
+ the exact conversation saved in the handoff, including when another session was
278
+ used more recently, and supplies the handoff as the initial prompt. It also points
279
+ the agent to the full shared context/progress documents. Hooks are not required
280
+ to deliver this continuation prompt. A failed launch leaves the task paused;
281
+ a newer handoff saved during the resumed session is retained. When no tasks are
282
+ paused, `continue` opens the most recently continued task. Selection stays within
283
+ the repository chosen by RL's normal routing or `--repo`.
284
+
285
+ An agent can save directly from its shell:
286
+
287
+ ```sh
288
+ rl pause --summary "Login error states" \
289
+ --changes "Added client-side validation in src/login.ts" \
290
+ --validation "Unit tests passed; browser checks not run" \
291
+ --next "Implement the server-error state, then run browser checks" \
292
+ --blockers "Waiting for final copy"
293
+ ```
294
+
295
+ Codex's current UUID is inferred from its environment. Outside Codex, pass
296
+ `--session <UUID>`; Claude also requires `--agent claude --session <UUID>`.
297
+ For automation, `rl pause --file handoff.json` or `rl pause --file -` accepts
298
+ JSON with `summary`, `changes`, `validation`, `next`, optional `blockers`,
299
+ `agent`, and `sessionId`. `--json` prints the saved checkpoint. Required text
300
+ fields cannot be empty; use “Not run” for checks that were not performed.
301
+
302
+ Pausing saves the handoff and session together under the state lock. It does not
303
+ stop the agent or alter Git files. Every checkpoint stays in the workspace's
304
+ `task.handoffs` history, including after workspace deletion. `rl status --workspace` includes
305
+ the saved handoffs, and `rl list` adds a TASK column showing `paused` or `active`.
306
+
307
+ ### Start and resume agents
308
+
309
+ ```sh
310
+ rl agent start codex -- --model <model>
311
+ rl agent start claude
312
+ rl agent run codex --prompt "Review the change" -- --json
313
+ rl agent run claude --prompt "Review the change"
314
+ rl agent handoff claude --output handoff.md
315
+ rl resume # choose among this workspace's Codex and Claude sessions
316
+ rl resume --latest # resume the most recently used session directly (-l / --l)
317
+ rl resume codex # choose only among Codex sessions
318
+ rl resume codex --latest # resume the most recently used Codex session directly
319
+ rl resume claude # choose only among Claude sessions
320
+ rl agent save codex # from inside Codex, if needed
321
+ rl doctor
322
+ rl doctor --repair
323
+ ```
324
+
325
+ Both launch modes preserve agent options after `--`, use the selected workspace,
326
+ and return the agent's exit status. Headless mode uses `codex exec` or
327
+ `claude --print`. RL leaves permissions and authentication to the agent.
328
+
329
+ `rl resume` lists saved Codex and Claude sessions for the current RL workspace.
330
+ If multiple sessions match, an `fzf` picker shows the agent, full session UUID,
331
+ last-used time, and start time, with the most recently used first. If exactly
332
+ one session matches, it resumes automatically. An optional `codex` or `claude`
333
+ argument filters the choices. Escape cancels without launching an agent.
334
+ Use `--latest` (or `-l` / `--l`) to skip the picker and resume the most recently
335
+ used matching session directly.
336
+ `rl continue` still resumes the exact session saved in its task handoff.
337
+
338
+ Run Codex normally in an adopted RL workspace, including in the Codex app.
339
+ `rl status`, `rl list`, `rl instances`, `rl agent sessions`, and `rl resume` / `rl resume codex`
340
+ automatically discover and save matching sessions through Codex's
341
+ [`thread/list` API](https://learn.chatgpt.com/docs/app-server#list-threads-with-pagination--filters).
342
+ Discovery filters by the exact workspace directory, excludes subagents and
343
+ ephemeral sessions, and checks branch metadata and existing ownership. Without
344
+ branch metadata, only sessions created after workspace adoption are imported.
345
+ It reads metadata from Codex's state database, preserves newer saved usage times,
346
+ and leaves saved sessions available if Codex is missing or discovery fails.
347
+ Overview tables show saved session counts in the CODEX and CLAUDE columns.
348
+
349
+ An agent can also run `rl agent save` (Codex by default) or
350
+ `rl agent save codex`; this uses its `CODEX_THREAD_ID`, falling back to
351
+ `CODEX_SESSION_ID`. `rl agent save <agent> <UUID>` explicitly saves a particular conversation.
352
+ Repeated saves update the existing entry. Resume uses the exact recorded UUID.
353
+ Observed Codex `thr_...` IDs are diagnostic only until UUID association is available.
354
+
355
+ Hooks supply shared context/progress at session start, after compaction, and to
356
+ subagents. Prompt submission refreshes changed notes. Codex hooks must be reviewed
357
+ and trusted with `/hooks` before they run; session discovery works independently.
358
+
359
+ | Integration | Codex | Claude Code |
360
+ | --- | --- | --- |
361
+ | Interactive / headless launch | `codex` / `codex exec` | `claude` / `claude --print` |
362
+ | Resume | `codex resume <UUID>` | `claude --resume <UUID>` |
363
+ | Project hooks | `.codex/hooks.json` | `.claude/settings.local.json` |
364
+ | Shared lifecycle | SessionStart, UserPromptSubmit, Stop, SessionEnd, SubagentStart, SubagentStop | Same |
365
+ | Optional extended hooks | Interrupt | StopFailure, Notification |
366
+
367
+ Run `rl setup adopt --extended-hooks` only with agent versions supporting those events.
368
+ Adoption preserves unrelated hooks/settings and excludes generated files locally.
369
+ It never edits global agent configuration. Review agent hook trust and restart
370
+ the agent after adoption or repair.
371
+
372
+ Doctor reports PATH/version/help probes, installed handlers, and observed events.
373
+ Installed help is evidence for launch options; installed files are not proof of
374
+ trusted hook delivery. Activity is `working`, `idle`, `ended`, or `stale` after
375
+ 30 minutes without an event. It describes observations, not process liveness.
376
+
377
+ Compatibility is tested with documented payloads, stub processes, and installed
378
+ CLI help: Codex 0.160.1 and Claude Code 2.1.290. Live model sessions and all older
379
+ versions are not certified. See the official [Codex hooks](https://learn.chatgpt.com/docs/hooks)
380
+ and [Claude hooks](https://code.claude.com/docs/en/hooks) contracts.
381
+
382
+ ## Session-driven agent workflows
383
+
384
+ An adopted workspace has a built-in `writer-reviewer-dry` workflow immediately,
385
+ without creating configuration files. Your current Codex or Claude session
386
+ creates and controls its native children. RL supplies their editable roles,
387
+ handoff rules, review policy and durable run records. RL never launches a
388
+ provider CLI, model API or check process for a workflow.
389
+
390
+ The default team starts together and stays available for the task:
391
+
392
+ - **Writer** implements scoped changes. Before adding a function, it asks DRY
393
+ about existing implementations and waits for the answer. It submits stable
394
+ file groups to the reviewer, then fixes and resubmits rejected work.
395
+ - **Reviewer** stays read-only, reviews writer checkpoints and returns a rating
396
+ with evidence and actionable feedback. On suspected duplication it asks the
397
+ same DRY agent before returning its review.
398
+ - **DRY** stays read-only and serves both peers, returning paths, symbols,
399
+ behavioral differences and reuse options, or explicitly reporting that no
400
+ suitable implementation was found.
401
+
402
+ Submitted files stay frozen while awaiting review; the writer can work on
403
+ unrelated files meanwhile. Ratings apply to saved file contents and staged
404
+ versions. RL rejects changed or superseded checkpoints and requires current
405
+ accepted reviews for the writer's changes before completion. The defaults are
406
+ **90/100** and at most **five review rounds** per file group. Required fixes
407
+ and incomplete coverage block acceptance regardless of rating. Pending check
408
+ requests or routing leads must be resolved before a checkpoint can be accepted.
409
+
410
+ ```sh
411
+ rl workflow context --json # discover active definitions and their source
412
+ rl agent list
413
+ rl agent show writer
414
+ rl policy show review
415
+ rl workflow init # write editable copies and refresh workspace hooks
416
+ rl agent set writer --instructions writer.md
417
+ rl workflow set writer-reviewer-dry --file workflow.json --default
418
+ rl workflow status # latest saved run and checkpoint ratings
419
+ rl workflow metrics
420
+ ```
421
+
422
+ Export a definition before editing it:
423
+ `rl workflow show writer-reviewer-dry --json > workflow.json`.
424
+ `agent set --instructions` preserves the profile's other settings. Complete
425
+ profiles can be saved with `rl agent set writer --file profile.json`.
426
+ Use `rl agent add` and `rl workflow add` to create additional definitions.
427
+
428
+ Configuration stays in this worktree. The three concerns remain separate:
429
+
430
+ | File | Owns |
431
+ | --- | --- |
432
+ | `.rl/agents.json` | Roles: description, instructions, optional model/reasoning and access preferences; provider defaults to inherit |
433
+ | `.rl/agent-workflows.json` | Default workflow, triggers, dependencies, concurrency, retries, deadlines, collaboration routes and review rounds |
434
+ | `.rl/policies.json` | Review criteria, rating scale/threshold, severity deduction weights and acceptance requirements |
435
+
436
+ Each file has `"version": 1` and a named `agents`, `workflows` or `policies` map.
437
+ The workflow file also accepts `"default": "writer-reviewer-dry"`; use
438
+ `workflow add/set --default` to select a different default. Existing explicit
439
+ configurations are preserved, including workspaces with partial legacy settings.
440
+ A missing file uses built-in definitions, which
441
+ are active for automatic triggers too. Run `workflow init` only when you want
442
+ editable copies and none of the three files exists yet.
443
+
444
+ The default workflow's `collaboration` section is editable:
445
+
446
+ ```json
447
+ {
448
+ "writer": "writer",
449
+ "reviewer": "reviewer",
450
+ "dry": "dry",
451
+ "maxRounds": 5,
452
+ "rules": [
453
+ { "from": "writer", "event": "new_function", "to": "dry", "required": true },
454
+ { "from": "reviewer", "event": "suspected_duplicate", "to": "dry", "required": true }
455
+ ]
456
+ }
457
+ ```
458
+
459
+ These names refer to step IDs. All three collaboration steps must be ready at
460
+ startup with concurrency at least three; reviewer and DRY must be read-only.
461
+ Change routes, requirements, review rounds, triggers and profiles as needed.
462
+ Required gates support writer `new_function` and reviewer `suspected_duplicate`;
463
+ additional event routes can be added with `required: false` for optional messaging.
464
+ Other workflows can use sequential/parallel dependencies and parent-run command
465
+ steps without collaboration. A writing stage runs exclusively in those workflows;
466
+ explicit dependency results are shared and independent reviews remain isolated.
467
+
468
+ The separate policy has a `rating` object with `min`, `max`, `minimum` and
469
+ `instructions`. Agents use that rubric to rate checkpoints. RL also calculates
470
+ a separate score from findings: the default deducts 50/20/10/2 for
471
+ critical/high/medium/low findings, deduplicates exact file/line/root-cause matches,
472
+ and blocks readiness on required fixes or coverage gaps. `rl workflow score`
473
+ rescores saved evidence without agent calls. Native model/reasoning settings are
474
+ preferences applied by the parent where supported; unsupported settings must be
475
+ reported. Provider preferences never authorize another provider process.
476
+
477
+ Session-start hooks identify the active configuration and teach the parent the
478
+ protocol. Prompt hooks refresh it after configuration changes and compaction.
479
+ The default queues the team at the parent's `task_planned` coding milestone or
480
+ before its first edit. Before-edit/tool rules deny the pending tool until their
481
+ request completes, is explicitly dismissed or its run is cancelled. Coordination
482
+ tools are excluded from this gate. Child hooks do not recursively queue teams.
483
+ Normal session resume and task checkpoints remain independent.
484
+
485
+ Automatic events are `session_start`, `prompt`, `before_edit`, `after_edit`,
486
+ `before_tool`, `after_tool` and `before_finish`. Edit events recognize
487
+ Edit/Write/MultiEdit/apply_patch; other tools, including shell commands, use the
488
+ tool events. `tools` matches exact hook tool names; `paths` matches workspace
489
+ relative paths with `*` and `**`. Path filtering reads structured edit paths
490
+ and patch headers, without guessing about shell commands. `changes: true`
491
+ requires changes in the local comparison scope. Semantic events such as
492
+ `task_planned` are reported by the parent, since RL cannot observe private
493
+ reasoning. All conditions on a rule must match; multiple rules are alternatives.
494
+
495
+ Matching requests belong to that parent conversation only. Identical
496
+ scope/configuration events are deduplicated; newer changes coalesce into an
497
+ unclaimed request. Before-finish hooks can continue the turn once, guarding
498
+ against repeated Stop-hook loops. If native delegation is unavailable or
499
+ disallowed, the session must dismiss the request with its concrete reason and
500
+ report that limitation. Current permissions and workspace boundaries apply to
501
+ every child. Host permissions are enforced by the host.
502
+
503
+ The MCP server (`rl agent mcp`) exposes:
504
+
505
+ | Tool | Purpose |
506
+ | --- | --- |
507
+ | `rl_workflow_context` | Discover roles, workflows, triggers, policies and configuration source |
508
+ | `rl_workflow_pending` | Read this parent's queued requests |
509
+ | `rl_workflow_event` | Report a milestone and match trigger rules |
510
+ | `rl_workflow_start` | Prepare a session-owned run, optionally from a request |
511
+ | `rl_workflow_claim` | Claim a ready step and receive its prompt, scope, result schema and native settings |
512
+ | `rl_workflow_report` | Return final evidence, actual check output or failure with the claim token |
513
+ | `rl_workflow_dismiss` | Decline a queued request with a recorded reason |
514
+ | `rl_workflow_bind` | Bind a claimed role to its unique native child ID |
515
+ | `rl_workflow_inbox` | Read that role's consultations, submissions, ratings and peer handles |
516
+ | `rl_workflow_consult` | Ask an existing peer through a configured route |
517
+ | `rl_workflow_answer` | Answer a consultation addressed to that role |
518
+ | `rl_workflow_submit` | Submit a writer checkpoint and declare new functions as path#function subjects |
519
+ | `rl_workflow_review` | Return a rating, rationale, evidence and declared duplicate suspicions |
520
+
521
+ The parent claims, spawns and binds all three peers, then announces readiness.
522
+ Handoff tools return a `notify` destination with the peer's native handle. The
523
+ caller delivers it through native messaging or asks the parent to relay it.
524
+ RL persists the handoff; it cannot wake native children on its own. Peers use
525
+ native wait/messaging tools while idle. Finish the writer first, then reviewer,
526
+ then DRY, reporting final evidence through `rl_workflow_report`.
527
+
528
+ RL verifies answered consultations for declared new functions and duplicate
529
+ suspicions. Identifying those semantic events and declaring them honestly is
530
+ the agents' responsibility; RL cannot independently prove that every new
531
+ function was declared.
532
+
533
+ Supply `agent` and the parent's full `sessionId`; Codex may infer its ID from
534
+ the environment, while Claude supplies its UUID explicitly. Observed Codex
535
+ `thr_` IDs also coordinate workflows, but never enter UUID-based resumable
536
+ history. These are local coordination identities, not an authentication boundary
537
+ against a process that already has access to the state files.
538
+
539
+ CLI equivalents are available without an MCP connection:
540
+
541
+ ```sh
542
+ rl workflow pending --agent claude --session <UUID>
543
+ rl workflow event --file event.json --agent claude --session <UUID>
544
+ rl workflow run --request <request-UUID> --agent claude --session <UUID>
545
+ rl workflow claim <run> --step writer --agent claude --session <UUID>
546
+ rl workflow bind <run> --file binding.json --agent claude --session <UUID>
547
+ rl workflow inbox <run> --step writer --claim <token> --agent claude --session <UUID>
548
+ rl workflow report <run> --file report.json --agent claude --session <UUID>
549
+ ```
550
+
551
+ An event file contains `{ "event": "task_planned" }`. Binding files contain
552
+ `step`, `claim` and `childId`. CLI equivalents for `consult`, `answer`,
553
+ `submit` and `review` take `--file` with the same tool fields. Each role's
554
+ prompt supplies its claim token and parent conversation identity. Final reports
555
+ contain `step`, `claim` and `result` (the supplied schema), or an actual
556
+ `check` result or `error`. Reports may include native `childId` and token/cost
557
+ usage. `workflow run` prepares work without spawning agents; `--dry-run`
558
+ previews the scope without creating a run.
559
+
560
+ Review scope includes committed branch changes from the merge-base, staged,
561
+ unstaged and non-ignored untracked changes, capped at 4 MiB. Bases use local refs
562
+ without fetching; event detection falls back to HEAD if the saved base is
563
+ unresolvable. Generic workflows validate whole-scope fingerprints; collaborative
564
+ reviews validate each saved file group while implementation continues. Initial
565
+ unrelated dirty files need no submission unless changed during the run. RL
566
+ refreshes the whole scope when the writer closes and verifies it for remaining
567
+ final reports. Earlier checks/reviews in generic workflows remain historical
568
+ after writing; place final validation after the writer. Failed checks block
569
+ dependents. Reported failures can be retried within the configured budget.
570
+ Generic routing leads receive one focused follow-up; further leads remain
571
+ limitations. Collaborative peers handle consultations without replacement stages.
572
+
573
+ `workflow pause` stops new claims and submissions but lets claimed children
574
+ report and finish pending answers/reviews. The parent owns child cancellation.
575
+ `workflow resume` lets collaborative peers continue with the same claims and
576
+ native handles. Generic workflows require running children to report first.
577
+ Cancellation rejects further results and requires a new run. Neither command
578
+ sends process signals. Run records retain the parent identity, native IDs,
579
+ claims, evidence, checkpoints and assessments under this instance's
580
+ `workflow-runs/` directory. RL measures claim-to-report elapsed time; token/cost
581
+ usage is parent-reported and missing totals remain unknown.
582
+
583
+ After upgrading existing workspaces, run `rl doctor --repair` to add tool hooks,
584
+ and restart/review hooks as required by your host. Automated tests exercise
585
+ hook payloads and MCP/CLI coordination; they do not certify live model compliance
586
+ or native delegation availability in every client.
587
+
588
+ ## Let agents use notes through MCP
589
+
590
+ `rl agent mcp` serves workspace-scoped tools over stdio: `rl_status`, `rl_context`,
591
+ `rl_progress`, `rl_context_append`, `rl_progress_append`, `rl_session_save`,
592
+ `rl_task_pause`, and the thirteen `rl_workflow_*` coordination tools described above.
593
+ `rl_task_pause` accepts the handoff JSON described above and atomically saves
594
+ the session and task checkpoint. `rl_status` includes task state and handoff history.
595
+ `rl_status` automatically discovers Codex sessions for this workspace.
596
+ `rl_session_save` accepts `{"agent":"codex","sessionId":"<UUID>"}`;
597
+ `agent` defaults to Codex. If `sessionId` is omitted, it uses the MCP server's
598
+ Codex environment when available. Clients should pass their current UUID when
599
+ the server does not inherit it. Claude requires an explicit UUID.
600
+ Append tools take `{"text":"..."}`. They share the same locked document updates
601
+ as the CLI and expose no arbitrary command, deletion, or filesystem tool.
602
+
603
+ In the adopted workspace, add an entry to its trusted `.codex/config.toml`:
604
+
605
+ ```toml
606
+ [mcp_servers.rl]
607
+ command = "rl"
608
+ args = ["agent", "mcp"]
609
+ ```
610
+
611
+ For Claude, merge this entry into the workspace's `.mcp.json`:
612
+
613
+ ```json
614
+ {
615
+ "mcpServers": {
616
+ "rl": { "type": "stdio", "command": "rl", "args": ["agent", "mcp"] }
617
+ }
618
+ }
619
+ ```
620
+
621
+ The client must launch the server in this workspace with `rl` on PATH.
622
+ With custom state settings, pass the same `RL_STATE_DIR` in the server environment.
623
+ Review project trust/server approval normally. Configuration follows the official
624
+ [Codex MCP guide](https://learn.chatgpt.com/docs/extend/mcp?surface=cli) and
625
+ [Claude MCP guide](https://code.claude.com/docs/en/mcp).
626
+ RL does not modify global client settings or relax agent sandbox permissions.
627
+
628
+ ## Notes and reports
629
+
630
+ ```sh
631
+ rl notes show context
632
+ rl notes show progress
633
+ rl notes set context feature-notes.md
634
+ rl notes append progress implementation-notes.md
635
+ printf 'Done: parser. Next: integration tests.\n' | rl notes append progress -
636
+ rl notes summary --stdout
637
+ rl notes summary --output feature-report.md
638
+ ```
639
+
640
+ Context records scope, domain rules, acceptance criteria, and design decisions.
641
+ Progress records completed work, remaining tasks, implementation details, and
642
+ validation. Append preserves concurrent updates; set replaces a document.
643
+ Handoff and summary exports refuse to overwrite existing files; summary also
644
+ supports explicit `--force`. Long injected notes include an excerpt and their path.
645
+
646
+ State lives under `$RL_STATE_DIR/<repository-hash>/<instance-UUID>/`, outside
647
+ the checkout, with `instance.json`, `context.md`, and `progress.md`.
648
+ Deleting a workspace archives its record. Recreating it starts a new instance
649
+ with separate sessions. Back up state alongside your work.
650
+
651
+ ## Multiple repositories and settings
652
+
653
+ ```sh
654
+ rl repo add /path/to/frontend --base origin/test
655
+ rl repo add /path/to/backend --base origin/test
656
+ # Or run `rl repo add .` inside each repository.
657
+ rl checkout frontend
658
+ rl # pick a frontend workspace
659
+ rl checkout backend
660
+ rl checkout # pick a repository
661
+ rl repo list
662
+ rl repo use backend # default when outside registered repositories
663
+ rl --repo backend list # inspect another repo without switching
664
+ ```
665
+
666
+ Registration uses the repository name from `origin`, or the main checkout folder
667
+ name without an origin. An alias is optional: `rl repo add . --alias frontend`.
668
+ The previous `rl repo add frontend /path/to/repository` syntax still works.
669
+ Name collisions require a distinct alias.
670
+
671
+ `rl checkout [repository]` enters that repository's main checkout using shell
672
+ integration (or prints its path when run directly). With no name, it offers a
673
+ repository picker; a single registered repository is selected automatically.
674
+ It preserves Git branches and changes, and leaves the configured default alone.
675
+ Bare `rl` then offers workspaces for the repository you entered. `rl status` shows
676
+ the selected repository, how it was selected, its base, workspaces and saved session
677
+ counts. Use `rl status --workspace` for the detailed current-workspace view;
678
+ `--json` follows the selected view.
679
+
680
+ Repositories are registered explicitly; RL does not scan siblings. Command selection
681
+ uses `--repo`, then `RL_REPO`, the current registered worktree, and the registry
682
+ default. An explicit `RL_REPO` override still applies after changing directories.
683
+ Removing a repository registration retains all worktrees and state.
684
+ Without registered repositories or an explicit `RL_REPO_ROOT`, RL detects the
685
+ main checkout of the current Git repository, including from linked worktrees
686
+ and subdirectories.
687
+
688
+ | Environment setting | Default |
689
+ | --- | --- |
690
+ | `RL_WORKTREE_DIR` | `$HOME/.rl/worktrees` |
691
+ | `RL_STATE_DIR` | `$HOME/.rl/instances` |
692
+ | `RL_REPO` | Optional repository alias |
693
+ | `RL_PR_OFFLINE` | Set to `1` to disable PR queries |
694
+
695
+ Environment variables can also come from trusted zsh configuration selected by
696
+ `RL_CONFIG`, defaulting to `~/.config/rl/config.zsh`. See
697
+ [config.example.zsh](config.example.zsh). Registration supplies repository/base
698
+ settings; `rl help` and individual `--help` show command options.
699
+
700
+ ## Compatibility aliases
701
+
702
+ Existing commands keep their behavior. They are omitted from the main help to
703
+ keep one primary spelling for each operation:
704
+
705
+ | Previous command | Primary command |
706
+ | --- | --- |
707
+ | `rl merge` | `rl git merge` |
708
+ | `rl context/progress show/set/append/path` | `rl notes show/set/append/path context/progress` |
709
+ | `rl summary` | `rl notes summary` |
710
+ | `rl session list/save/add` | `rl agent sessions/save` |
711
+ | `rl handoff`, `rl mcp` | `rl agent handoff`, `rl agent mcp` |
712
+ | `rl clean` | `rl storage clean` |
713
+ | `rl config init/show`, `rl adopt`, `rl init` | `rl setup init/show`, `rl setup adopt`, `rl setup shell` |
714
+ | `rl status --list`, `rl status --all` | `rl list`, `rl list --all` |
715
+
716
+ ## Development
717
+
718
+ ```sh
719
+ npm ci
720
+ npm run build
721
+ npm test
722
+ npm run format:check
723
+ npm pack --dry-run
724
+ ```
725
+
726
+ To install an unpublished checkout after building it, run `npm install --global .`
727
+ from that checkout.
728
+
729
+ Strict TypeScript modules share Store, Git execution, workspace resolution, and
730
+ agent adapters. Tests use isolated temporary repositories, representative hook
731
+ payloads, stub agents/GitHub, and a real offline tarball installation. They do
732
+ not modify your global install or launch paid sessions. `npm test` includes
733
+ package and shell smoke checks. No npm install script runs application setup.
734
+
735
+ Issues and pull requests are welcome. Include reproduction steps and validation.
736
+ Licensed under [MIT](LICENSE).