paseo-room 0.1.0-alpha.2 → 0.1.0-alpha.4

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
@@ -6,8 +6,9 @@ using the Codex and/or Claude Code you already have installed.
6
6
  It does three things:
7
7
 
8
8
  1. Reads your existing Codex / Claude Code configuration.
9
- 2. Writes one isolated role home per seat under `~/.paseo-room`, sharing your login, skills and plugins by symlink.
10
- 3. Registers those role homes with your running Paseo daemon as providers — room tools on for Supervisor and Lead, off for Peer.
9
+ 2. Writes one isolated role home per seat under `~/.paseo-room`, sharing file-backed login
10
+ where supported, plus skills and plugins, by symlink.
11
+ 3. Registers those role homes with your running Paseo daemon as providers — room tools on for Supervisor and Lead, off for Peer — and adds one agent profile per seat so opening one is a single pick.
11
12
 
12
13
  Everything it creates lives in `$HOME`, under one directory it owns outright. It reads
13
14
  `~/.codex` and `~/.claude`; it never writes to them.
@@ -54,7 +55,11 @@ Exit codes: `0` success, `1` a check failed, `2` bad usage.
54
55
  version. `paseo-room` checks this before touching anything, and never installs or upgrades
55
56
  Paseo for you.
56
57
  - An initialised Codex home (`~/.codex/config.toml`) and/or Claude Code home (`~/.claude`).
57
- Log in to those tools yourself first; the room shares that login, it does not create one.
58
+ Log in to those tools yourself first; the room never creates credentials. Codex auth and
59
+ Claude's file-backed `.credentials.json` are shared. On macOS, Claude's default Keychain
60
+ login is scoped to `CLAUDE_CONFIG_DIR`, so use inherited environment auth or log in once
61
+ in each Claude seat instead. See Anthropic's
62
+ [credential-management reference](https://code.claude.com/docs/en/authentication#credential-management).
58
63
 
59
64
  ## What gets created
60
65
 
@@ -68,14 +73,17 @@ Exit codes: `0` success, `1` a check failed, `2` bad usage.
68
73
  model-catalog.json # your catalog with native multi-agent metadata removed
69
74
  auth.json, AGENTS.md, skills, plugins, hooks.json → symlinks into ~/.codex
70
75
  roles/claude/<role>/
71
- CLAUDE.md # role instructions, as user memory
76
+ CLAUDE.md # your global memory + role instructions
72
77
  settings.json # your settings.json + PASEO_ROOM_ROLE
73
78
  .claude.json # seeded once from yours, then owned by Claude
74
- .credentials.json, skills, plugins, commands, hooks → symlinks into ~/.claude
79
+ .credentials.json, skills, plugins, commands, hooks, rules, output-styles,
80
+ keybindings.json, themes → symlinks into ~/.claude
75
81
  ```
76
82
 
77
83
  Each seat keeps its own sessions, history and projects inside its role home, so three seats
78
- never share conversation state — but they do share one login and one set of skills.
84
+ never share conversation state. Skills and file-backed credentials are shared by reference.
85
+ The filename is `.credentials.json` (plural); on macOS Claude normally uses Keychain instead,
86
+ and keys that entry to the configured directory rather than sharing it across role homes.
79
87
 
80
88
  ## What the room changes
81
89
 
@@ -105,12 +113,44 @@ agent's own configuration:
105
113
  | Pin | Applies to | Why |
106
114
  |---|---|---|
107
115
  | `params: {sandbox_mode, approval_policy}` | Codex | Without it Paseo sends its own mode preset (default `auto-review`) to the Codex app-server, and that outranks the generated `config.toml`. |
108
- | `disallowedTools: ["Task"]` | Claude | Claude's own subagents would be a second control plane. This is the counterpart of Codex's `[agents].enabled = false`. |
116
+ | `disallowedTools` for `Task`, `Agent`, `Workflow`, coordination, task-list, cron and team tools | Claude | Blocks legacy/current subagents, dynamic workflows, cross-session coordination and agent teams. |
117
+ | `disableAgentView: true` + `CLAUDE_CODE_DISABLE_AGENT_VIEW=1` | Claude | Disables Claude's separate background-agent control plane across settings scopes and at launch. |
118
+ | `disableWorkflows: true` + `CLAUDE_CODE_DISABLE_WORKFLOWS=1` | Claude | Disables dynamic workflows through every entry point, beyond denying the `Workflow` tool. |
119
+ | `crossSessionInbound: "refuse"` | Claude | Prevents another Claude session from injecting a turn into a room seat. |
109
120
  | `paseoTools: {enabled}` | both | Room tools for Supervisor and Lead, never for Peer. |
110
121
 
111
- The Claude permission mode is deliberately **not** set here. Paseo passes `--permission-mode`
112
- per agent (`plan`, `default`, `acceptEdits`, `auto`, `bypassPermissions`; default `auto`), and
113
- a command-line flag beats anything in `settings.json`. Choose the mode in Paseo.
122
+ It also saves one **agent profile** per seat, which is what the Paseo picker lists under
123
+ Profiles. A profile is a preset, not a constraint: it decides where a seat *starts*.
124
+
125
+ | Profile field | Value | Owned by |
126
+ |---|---|---|
127
+ | `provider` | that seat's provider | the room — repaired on every `setup --apply` |
128
+ | `name` | e.g. `Codex Lead` | the room |
129
+ | `icon` | `eye` / `compass` / `code` for Supervisor / Lead / Peer | the room |
130
+ | `color` | `violet` / `blue` / `emerald` for Supervisor / Lead / Peer | the room |
131
+ | `modeId` | `full-access` for Codex, `bypassPermissions` for Claude | the room |
132
+ | `notes` | who may open this seat, shown to orchestrating agents by Paseo's `list_profiles` | the room |
133
+ | `thinkingOptionId` | `low` for Supervisor, `high` for Lead and Peer | seeded once, then yours |
134
+ | `model` | never written | yours |
135
+
136
+ Supervisor starts low because it routes rather than reasons. Neither seat starts on the top
137
+ option — Codex's `ultra` and Claude's `ultracode` advertise automatic task delegation, which
138
+ is a second control plane. `setup` restores room-owned identity, appearance and mode fields,
139
+ but leaves your model and reasoning choice alone; profiles you created yourself are never
140
+ touched.
141
+
142
+ Claude starts in Paseo's `bypassPermissions` mode, while Codex starts in its equivalent
143
+ `full-access` mode. Claude deny rules still apply in bypass mode, so native orchestration
144
+ stays unavailable. The room does not write `permissions.defaultMode` to `settings.json`:
145
+ Paseo passes the profile's mode as a command-line session setting, which outranks that file.
146
+ The two Claude disable environment keys are pinned in both the provider and generated
147
+ `settings.json`, because Claude applies settings-file environment values after launch values.
148
+ The generated top-level `disableAgentView` and `disableWorkflows` settings are also forced to
149
+ `true`; their restrictive value cannot be weakened by another ordinary settings scope.
150
+
151
+ No default model is pinned. The profile schema supports `model`, but leaving it absent lets
152
+ each provider use its current default and avoids silently choosing a cost/capability tier for
153
+ the operator.
114
154
 
115
155
  ## Keeping the room current
116
156
 
@@ -131,17 +171,30 @@ unrelated Paseo providers alone.
131
171
  The exact wording every seat reads lives in [`src/room/clauses.ts`](src/room/clauses.ts).
132
172
  In short:
133
173
 
134
- - **Supervisor** routes Human directives to Lead and observes. It does not edit project work,
135
- run validation, or decide technical acceptance. Room tools: on.
136
- - **Lead** owns framing, decomposition, routing, integration and technical acceptance. One
137
- moving write scope has exactly one owner, and at most one Peer is writable at a time.
138
- Room tools: on.
174
+ - **Supervisor** routes Human directives to Lead and observes. Before opening a seat it checks
175
+ for and reuses the project's existing Lead, including an idle or resumable Lead. It does
176
+ not edit project work, run validation, direct Peer, or decide technical acceptance. Room
177
+ tools: on.
178
+ - **Lead** is the durable owner of one project across turns. It owns framing, decomposition,
179
+ routing, integration and technical acceptance. One moving write scope has exactly one
180
+ owner, and at most one Peer is writable at a time. Room tools: on.
139
181
  - **Peer** owns one bounded outcome, may challenge a failed premise with
140
182
  `REOPEN_REQUEST` / `DEPENDENCY_REQUEST` / `BLOCKED`, hands back a reproducible candidate,
141
183
  and never accepts its own difficult change. Room tools: off.
142
184
 
143
185
  Human keeps product goals, priority, material cost, external effects and irreversible risk.
144
186
 
187
+ One rule has no runtime enforcement behind it and so is procedural and regression-tested in
188
+ the contract instead: **one Lead owns one project; Supervisor discovers and reuses it, while
189
+ Lead alone opens Peer seats.** A completed turn, idle state, pending permission, or resumable
190
+ closed session is not an absent Lead. Fresh independent review means that existing Lead opens
191
+ a fresh read-only Peer; it never means Supervisor opens another Lead.
192
+
193
+ Paseo takes the seat to open as a plain provider id, so if two Leads nevertheless appear,
194
+ Supervisor stops parallel routing, preserves both histories, keeps the previously established
195
+ healthy owner, and closes the duplicate only after a stable handoff. Ambiguous ownership,
196
+ health, or concurrent writes go back to Human rather than being guessed or merged.
197
+
145
198
  Every seat also carries a **default workspace protocol** — topology by difficulty,
146
199
  verification, review, repository conventions — so a project has that layer without doing
147
200
  anything. Each seat gets the sections that bear on its own work; topology goes to Lead and
@@ -150,6 +203,40 @@ Supervisor, not to Peer. A repository that needs different rules writes
150
203
  wherever it is silent. `~/.paseo-room/room/WORKSPACE_PROTOCOL.md` is the whole default as
151
204
  one file, so you can read what is in force and start from it.
152
205
 
206
+ ## Working the room
207
+
208
+ The whole point is that you do not orchestrate. Say the outcome and the boundaries; let Lead
209
+ decide the route.
210
+
211
+ 1. **Talk to one seat.** Six providers is not six windows. One project: open **Lead**. Several
212
+ projects at once, or you want an audit trail of directives: open **Supervisor** only, and
213
+ let it discover and reuse one Lead per project. Opening both and then talking to Lead makes
214
+ Supervisor an expensive ornament with an incomplete record.
215
+ 2. **Say the outcome, not the plan.** You may direct the technical route, but every time you
216
+ do you take the acceptance risk back from Lead — and an orchestrator who has already solved
217
+ the problem leaves the worker able to be right about only one thing.
218
+ 3. **Interrupt at four boundaries only:** product goals and priority, material cost, external
219
+ effects, irreversible risk. Technical route and ownership are Lead's.
220
+ 4. **Read anything, direct one thing.** Reading a Peer's timeline is how you get evidence
221
+ without becoming a second channel; stopping a seat is yours by right. But answering a
222
+ Peer's `REOPEN_REQUEST` yourself means Lead never learns its premise was wrong and writes
223
+ the same premise into the next brief. If you do override a Peer, tell Lead — it waits on
224
+ events, so it will wait a long time.
225
+ 5. **Accept the product, not the diff.** Ask for the candidate and the gate result. "It's
226
+ done" is not evidence.
227
+ 6. **When the room gets confusing, throw it away.** `remove --apply`, then `setup --apply`.
228
+ Role homes are generated; do not debug them.
229
+
230
+ Using one Peer directly, with no Lead at all, is fine for small single-scope work — that is
231
+ not breaking the room, it is not using it. Just be clear that you are then the Lead: the brief
232
+ and the technical acceptance are yours.
233
+
234
+ With both Codex and Claude seated, the highest-value use of the second family is not splitting
235
+ work at random — it is **independent review**. A read-only Peer from a different model family
236
+ reading a candidate is more independent than a fresh session of the family that wrote it. Run
237
+ one project on one family and keep the other for the review seat. Ask the existing Lead for
238
+ that review; Supervisor must route the request to Lead rather than opening a fresh Lead.
239
+
153
240
  ## Documentation
154
241
 
155
242
  - [docs/orchestration-model.md](docs/orchestration-model.md) — the reference model this
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ var init_package = __esm({
15
15
  "package.json"() {
16
16
  package_default = {
17
17
  name: "paseo-room",
18
- version: "0.1.0-alpha.2",
18
+ version: "0.1.0-alpha.4",
19
19
  description: "One CLI that configures Codex/Claude role homes in $HOME and registers them with your local Paseo daemon.",
20
20
  keywords: [
21
21
  "paseo",
@@ -104,14 +104,17 @@ function pick(...candidates) {
104
104
  }
105
105
  function resolveLayout(options = {}, env = process.env) {
106
106
  const home = pick(env.HOME, homedir());
107
+ const claudeOverride = options.claudeHome?.trim() || env.CLAUDE_CONFIG_DIR?.trim() || void 0;
108
+ const claudeHome = resolve(pick(claudeOverride, join(home, ".claude")));
107
109
  return {
108
110
  home,
109
111
  roomHome: resolve(pick(options.roomHome, env.PASEO_ROOM_HOME, join(home, ".paseo-room"))),
110
112
  paseoHome: resolve(pick(env.PASEO_HOME, join(home, ".paseo"))),
111
113
  agentHome: {
112
114
  codex: resolve(pick(options.codexHome, env.CODEX_HOME, join(home, ".codex"))),
113
- claude: resolve(pick(options.claudeHome, env.CLAUDE_CONFIG_DIR, join(home, ".claude")))
115
+ claude: claudeHome
114
116
  },
117
+ claudeState: claudeOverride?.trim() ? join(claudeHome, ".claude.json") : join(home, ".claude.json"),
115
118
  bin: {
116
119
  codex: pick(options.codexBin, env.CODEX_BIN, "codex"),
117
120
  claude: pick(options.claudeBin, env.CLAUDE_BIN, "claude"),
@@ -293,6 +296,31 @@ var init_clauses = __esm({
293
296
  Supervisor has Paseo tools enabled solely within its authority. Use the smallest Paseo
294
297
  room/session lifecycle action needed for an explicit Human request or bounded room
295
298
  recovery; preserve current ownership and inform Lead of every change.
299
+
300
+ Before opening a Lead, Supervisor checks whether a healthy Lead already owns the project
301
+ by inspecting its current and recent agents. An initializing or running Lead, an idle
302
+ Lead after a completed turn, and a closed but unarchived, resumable Lead are the same
303
+ project owner: route the directive, question, evidence, or review request to that Lead,
304
+ resuming it when necessary. A pending creation, run, or permission request is unresolved
305
+ state, not an absent Lead; wait for a state-changing event. Resolve a permission only
306
+ within authority already granted by Human, and otherwise escalate it to Human.
307
+
308
+ Only when no Lead owns the project may Supervisor open exactly one Lead as its child and
309
+ route the Human directive to it. Workspace placement does not change parentage. Of the
310
+ seats available, Supervisor opens Lead seats only; opening Peer seats is Lead's, and
311
+ opening another Supervisor is Human's. Reuse the project Lead and never open another Lead
312
+ for freshness or convenience.
313
+
314
+ A fresh-session review is Lead's to arrange with a fresh read-only Peer against a stable
315
+ candidate. Route that request to the existing Lead; freshness applies to the review Peer
316
+ and is not a reason for Supervisor to open a fresh Lead or direct the Peer.
317
+
318
+ If duplicate Leads exist, stop new parallel routing and preserve both timelines and
319
+ artifacts. Keep the previously established healthy Lead as project owner, route the
320
+ duplicate's stable handoff and evidence to it, and close the duplicate only after moving
321
+ work has stopped and a stable handoff exists. If prior ownership, health, or concurrent
322
+ writes are ambiguous, escalate to Human instead of choosing, merging, accepting, or
323
+ directing a Peer.
296
324
  `),
297
325
  "RC-104": clause(`
298
326
  Supervisor sends technical questions and evidence to Lead. Escalate product, priority,
@@ -304,6 +332,10 @@ var init_clauses = __esm({
304
332
  technical acceptance within Human boundaries. Lead executes the Human outcome and
305
333
  constraints, escalating Human-owned choices to Human.
306
334
 
335
+ Lead owns one project across turns. A completed turn, idle state, or closed but unarchived,
336
+ resumable session does not end that ownership; it ends only when Human closes or reassigns
337
+ the project, or bounded recovery replaces an unhealthy Lead after a stable handoff.
338
+
307
339
  Lead has Paseo tools enabled to manage project agents and direct Peer; this capability
308
340
  does not expand project or external-action authority.
309
341
  `),
@@ -339,6 +371,19 @@ var init_clauses = __esm({
339
371
  When material uncertainty warrants independent review, Lead may dispatch a fresh
340
372
  read-only Peer with an exact stable candidate and a bounded question. Review is
341
373
  optional: do not introduce a dedicated reviewer role or a fixed reviewer count.
374
+
375
+ The fresh session is the review Peer's session, never a replacement or duplicate project
376
+ Lead. Lead remains the owner, receives the review evidence, inspects the exact candidate,
377
+ and makes the technical acceptance decision.
378
+ `),
379
+ "RC-207": clause(`
380
+ Lead opens Peer seats and no others. A seat list may offer Lead and Supervisor seats;
381
+ opening one creates a second orchestrator or inverts the Human-facing seat, so Lead
382
+ must not, whatever the tool permits.
383
+
384
+ Open each Peer on the same agent implementation as this seat unless the workspace
385
+ protocol routes that kind of work elsewhere. A Peer belongs to one brief: close it when
386
+ the brief closes rather than holding a standing pool.
342
387
  `),
343
388
  "RC-301": clause(`
344
389
  Peer owns exactly one Lead-delegated bounded outcome and proportionate evidence. Do
@@ -384,6 +429,11 @@ var init_workspace = __esm({
384
429
 
385
430
  When the route itself is uncertain, spend a read-only Peer on the question before
386
431
  spending a writable Peer on the answer.
432
+
433
+ When seats from more than one agent implementation are available, a second
434
+ implementation is worth most as an independent reader of a candidate the first one
435
+ wrote. Absent a repository rule assigning work by kind, keep a task on the
436
+ implementation of the seat that opened it.
387
437
  `),
388
438
  "WP-02 Verification": clause(`
389
439
  The repository's own gate is the evidence. Lead names the exact command in the brief;
@@ -441,7 +491,7 @@ var init_instructions = __esm({
441
491
  init_workspace();
442
492
  ROLE_IDS = {
443
493
  supervisor: ["RC-101", "RC-102", "RC-103", "RC-104"],
444
- lead: ["RC-201", "RC-202", "RC-203", "RC-204", "RC-205", "RC-206"],
494
+ lead: ["RC-201", "RC-202", "RC-203", "RC-204", "RC-205", "RC-206", "RC-207"],
445
495
  // Peer needs the challenge protocol as well as its own numbered obligations.
446
496
  peer: ["RC-204", "RC-301", "RC-302", "RC-303", "RC-304", "RC-305"]
447
497
  };
@@ -515,7 +565,10 @@ function readObject(source) {
515
565
  }
516
566
  function renderRoleSettings(source, role) {
517
567
  const settings = readObject(source);
518
- settings.env = { ...asObject(settings.env), PASEO_ROOM_ROLE: role };
568
+ settings.env = { ...asObject(settings.env), ...CONTROL_PLANE_ENV, PASEO_ROOM_ROLE: role };
569
+ settings.disableAgentView = true;
570
+ settings.disableWorkflows = true;
571
+ settings.crossSessionInbound = "refuse";
519
572
  return JSON.stringify(settings, null, 2) + "\n";
520
573
  }
521
574
  function renderRoleState(source) {
@@ -524,7 +577,13 @@ function renderRoleState(source) {
524
577
  for (const key of SEEDED_KEYS) if (key in root) state[key] = root[key];
525
578
  return JSON.stringify(state, null, 2) + "\n";
526
579
  }
527
- var SHARED, SEEDED_KEYS, claudeAgent;
580
+ function renderRoleMemory(source, role) {
581
+ const operator = source?.trim();
582
+ return operator ? `${operator}
583
+
584
+ ${renderInstructions(role)}` : renderInstructions(role);
585
+ }
586
+ var SHARED, CONTROL_PLANE_ENV, SEEDED_KEYS, claudeAgent;
528
587
  var init_claude = __esm({
529
588
  "src/agents/claude.ts"() {
530
589
  "use strict";
@@ -533,15 +592,50 @@ var init_claude = __esm({
533
592
  init_result();
534
593
  init_instructions();
535
594
  init_which();
536
- SHARED = [".credentials.json", "skills", "plugins", "commands", "hooks"];
537
- SEEDED_KEYS = ["hasCompletedOnboarding", "theme", "installMethod", "userID", "oauthAccount"];
595
+ SHARED = [
596
+ ".credentials.json",
597
+ "skills",
598
+ "plugins",
599
+ "commands",
600
+ "hooks",
601
+ "rules",
602
+ "output-styles",
603
+ "keybindings.json",
604
+ "themes"
605
+ ];
606
+ CONTROL_PLANE_ENV = {
607
+ CLAUDE_CODE_DISABLE_AGENT_VIEW: "1",
608
+ CLAUDE_CODE_DISABLE_WORKFLOWS: "1"
609
+ };
610
+ SEEDED_KEYS = ["hasCompletedOnboarding", "theme", "installMethod", "userID", "mcpServers"];
538
611
  claudeAgent = {
539
612
  id: "claude",
540
613
  label: "Claude Code",
541
614
  homeEnv: "CLAUDE_CONFIG_DIR",
542
- // Claude's own subagents would be a second control plane; Paseo owns agent
543
- // lifecycle. This is the Claude counterpart of Codex's [agents] enabled = false.
544
- pins: { disallowedTools: ["Task"] },
615
+ // Agent View and dynamic workflows have entry points beyond model tool calls.
616
+ providerEnv: CONTROL_PLANE_ENV,
617
+ defaultModeId: "bypassPermissions",
618
+ // Keep the legacy Task name and block current native orchestration,
619
+ // shared task/cron coordination, and cross-session paths. Paseo alone owns
620
+ // agent lifecycle and coordination.
621
+ pins: {
622
+ disallowedTools: [
623
+ "Task",
624
+ "Agent",
625
+ "Workflow",
626
+ "ListAgents",
627
+ "SendMessage",
628
+ "TeamCreate",
629
+ "TeamDelete",
630
+ "TaskCreate",
631
+ "TaskGet",
632
+ "TaskList",
633
+ "TaskUpdate",
634
+ "CronCreate",
635
+ "CronDelete",
636
+ "CronList"
637
+ ]
638
+ },
545
639
  async build(layout, roles) {
546
640
  const home = layout.agentHome.claude;
547
641
  const binary = await which(layout.bin.claude, layout.searchPath);
@@ -553,13 +647,14 @@ var init_claude = __esm({
553
647
  }
554
648
  const checks = [pass("claude.home", `Claude Code found at ${binary} using ${home}.`)];
555
649
  const settingsSource = await readIfPresent(join4(home, "settings.json"));
556
- const stateSource = await readIfPresent(join4(layout.home, ".claude.json"));
650
+ const stateSource = await readIfPresent(layout.claudeState);
651
+ const memorySource = await readIfPresent(join4(home, "CLAUDE.md"));
557
652
  const shared = await existingPaths(home, SHARED);
558
653
  const entries = [];
559
654
  for (const role of roles) {
560
655
  const target = roleHome(layout, "claude", role);
561
656
  entries.push({ kind: "dir", path: target });
562
- entries.push({ kind: "file", path: join4(target, "CLAUDE.md"), content: renderInstructions(role) });
657
+ entries.push({ kind: "file", path: join4(target, "CLAUDE.md"), content: renderRoleMemory(memorySource, role) });
563
658
  entries.push({ kind: "file", path: join4(target, "settings.json"), content: renderRoleSettings(settingsSource, role) });
564
659
  entries.push({ kind: "file", path: join4(target, ".claude.json"), content: renderRoleState(stateSource), once: true });
565
660
  for (const path of shared) entries.push({ kind: "link", path: join4(target, basename(path)), target: path });
@@ -616,6 +711,7 @@ var init_codex = __esm({
616
711
  id: "codex",
617
712
  label: "Codex",
618
713
  homeEnv: "CODEX_HOME",
714
+ defaultModeId: "full-access",
619
715
  // Without these, Paseo's own mode preset (default auto-review) is sent to the
620
716
  // app-server and outranks the sandbox/approval keys in the generated config.
621
717
  pins: { params: { sandbox_mode: "danger-full-access", approval_policy: "never" } },
@@ -754,6 +850,13 @@ async function withSession(daemon, run2, options = {}) {
754
850
  async removeProviders(ids) {
755
851
  await client.config.patch({ removeProviders: [...ids] });
756
852
  },
853
+ async readProfiles() {
854
+ const response = configSchema.parse(await client.config.get());
855
+ return response.config.agentProfiles ?? [];
856
+ },
857
+ async writeProfiles(profiles) {
858
+ await client.config.patch({ agentProfiles: [...profiles] });
859
+ },
757
860
  async refresh(ids) {
758
861
  await client.providers.refresh({ providers: [...ids] });
759
862
  }
@@ -771,6 +874,31 @@ function providerMatches(desired, live) {
771
874
  return entry.extends === desired.extends && same(entry.command, desired.command) && env !== null && typeof env === "object" && Object.entries(desired.env).every(([key, value]) => env[key] === value) && tools !== null && typeof tools === "object" && tools.enabled === desired.paseoTools.enabled && // Pins are the room's guarantee: drifting them silently re-enables what they block.
772
875
  same(entry.params, desired.params) && same(entry.disallowedTools, desired.disallowedTools);
773
876
  }
877
+ function profileMatches(desired, live) {
878
+ if (live === null || typeof live !== "object") return false;
879
+ const entry = live;
880
+ return entry.name === desired.name && entry.icon === desired.icon && entry.color === desired.color && entry.provider === desired.provider && entry.modeId === desired.modeId && entry.notes === desired.notes;
881
+ }
882
+ function mergeProfiles(live, desired, drop) {
883
+ const dropped = new Set(drop);
884
+ const wanted = new Map(desired.map((profile) => [profile.id, profile]));
885
+ const seen = /* @__PURE__ */ new Set();
886
+ const kept = live.filter((entry) => !dropped.has(String(entry.id))).map((entry) => {
887
+ const profile = wanted.get(String(entry.id));
888
+ if (!profile) return entry;
889
+ seen.add(profile.id);
890
+ return {
891
+ ...entry,
892
+ name: profile.name,
893
+ icon: profile.icon,
894
+ color: profile.color,
895
+ provider: profile.provider,
896
+ modeId: profile.modeId,
897
+ notes: profile.notes
898
+ };
899
+ });
900
+ return [...kept, ...desired.filter((profile) => !seen.has(profile.id)).map((profile) => ({ ...profile }))];
901
+ }
774
902
  var MINIMUM_VERSION, statusSchema, configSchema;
775
903
  var init_paseo = __esm({
776
904
  "src/paseo.ts"() {
@@ -784,7 +912,13 @@ var init_paseo = __esm({
784
912
  cliVersion: z.string(),
785
913
  daemonVersion: z.string().nullable()
786
914
  });
787
- configSchema = z.object({ config: z.object({ providers: z.record(z.string(), z.unknown()).optional() }) });
915
+ configSchema = z.object({
916
+ config: z.object({
917
+ providers: z.record(z.string(), z.unknown()).optional(),
918
+ // Read loosely: entries carry operator fields the room neither knows nor touches.
919
+ agentProfiles: z.array(z.record(z.string(), z.unknown())).optional()
920
+ })
921
+ });
788
922
  }
789
923
  });
790
924
 
@@ -792,17 +926,28 @@ var init_paseo = __esm({
792
926
  function providerId(agent, role) {
793
927
  return `${agent}-${role}`;
794
928
  }
929
+ function profileId(agent, role) {
930
+ return `room-${agent}-${role}`;
931
+ }
795
932
  function providerLabel(agent, role) {
796
933
  const title = (value) => value.charAt(0).toUpperCase() + value.slice(1);
797
934
  return `${title(agent)} ${title(role)}`;
798
935
  }
799
- var ROLES, AGENT_IDS, ROLE_PASEO_TOOLS;
936
+ var ROLES, AGENT_IDS, ROLE_PASEO_TOOLS, ROLE_THINKING, ROLE_ICON, ROLE_COLOR, ROLE_NOTES;
800
937
  var init_roles = __esm({
801
938
  "src/roles.ts"() {
802
939
  "use strict";
803
940
  ROLES = ["supervisor", "lead", "peer"];
804
941
  AGENT_IDS = ["codex", "claude"];
805
942
  ROLE_PASEO_TOOLS = { supervisor: true, lead: true, peer: false };
943
+ ROLE_THINKING = { supervisor: "low", lead: "high", peer: "high" };
944
+ ROLE_ICON = { supervisor: "eye", lead: "compass", peer: "code" };
945
+ ROLE_COLOR = { supervisor: "violet", lead: "blue", peer: "emerald" };
946
+ ROLE_NOTES = {
947
+ supervisor: "Human-facing routing seat. Opened by Human, never by another agent.",
948
+ lead: "Sole project technical owner. Open only when none exists; otherwise reuse it. Creates Peer seats only.",
949
+ peer: "Runs one Lead brief, writing or read-only. Created by Lead, one per brief, closed with it."
950
+ };
806
951
  }
807
952
  });
808
953
 
@@ -848,11 +993,23 @@ function roleProviders(layout, agent, binary, roles) {
848
993
  extends: agent.id,
849
994
  label: providerLabel(agent.id, role),
850
995
  command: [binary],
851
- env: { [agent.homeEnv]: roleHome(layout, agent.id, role) },
996
+ env: { ...agent.providerEnv, [agent.homeEnv]: roleHome(layout, agent.id, role) },
852
997
  paseoTools: { enabled: ROLE_PASEO_TOOLS[role] },
853
998
  ...agent.pins
854
999
  }]));
855
1000
  }
1001
+ function roleProfiles(agent, roles) {
1002
+ return roles.map((role) => ({
1003
+ id: profileId(agent.id, role),
1004
+ name: providerLabel(agent.id, role),
1005
+ icon: ROLE_ICON[role],
1006
+ color: ROLE_COLOR[role],
1007
+ provider: providerId(agent.id, role),
1008
+ modeId: agent.defaultModeId,
1009
+ thinkingOptionId: ROLE_THINKING[role],
1010
+ notes: ROLE_NOTES[role]
1011
+ }));
1012
+ }
856
1013
  async function buildDesired(layout, agents, roles) {
857
1014
  const entries = [
858
1015
  { kind: "dir", path: layout.roomHome },
@@ -860,44 +1017,60 @@ async function buildDesired(layout, agents, roles) {
860
1017
  { kind: "file", path: join7(sharedRoom(layout), "WORKSPACE_PROTOCOL.md"), content: renderInstructions("workspace") }
861
1018
  ];
862
1019
  const providers = {};
1020
+ const profiles = [];
863
1021
  const checks = [];
864
1022
  for (const id of agents) {
865
1023
  const agent = AGENTS[id];
866
1024
  const plan = await agent.build(layout, roles);
867
1025
  entries.push(...plan.entries);
868
1026
  checks.push(...plan.checks);
869
- if (plan.binary !== void 0) Object.assign(providers, roleProviders(layout, agent, plan.binary, roles));
1027
+ if (plan.binary === void 0) continue;
1028
+ Object.assign(providers, roleProviders(layout, agent, plan.binary, roles));
1029
+ profiles.push(...roleProfiles(agent, roles));
870
1030
  }
871
1031
  entries.push({ kind: "file", path: join7(layout.roomHome, MARKER), content: renderMarker(package_default.version, agents, roles) });
872
- return { entries, providers, checks };
1032
+ return { entries, providers, profiles, checks };
873
1033
  }
874
1034
  async function staleFrom(layout, previous, agents, roles) {
875
1035
  if (!previous) return NOTHING_STALE;
876
1036
  const kept = new Set(agents.flatMap((agent) => roles.map((role) => providerId(agent, role))));
877
1037
  const providerIds = [];
1038
+ const profileIds = [];
878
1039
  const directories = [];
879
1040
  for (const agent of previous.agents) {
880
1041
  for (const role of previous.roles) {
881
1042
  if (kept.has(providerId(agent, role))) continue;
882
1043
  providerIds.push(providerId(agent, role));
1044
+ profileIds.push(profileId(agent, role));
883
1045
  const path = roleHome(layout, agent, role);
884
1046
  if (await exists(path)) directories.push(path);
885
1047
  }
886
1048
  }
887
- return { providerIds, directories };
1049
+ return { providerIds, profileIds, directories };
888
1050
  }
889
1051
  async function planRoom(session, desired, stale) {
890
1052
  const live = await session.readProviders();
891
- return [
892
- ...await planEntries(desired.entries),
893
- ...Object.entries(desired.providers).map(([id, provider]) => ({
894
- action: !(id in live) ? "create" : providerMatches(provider, live[id]) ? "noop" : "update",
895
- kind: "provider",
896
- target: id
897
- })),
898
- ...stale.providerIds.filter((id) => id in live).map((id) => ({ action: "remove", kind: "provider", target: id })),
899
- ...stale.directories.map((path) => ({ action: "remove", kind: "dir", target: path }))
900
- ];
1053
+ const liveProfiles = await session.readProfiles();
1054
+ const byId = new Map(liveProfiles.map((entry) => [String(entry.id), entry]));
1055
+ return {
1056
+ liveProfiles,
1057
+ operations: [
1058
+ ...await planEntries(desired.entries),
1059
+ ...Object.entries(desired.providers).map(([id, provider]) => ({
1060
+ action: !(id in live) ? "create" : providerMatches(provider, live[id]) ? "noop" : "update",
1061
+ kind: "provider",
1062
+ target: id
1063
+ })),
1064
+ ...desired.profiles.map((profile) => ({
1065
+ action: !byId.has(profile.id) ? "create" : profileMatches(profile, byId.get(profile.id)) ? "noop" : "update",
1066
+ kind: "profile",
1067
+ target: profile.id
1068
+ })),
1069
+ ...stale.providerIds.filter((id) => id in live).map((id) => ({ action: "remove", kind: "provider", target: id })),
1070
+ ...stale.profileIds.filter((id) => byId.has(id)).map((id) => ({ action: "remove", kind: "profile", target: id })),
1071
+ ...stale.directories.map((path) => ({ action: "remove", kind: "dir", target: path }))
1072
+ ]
1073
+ };
901
1074
  }
902
1075
  async function setup(options = {}) {
903
1076
  const layout = resolveLayout(options, options.env);
@@ -911,7 +1084,7 @@ async function setup(options = {}) {
911
1084
  if (hasFailure(checks)) return failed("setup", checks);
912
1085
  const stale = await staleFrom(layout, await readMarker(layout), agents, ROLES);
913
1086
  return withSession(daemon.daemon, async (session) => {
914
- const operations = await planRoom(session, desired, stale);
1087
+ const { operations, liveProfiles } = await planRoom(session, desired, stale);
915
1088
  const pending = operations.filter((operation) => operation.action !== "noop");
916
1089
  if (!options.apply) {
917
1090
  return {
@@ -927,6 +1100,9 @@ async function setup(options = {}) {
927
1100
  const ids = Object.keys(desired.providers);
928
1101
  await session.writeProviders(desired.providers);
929
1102
  if (stale.providerIds.length > 0) await session.removeProviders(stale.providerIds);
1103
+ if (pending.some((operation) => operation.kind === "profile")) {
1104
+ await session.writeProfiles(mergeProfiles(liveProfiles, desired.profiles, stale.profileIds));
1105
+ }
930
1106
  await session.refresh(ids);
931
1107
  return {
932
1108
  command: "setup",
@@ -951,14 +1127,17 @@ async function verify(options = {}) {
951
1127
  const checks = [...daemon.checks, ...desired.checks];
952
1128
  if (hasFailure(checks)) return failed("verify", checks);
953
1129
  return withSession(daemon.daemon, async (session) => {
954
- const operations = await planRoom(session, desired, NOTHING_STALE);
1130
+ const { operations } = await planRoom(session, desired, NOTHING_STALE);
955
1131
  const drifted = operations.filter((operation) => operation.action !== "noop");
956
- const providers = drifted.filter((operation) => operation.kind === "provider").length;
957
- const files = drifted.length - providers;
1132
+ const count = (kind) => drifted.filter((operation) => operation.kind === kind).length;
1133
+ const providers = count("provider");
1134
+ const profiles = count("profile");
1135
+ const files = drifted.length - providers - profiles;
958
1136
  const all = [
959
1137
  ...checks,
960
1138
  files === 0 ? pass("room.files", "Every managed role file matches the current definition.") : fail("room.files", `${String(files)} managed role files are missing or outdated.`, "Run: paseo-room setup --apply"),
961
- providers === 0 ? pass("room.providers", `All ${String(Object.keys(desired.providers).length)} Paseo providers are registered as expected.`) : fail("room.providers", `${String(providers)} Paseo providers are missing or differ.`, "Run: paseo-room setup --apply")
1139
+ providers === 0 ? pass("room.providers", `All ${String(Object.keys(desired.providers).length)} Paseo providers are registered as expected.`) : fail("room.providers", `${String(providers)} Paseo providers are missing or differ.`, "Run: paseo-room setup --apply"),
1140
+ profiles === 0 ? pass("room.profiles", `All ${String(desired.profiles.length)} Paseo agent profiles are registered as expected.`) : fail("room.profiles", `${String(profiles)} Paseo agent profiles are missing or differ.`, "Run: paseo-room setup --apply")
962
1141
  ];
963
1142
  return {
964
1143
  command: "verify",
@@ -978,8 +1157,10 @@ async function remove(options = {}) {
978
1157
  const invalid = layoutChecks(layout, marker.agents);
979
1158
  if (invalid.length > 0) return failed("remove", invalid);
980
1159
  const ids = marker.agents.flatMap((agent) => marker.roles.map((role) => providerId(agent, role)));
1160
+ const profiles = new Set(marker.agents.flatMap((agent) => marker.roles.map((role) => profileId(agent, role))));
981
1161
  const operations = [
982
1162
  ...ids.map((id) => ({ action: "remove", kind: "provider", target: id })),
1163
+ ...[...profiles].map((id) => ({ action: "remove", kind: "profile", target: id })),
983
1164
  { action: "remove", kind: "dir", target: layout.roomHome }
984
1165
  ];
985
1166
  if (!options.apply) {
@@ -988,10 +1169,15 @@ async function remove(options = {}) {
988
1169
  const daemon = await checkDaemon(layout, options.env);
989
1170
  const checks = [];
990
1171
  if (daemon.daemon) {
991
- await withSession(daemon.daemon, (session) => session.removeProviders(ids), sessionOptions(options));
992
- checks.push(pass("room.providers", `Removed ${String(ids.length)} Paseo providers.`));
1172
+ await withSession(daemon.daemon, async (session) => {
1173
+ await session.removeProviders(ids);
1174
+ const live = await session.readProfiles();
1175
+ const kept = live.filter((entry) => !profiles.has(String(entry.id)));
1176
+ if (kept.length !== live.length) await session.writeProfiles(kept);
1177
+ }, sessionOptions(options));
1178
+ checks.push(pass("room.providers", `Removed ${String(ids.length)} Paseo providers and their agent profiles.`));
993
1179
  } else {
994
- checks.push({ id: "room.providers", status: "warn", message: "Paseo is unreachable; provider entries were left in place.", fix: "Start Paseo and run remove again to clear them." });
1180
+ checks.push({ id: "room.providers", status: "warn", message: "Paseo is unreachable; provider and profile entries were left in place.", fix: "Start Paseo and run remove again to clear them." });
995
1181
  }
996
1182
  await rm2(layout.roomHome, { recursive: true, force: true });
997
1183
  checks.push(pass("room.files", `Deleted ${layout.roomHome}.`));
@@ -1012,7 +1198,7 @@ var init_commands = __esm({
1012
1198
  init_room();
1013
1199
  init_roles();
1014
1200
  AGENTS = { codex: codexAgent, claude: claudeAgent };
1015
- NOTHING_STALE = { providerIds: [], directories: [] };
1201
+ NOTHING_STALE = { providerIds: [], profileIds: [], directories: [] };
1016
1202
  }
1017
1203
  });
1018
1204
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/result.ts","../src/layout.ts","../src/fsops.ts","../src/room/clauses.ts","../src/room/workspace.ts","../src/room/instructions.ts","../src/which.ts","../src/agents/claude.ts","../src/agents/codex.ts","../src/paseo.ts","../src/roles.ts","../src/room.ts","../src/commands.ts","../src/wizard.ts","../src/cli.ts","../src/render.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"paseo-room\",\n \"version\": \"0.1.0-alpha.2\",\n \"description\": \"One CLI that configures Codex/Claude role homes in $HOME and registers them with your local Paseo daemon.\",\n \"keywords\": [\n \"paseo\",\n \"codex\",\n \"claude-code\",\n \"agent\",\n \"orchestration\",\n \"cli\"\n ],\n \"homepage\": \"https://github.com/cuongntr/paseo-room#readme\",\n \"bugs\": \"https://github.com/cuongntr/paseo-room/issues\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/cuongntr/paseo-room.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Invoker <cuongnt1987@gmail.com>\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=22\"\n },\n \"bin\": {\n \"paseo-room\": \"dist/index.js\"\n },\n \"files\": [\n \"dist/\"\n ],\n \"scripts\": {\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint . --max-warnings 0\",\n \"test\": \"vitest run\",\n \"build\": \"tsup\",\n \"prepack\": \"npm run build\",\n \"verify\": \"npm run typecheck && npm run lint && npm test && npm run build\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.8.0\",\n \"@getpaseo/client\": \"0.8.0-beta.1\",\n \"commander\": \"^14.0.3\",\n \"semver\": \"^7.8.5\",\n \"smol-toml\": \"^1.8.0\",\n \"zod\": \"^4.5.4\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@types/node\": \"^22.0.0\",\n \"@types/semver\": \"^7.7.0\",\n \"eslint\": \"^10.10.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"~5.9.3\",\n \"typescript-eslint\": \"^8.70.0\",\n \"vitest\": \"^4.1.11\"\n }\n}\n","export type Status = 'pass' | 'warn' | 'fail';\nexport interface Check {\n readonly id: string;\n readonly status: Status;\n readonly message: string;\n readonly fix?: string;\n}\nexport interface Operation {\n readonly action: 'create' | 'update' | 'remove' | 'noop';\n readonly kind: 'dir' | 'file' | 'link' | 'provider';\n readonly target: string;\n}\nexport type Outcome = 'ok' | 'changes-planned' | 'failed';\nexport interface Result {\n readonly command: string;\n readonly outcome: Outcome;\n readonly changed: boolean;\n readonly checks: readonly Check[];\n readonly operations: readonly Operation[];\n}\n\nexport function pass(id: string, message: string): Check {\n return { id, status: 'pass', message };\n}\nexport function fail(id: string, message: string, fix: string): Check {\n return { id, status: 'fail', message, fix };\n}\nexport function failed(command: string, checks: readonly Check[]): Result {\n return { command, outcome: 'failed', changed: false, checks, operations: [] };\n}\nexport function hasFailure(checks: readonly Check[]): boolean {\n return checks.some(check => check.status === 'fail');\n}\nexport function exitCode(result: Result): number {\n return result.outcome === 'failed' || hasFailure(result.checks) ? 1 : 0;\n}\n","import { homedir } from 'node:os';\nimport { join, resolve, sep } from 'node:path';\nimport { fail, type Check } from './result.js';\nimport type { AgentId, Role } from './roles.js';\n\nexport interface Options {\n readonly roomHome?: string;\n readonly codexHome?: string;\n readonly claudeHome?: string;\n readonly codexBin?: string;\n readonly claudeBin?: string;\n readonly paseoBin?: string;\n}\nexport interface Layout {\n readonly home: string;\n readonly roomHome: string;\n readonly paseoHome: string;\n readonly agentHome: Record<AgentId, string>;\n readonly bin: Record<AgentId | 'paseo', string>;\n /** The PATH executables are looked up on. Resolved here so nothing reaches for process.env. */\n readonly searchPath: string;\n}\n\nfunction pick(...candidates: readonly (string | undefined)[]): string {\n for (const candidate of candidates) if (candidate?.trim()) return candidate.trim();\n throw new Error('Could not determine HOME; pass explicit --room-home and --codex-home/--claude-home paths.');\n}\n\n/** Everything is derived from HOME; flags and environment only override defaults. */\nexport function resolveLayout(options: Options = {}, env: NodeJS.ProcessEnv = process.env): Layout {\n const home = pick(env.HOME, homedir());\n // Relative overrides resolve against the working directory, as a CLI flag should.\n return {\n home,\n roomHome: resolve(pick(options.roomHome, env.PASEO_ROOM_HOME, join(home, '.paseo-room'))),\n paseoHome: resolve(pick(env.PASEO_HOME, join(home, '.paseo'))),\n agentHome: {\n codex: resolve(pick(options.codexHome, env.CODEX_HOME, join(home, '.codex'))),\n claude: resolve(pick(options.claudeHome, env.CLAUDE_CONFIG_DIR, join(home, '.claude'))),\n },\n bin: {\n codex: pick(options.codexBin, env.CODEX_BIN, 'codex'),\n claude: pick(options.claudeBin, env.CLAUDE_BIN, 'claude'),\n paseo: pick(options.paseoBin, env.PASEO_BIN, 'paseo'),\n },\n searchPath: env.PATH ?? '',\n };\n}\n\n/** True when `path` is the root itself or sits underneath it. */\nexport function contains(root: string, path: string): boolean {\n return path === root || path.startsWith(root.endsWith(sep) ? root : root + sep);\n}\n\n/** The room home must own its directory: no overlap with $HOME or a source agent home. */\nexport function layoutChecks(layout: Layout, agents: readonly AgentId[]): Check[] {\n const checks: Check[] = [];\n if (contains(layout.roomHome, layout.home)) {\n checks.push(fail('room.home', `Refusing to use ${layout.roomHome} as the room home: it contains your home directory.`,\n 'Point --room-home at a dedicated directory, by default ~/.paseo-room.'));\n }\n for (const id of agents) {\n const home = layout.agentHome[id];\n if (contains(layout.roomHome, home) || contains(home, layout.roomHome)) {\n checks.push(fail(`${id}.home`, `The ${id} home ${home} overlaps the room home ${layout.roomHome}.`,\n `Pass --${id}-home pointing at your own ${id} configuration (this happens when setup runs inside a room seat).`));\n }\n }\n return checks;\n}\n\nexport function roleHome(layout: Layout, agent: AgentId, role: Role): string {\n return join(layout.roomHome, 'roles', agent, role);\n}\nexport function sharedRoom(layout: Layout): string {\n return join(layout.roomHome, 'room');\n}\n","import { chmod, lstat, mkdir, readFile, readlink, rm, symlink, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport type { Operation } from './result.js';\n\nexport type Entry =\n | { readonly kind: 'dir'; readonly path: string }\n /** `once` writes the file only when absent: runtime state the agent owns after setup. */\n | { readonly kind: 'file'; readonly path: string; readonly content: string; readonly once?: true }\n | { readonly kind: 'link'; readonly path: string; readonly target: string };\n\nconst DIR_MODE = 0o700;\nconst FILE_MODE = 0o600;\n\nasync function current(entry: Entry): Promise<'absent' | 'same' | 'different'> {\n let stat;\n try { stat = await lstat(entry.path); } catch { return 'absent'; }\n if (entry.kind === 'dir') return stat.isDirectory() ? 'same' : 'different';\n if (entry.kind === 'link') {\n if (!stat.isSymbolicLink()) return 'different';\n return await readlink(entry.path) === entry.target ? 'same' : 'different';\n }\n if (!stat.isFile()) return 'different';\n if (entry.once) return 'same';\n return await readFile(entry.path, 'utf8') === entry.content ? 'same' : 'different';\n}\n\n/** Everything lives under the room home, which this CLI owns outright. */\nexport async function planEntries(entries: readonly Entry[]): Promise<Operation[]> {\n const operations: Operation[] = [];\n for (const entry of entries) {\n const state = await current(entry);\n operations.push({\n action: state === 'same' ? 'noop' : state === 'absent' ? 'create' : 'update',\n kind: entry.kind,\n target: entry.path,\n });\n }\n return operations;\n}\n\n/** Rewrites only what differs, so a repeat run costs stats rather than writes. */\nexport async function applyEntries(entries: readonly Entry[]): Promise<void> {\n for (const entry of entries) {\n if (await current(entry) === 'same') continue;\n if (entry.kind === 'dir') {\n await mkdir(entry.path, { recursive: true, mode: DIR_MODE });\n continue;\n }\n await mkdir(dirname(entry.path), { recursive: true, mode: DIR_MODE });\n await rm(entry.path, { force: true, recursive: true });\n if (entry.kind === 'link') await symlink(entry.target, entry.path);\n else {\n await writeFile(entry.path, entry.content, { mode: FILE_MODE });\n await chmod(entry.path, FILE_MODE);\n }\n }\n}\n\nexport async function exists(path: string): Promise<boolean> {\n try { await lstat(path); return true; } catch { return false; }\n}\n\n/** Which of `names` exist under `home`, probed once for all roles that share them. */\nexport async function existingPaths(home: string, names: readonly string[]): Promise<string[]> {\n const paths = names.map(name => join(home, name));\n const present = await Promise.all(paths.map(exists));\n return paths.filter((_, index) => present[index] === true);\n}\n\nexport async function readIfPresent(path: string): Promise<string | undefined> {\n try { return await readFile(path, 'utf8'); } catch { return undefined; }\n}\n","/**\n * The room's authority contract, in the wording the agents actually read.\n *\n * Write each statement as ordinary wrapped prose. Blank lines separate\n * statements; line breaks inside a statement are just there for reading and\n * collapse into single spaces when rendered.\n */\nexport function clause(source: string): readonly string[] {\n return source\n .trim()\n .split(/\\n\\s*\\n/)\n .map(statement => statement.split('\\n').map(line => line.trim()).join(' '));\n}\n\nexport const CLAUSES = {\n 'RC-001': clause(`\n Human owns product goals, priority, material-cost choices, external effects, and\n irreversible-risk decisions. No agent may take ownership of these decisions; obtain\n Human approval before crossing those boundaries.\n\n Human may direct the technical route, decomposition, and lifecycle, and may override\n an acceptance decision. Human does not normally operate the agent protocol.\n `),\n\n 'RC-002': clause(`\n A workspace protocol governs repository-local workflow: topology, verification\n commands, review rhythm, escalation routes, and project conventions. The room ships a\n default, and the part of it that bears on this role is reproduced at the end of this\n document. That default is in force wherever the repository says nothing.\n\n When the repository provides docs/WORKSPACE_PROTOCOL.md, read the parts that bear on\n your own work and follow them wherever they speak to a point. A repository rule wins\n over the default on that point; the default still holds everywhere the repository is\n silent.\n\n Neither the default nor a repository file can weaken this authority contract. No\n protocol can give Peer orchestration, give Supervisor or Peer technical acceptance,\n permit multiple writable Peers, or transfer Human decisions to an agent.\n `),\n\n 'RC-003': clause(`\n Use tests, artifacts, lifecycle states, and completion/error/attention events as\n evidence, not as automatic authorization or acceptance.\n\n Wait for state-changing events when progress depends on another actor. Do not\n repeatedly poll unchanged state; resume when new evidence or a relevant event arrives.\n `),\n\n 'RC-004': clause(`\n Preserve unrelated work. Stay within the granted repository scope and external-action\n authority; do not treat access to a tool as permission to expand either boundary.\n `),\n\n 'RC-101': clause(`\n Supervisor routes the Human directive to Lead without changing its outcome, requested\n output, constraints, or approval gates. Label added context separately; it must not\n rewrite the directive.\n `),\n\n 'RC-102': clause(`\n Supervisor observes technical work rather than choosing architecture, decomposing\n work, or moving write ownership. Prefer routing work through Lead.\n\n Supervisor must not edit project work, run project validation, or decide technical\n acceptance. Supervisor must not direct Peer while Lead is healthy; an unhealthy Lead\n calls for bounded recovery or escalation, not taking over Peer work.\n `),\n\n 'RC-103': clause(`\n Supervisor has Paseo tools enabled solely within its authority. Use the smallest Paseo\n room/session lifecycle action needed for an explicit Human request or bounded room\n recovery; preserve current ownership and inform Lead of every change.\n `),\n\n 'RC-104': clause(`\n Supervisor sends technical questions and evidence to Lead. Escalate product, priority,\n material-cost, external-effect, and irreversible-risk choices to Human rather than\n deciding them.\n `),\n\n 'RC-201': clause(`\n Lead owns project framing, architecture, dependencies, integration, verification, and\n technical acceptance within Human boundaries. Lead executes the Human outcome and\n constraints, escalating Human-owned choices to Human.\n\n Lead has Paseo tools enabled to manage project agents and direct Peer; this capability\n does not expand project or external-action authority.\n `),\n\n 'RC-202': clause(`\n Lead owns decomposition and moving write-scope assignment: give each moving scope\n exactly one owner, with at most one active writable Peer across the project at a time.\n Lead must not edit a scope concurrently with its writing Peer.\n\n Before transferring write ownership, stop the prior writer and establish a stable\n handoff. Read-only review does not create another writer.\n `),\n\n 'RC-203': clause(`\n Before delegation, Lead supplies a complete Peer brief: one bounded outcome,\n prerequisites, explicit write scope or read-only mode, stable contract and invariants,\n required acceptance evidence, and conditions that reopen the decision.\n `),\n\n 'RC-204': clause(`\n Lead permits independent Peer judgment: REOPEN_REQUEST challenges a premise;\n DEPENDENCY_REQUEST asks for an unowned prerequisite; BLOCKED reports that no safe\n progress is possible.\n\n For each signal, Peer provides evidence, consequence, and the needed decision or\n dependency. Lead resolves technical signals or escalates Human-owned choices; Peer\n must not seize unowned work while waiting.\n `),\n\n 'RC-205': clause(`\n Lead inspects the exact candidate or a deterministic snapshot and explicitly accepts\n or rejects it with a technical reason. Passing tests and completion reports are\n evidence, not acceptance. Among agents, Lead alone accepts; Human retains override\n authority.\n `),\n\n 'RC-206': clause(`\n When material uncertainty warrants independent review, Lead may dispatch a fresh\n read-only Peer with an exact stable candidate and a bounded question. Review is\n optional: do not introduce a dedicated reviewer role or a fixed reviewer count.\n `),\n\n 'RC-301': clause(`\n Peer owns exactly one Lead-delegated bounded outcome and proportionate evidence. Do\n not add adjacent tasks; send technical questions to Lead and escalate Human-owned\n choices through Lead.\n `),\n\n 'RC-302': clause(`\n A writing Peer owns only its assigned moving write scope. A review Peer stays\n read-only and inspects only the named candidate or snapshot, without changing project\n files or the candidate.\n `),\n\n 'RC-303': clause(`\n Peer must not spawn, manage, coordinate, or infer room topology, direct another Peer,\n or perform Paseo room/session lifecycle operations. Peer receives no Paseo tools;\n enabled is false. This capability boundary is not an operating-system sandbox.\n `),\n\n 'RC-304': clause(`\n Peer hands off a candidate by naming an immutable commit or deterministic snapshot,\n the original base, all changed paths, verification performed and its results, and\n residual risk. Make the candidate reproducible for Lead inspection.\n `),\n\n 'RC-305': clause(`\n Peer must not self-accept any work, including difficult work. Peer tests and\n completion are evidence only; Lead alone performs technical acceptance among agents,\n subject to Human override.\n `),\n};\n\nexport type RoleContractId = keyof typeof CLAUSES;\nexport const SHARED_IDS = ['RC-001', 'RC-002', 'RC-003', 'RC-004'] as const;\n","/**\n * The room's default workspace protocol: the repository-local layer of the model,\n * in the wording the seats actually read.\n *\n * It ships in force, not as something to copy. A repository that needs different\n * rules writes its own docs/WORKSPACE_PROTOCOL.md, which wins wherever it speaks\n * (RC-002).\n *\n * Keep every statement here workflow, and keep it new. Authority belongs in\n * clauses.ts: restating a clause here teaches the seat nothing and blurs the\n * boundary the two layers depend on. Anything true of only one project belongs in\n * that project's own file.\n */\nimport { clause } from './clauses.js';\n\nexport const DEFAULT_PROTOCOL = {\n 'WP-01 Topology': clause(`\n Match the shape of the work to its difficulty. A change Lead can make correctly in one\n sitting is made by Lead, without a Peer: delegation costs a brief, a handoff and a\n review, and a trivial change does not repay them.\n\n When the route itself is uncertain, spend a read-only Peer on the question before\n spending a writable Peer on the answer.\n `),\n\n 'WP-02 Verification': clause(`\n The repository's own gate is the evidence. Lead names the exact command in the brief;\n Peer runs it and reports the result as it came back, failures included. A candidate\n whose gate was not run is not a candidate.\n\n Do not report part of the gate as the whole of it, and do not report work as done while\n any part of it is unrun.\n `),\n\n 'WP-03 Review': clause(`\n Review runs in a fresh session rather than a continuation of the writer's. A session\n that produced the work cannot be surprised by it.\n `),\n\n 'WP-04 Repository conventions': clause(`\n Follow the conventions already visible in the files being changed rather than importing\n a different house style alongside them.\n\n Do not add top-level files, directories, dependencies or tooling the brief did not ask\n for. A repository that wants them will say so in its own protocol.\n `),\n};\n\nexport type ProtocolId = keyof typeof DEFAULT_PROTOCOL;\n","import type { Role } from '../roles.js';\nimport { CLAUSES, SHARED_IDS, type RoleContractId } from './clauses.js';\nimport { DEFAULT_PROTOCOL, type ProtocolId } from './workspace.js';\n\nexport type InstructionKind = Role | 'workspace';\n\nconst ROLE_IDS: Record<Role, readonly RoleContractId[]> = {\n supervisor: ['RC-101', 'RC-102', 'RC-103', 'RC-104'],\n lead: ['RC-201', 'RC-202', 'RC-203', 'RC-204', 'RC-205', 'RC-206'],\n // Peer needs the challenge protocol as well as its own numbered obligations.\n peer: ['RC-204', 'RC-301', 'RC-302', 'RC-303', 'RC-304', 'RC-305'],\n};\n\n// Topology is Lead's decision and Supervisor's to audit. RC-303 forbids Peer to\n// infer room topology, so handing Peer the topology rules would contradict its\n// own contract.\nconst PROTOCOL_IDS: Record<Role, readonly ProtocolId[]> = {\n supervisor: ['WP-01 Topology', 'WP-02 Verification', 'WP-03 Review', 'WP-04 Repository conventions'],\n lead: ['WP-01 Topology', 'WP-02 Verification', 'WP-03 Review', 'WP-04 Repository conventions'],\n peer: ['WP-02 Verification', 'WP-03 Review', 'WP-04 Repository conventions'],\n};\n\nconst PREFACES: Record<Role, string> = {\n supervisor: 'You are Supervisor, the Human-facing routing seat, not the project Lead.',\n lead: 'You are Lead, the project technical owner under Human authority.',\n peer: 'You are Peer, executing one brief from Lead in writing or read-only review mode.',\n};\n\nconst TITLES: Record<Role, string> = {\n supervisor: 'Supervisor role instructions',\n lead: 'Lead role instructions',\n peer: 'Peer role instructions',\n};\n\nconst PROTOCOL_TITLE = 'Workspace protocol';\n// Stated without a clause number, because this preface also heads the copy written\n// to the room home, where no clause is present to resolve the reference.\nconst PROTOCOL_PREFACE = [\n 'This is the room default, and it is in force now. A repository that needs different rules',\n 'provides `docs/WORKSPACE_PROTOCOL.md`: read it, follow it wherever it speaks to a point,',\n 'and keep what follows where it is silent.',\n].join('\\n');\n\nexport function instructionIds(role: Role): readonly RoleContractId[] {\n // Every role carries the shared authority contract plus its own obligations.\n return [...SHARED_IDS, ...ROLE_IDS[role]];\n}\n\nexport function protocolIds(role: Role): readonly ProtocolId[] {\n return PROTOCOL_IDS[role];\n}\n\nfunction sections(ids: readonly string[], source: Readonly<Record<string, readonly string[]>>): string[] {\n return ids.map(id => `## ${id}\\n${(source[id] ?? []).map(statement => `- ${statement}`).join('\\n')}`);\n}\n\n/** The protocol travels inside every role document, so no repository has to opt in. */\nfunction protocol(ids: readonly ProtocolId[]): string[] {\n return [`# ${PROTOCOL_TITLE}`, PROTOCOL_PREFACE, ...sections(ids, DEFAULT_PROTOCOL)];\n}\n\nexport function renderInstructions(kind: InstructionKind): string {\n if (kind === 'workspace') {\n return protocol(Object.keys(DEFAULT_PROTOCOL) as ProtocolId[]).join('\\n\\n') + '\\n';\n }\n return [\n `# ${TITLES[kind]}`,\n PREFACES[kind],\n ...sections(instructionIds(kind), CLAUSES),\n ...protocol(protocolIds(kind)),\n ].join('\\n\\n') + '\\n';\n}\n","import { execFile } from 'node:child_process';\nimport { access, constants } from 'node:fs/promises';\nimport { delimiter, isAbsolute, join, resolve } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst run = promisify(execFile);\n\n/**\n * Resolve a command to an absolute executable path on `searchPath`.\n *\n * Deliberately not canonicalised. Version managers point a stable name at a\n * versioned file — `~/.local/bin/claude` at `versions/2.1.267`, mise's\n * `node/latest` at `node/24.15.0` — and the resolved target is deleted by the\n * next upgrade. Providers store this path, so following the link would pin every\n * seat to a binary that stops existing.\n */\nexport async function which(command: string, searchPath: string): Promise<string | undefined> {\n const candidates = isAbsolute(command) || command.includes('/')\n ? [resolve(command)]\n : searchPath.split(delimiter).filter(Boolean).map(entry => join(entry, command));\n for (const candidate of candidates) {\n try {\n await access(candidate, constants.X_OK);\n return candidate;\n } catch { /* try the next PATH entry */ }\n }\n return undefined;\n}\n\nexport interface CommandOutput {\n readonly ok: boolean;\n readonly stdout: string;\n}\n/** Bounded, shell-free probe. Failures are reported, never thrown. */\nexport async function probe(executable: string, args: readonly string[], env: NodeJS.ProcessEnv): Promise<CommandOutput> {\n try {\n const { stdout } = await run(executable, [...args], { env, timeout: 20_000, maxBuffer: 16 * 1024 * 1024, encoding: 'utf8' });\n return { ok: true, stdout };\n } catch {\n return { ok: false, stdout: '' };\n }\n}\n","import { basename, join } from 'node:path';\nimport type { Layout } from '../layout.js';\nimport { roleHome } from '../layout.js';\nimport type { Entry } from '../fsops.js';\nimport { existingPaths, exists, readIfPresent } from '../fsops.js';\nimport { fail, pass, type Check } from '../result.js';\nimport type { Role } from '../roles.js';\nimport { renderInstructions } from '../room/instructions.js';\nimport { which } from '../which.js';\nimport type { Agent, AgentPlan } from './types.js';\n\n/** Operator resources shared by reference; credentials stay where Claude put them. */\nconst SHARED = ['.credentials.json', 'skills', 'plugins', 'commands', 'hooks'] as const;\n/** Copied once so a fresh role home does not re-run interactive onboarding. */\nconst SEEDED_KEYS = ['hasCompletedOnboarding', 'theme', 'installMethod', 'userID', 'oauthAccount'] as const;\n\nfunction asObject(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? { ...value } : {};\n}\n/** Any unreadable or non-object source is simply an empty starting point. */\nfunction readObject(source: string | undefined): Record<string, unknown> {\n try { return asObject(source === undefined ? {} : JSON.parse(source)); } catch { return {}; }\n}\n\n/** Keep the operator's hooks and env (Paseo installs its own), override nothing else. */\nexport function renderRoleSettings(source: string | undefined, role: Role): string {\n const settings = readObject(source);\n settings.env = { ...asObject(settings.env), PASEO_ROOM_ROLE: role };\n return JSON.stringify(settings, null, 2) + '\\n';\n}\n\nexport function renderRoleState(source: string | undefined): string {\n const root = readObject(source);\n const state: Record<string, unknown> = { hasCompletedOnboarding: true };\n for (const key of SEEDED_KEYS) if (key in root) state[key] = root[key];\n return JSON.stringify(state, null, 2) + '\\n';\n}\n\nexport const claudeAgent: Agent = {\n id: 'claude',\n label: 'Claude Code',\n homeEnv: 'CLAUDE_CONFIG_DIR',\n // Claude's own subagents would be a second control plane; Paseo owns agent\n // lifecycle. This is the Claude counterpart of Codex's [agents] enabled = false.\n pins: { disallowedTools: ['Task'] },\n async build(layout: Layout, roles: readonly Role[]): Promise<AgentPlan> {\n const home = layout.agentHome.claude;\n const binary = await which(layout.bin.claude, layout.searchPath);\n if (!binary) {\n return { entries: [], checks: [fail('claude.bin', 'Claude Code executable not found.', 'Install Claude Code, or pass --claude-bin /path/to/claude.')] };\n }\n if (!(await exists(home))) {\n return { entries: [], checks: [fail('claude.home', `No Claude config directory at ${home}.`, 'Run claude once to initialise it, or pass --claude-home.')] };\n }\n const checks: Check[] = [pass('claude.home', `Claude Code found at ${binary} using ${home}.`)];\n\n const settingsSource = await readIfPresent(join(home, 'settings.json'));\n const stateSource = await readIfPresent(join(layout.home, '.claude.json'));\n const shared = await existingPaths(home, SHARED);\n const entries: Entry[] = [];\n for (const role of roles) {\n const target = roleHome(layout, 'claude', role);\n entries.push({ kind: 'dir', path: target });\n entries.push({ kind: 'file', path: join(target, 'CLAUDE.md'), content: renderInstructions(role) });\n entries.push({ kind: 'file', path: join(target, 'settings.json'), content: renderRoleSettings(settingsSource, role) });\n entries.push({ kind: 'file', path: join(target, '.claude.json'), content: renderRoleState(stateSource), once: true });\n for (const path of shared) entries.push({ kind: 'link', path: join(target, basename(path)), target: path });\n }\n return { entries, checks, binary };\n },\n};\n","import { basename, join } from 'node:path';\nimport { parse, stringify, type TomlTable } from 'smol-toml';\nimport type { Layout } from '../layout.js';\nimport { roleHome } from '../layout.js';\nimport type { Entry } from '../fsops.js';\nimport { existingPaths, readIfPresent } from '../fsops.js';\nimport { fail, pass, type Check } from '../result.js';\nimport type { Role } from '../roles.js';\nimport { renderInstructions } from '../room/instructions.js';\nimport { probe, which } from '../which.js';\nimport type { Agent, AgentPlan } from './types.js';\n\n/** Read-only operator resources every role shares by reference, never by copy. */\nconst SHARED = ['auth.json', 'AGENTS.md', 'skills', 'plugins', 'hooks.json'] as const;\nconst CATALOG = 'model-catalog.json';\n\nfunction table(parent: TomlTable, key: string): TomlTable {\n const value = parent[key];\n if (value === undefined || typeof value !== 'object' || Array.isArray(value) || value instanceof Date) {\n return (parent[key] = {});\n }\n return value;\n}\n\nexport interface RoleConfigInput {\n readonly roleDocument: string;\n readonly catalogPath?: string;\n}\n/**\n * Copy the operator's config, then override only the keys the room owns.\n *\n * `model_instructions_file` is deliberately untouched: it *replaces* Codex's base\n * prompt, so writing it would mean vendoring and maintaining a full copy of that\n * prompt. The room contract is additive and belongs in `developer_instructions`.\n */\nexport function renderRoleConfig(source: TomlTable, input: RoleConfigInput): string {\n const config = structuredClone(source);\n config.sandbox_mode = 'danger-full-access';\n config.approval_policy = 'never';\n // An active profile outranks the top-level keys, so the room's must land there too.\n if (typeof config.profile === 'string') {\n const profile = table(table(config, 'profiles'), config.profile);\n profile.sandbox_mode = 'danger-full-access';\n profile.approval_policy = 'never';\n }\n config.developer_instructions = input.roleDocument;\n if (input.catalogPath) config.model_catalog_json = input.catalogPath;\n // Codex's own multi-agent mode would compete with the room's role contract.\n table(config, 'agents').enabled = false;\n const features = table(config, 'features');\n features.multi_agent = false;\n // Newer configs represent v2 as a table; keep that shape rather than writing a\n // boolean at the same key, which would be a TOML conflict.\n if (typeof features.multi_agent_v2 === 'boolean' || features.multi_agent_v2 === undefined) features.multi_agent_v2 = false;\n else table(features, 'multi_agent_v2').enabled = false;\n return stringify(config) + '\\n';\n}\n\nexport function renderCatalog(catalog: unknown): string {\n return JSON.stringify(catalog, (key, value: unknown) => (key === 'multi_agent_version' ? null : value), 2) + '\\n';\n}\n\nexport const codexAgent: Agent = {\n id: 'codex',\n label: 'Codex',\n homeEnv: 'CODEX_HOME',\n // Without these, Paseo's own mode preset (default auto-review) is sent to the\n // app-server and outranks the sandbox/approval keys in the generated config.\n pins: { params: { sandbox_mode: 'danger-full-access', approval_policy: 'never' } },\n async build(layout: Layout, roles: readonly Role[]): Promise<AgentPlan> {\n const checks: Check[] = [];\n const home = layout.agentHome.codex;\n const binary = await which(layout.bin.codex, layout.searchPath);\n if (!binary) {\n return { entries: [], checks: [fail('codex.bin', 'Codex executable not found.', 'Install Codex, or pass --codex-bin /path/to/codex.')] };\n }\n const configPath = join(home, 'config.toml');\n const raw = await readIfPresent(configPath);\n if (raw === undefined) {\n return { entries: [], checks: [fail('codex.home', `No config.toml in ${home}.`, 'Run codex once to initialise it, or pass --codex-home.')] };\n }\n let source: TomlTable;\n try { source = parse(raw); } catch {\n return { entries: [], checks: [fail('codex.config', `Could not read ${configPath} as TOML.`, 'Fix the syntax in your Codex config, then run setup again.')] };\n }\n checks.push(pass('codex.home', `Codex found at ${binary} using ${home}.`));\n\n const entries: Entry[] = [];\n\n // The catalog is optional: an older Codex simply keeps its built-in models.\n let catalogSource: string | undefined;\n const models = await probe(binary, ['debug', 'models'], { HOME: layout.home, CODEX_HOME: home, PATH: layout.searchPath });\n if (models.ok) {\n try { catalogSource = renderCatalog(JSON.parse(models.stdout)); } catch { catalogSource = undefined; }\n }\n if (!catalogSource) checks.push({ id: 'codex.catalog', status: 'warn', message: 'Codex model catalog unavailable; roles keep the default catalog.' });\n\n const shared = await existingPaths(home, SHARED);\n for (const role of roles) {\n const target = roleHome(layout, 'codex', role);\n const catalogPath = catalogSource ? join(target, CATALOG) : undefined;\n const roleDocument = renderInstructions(role);\n entries.push({ kind: 'dir', path: target });\n // Codex reads the brief from developer_instructions; this copy is for the operator.\n entries.push({ kind: 'file', path: join(target, 'role-instructions.md'), content: roleDocument });\n entries.push({\n kind: 'file',\n path: join(target, 'config.toml'),\n content: renderRoleConfig(source, { roleDocument, ...(catalogPath ? { catalogPath } : {}) }),\n });\n if (catalogSource && catalogPath) entries.push({ kind: 'file', path: catalogPath, content: catalogSource });\n for (const path of shared) entries.push({ kind: 'link', path: join(target, basename(path)), target: path });\n }\n return { entries, checks, binary };\n },\n};\n","import type { PaseoClient, PaseoClientConfig } from '@getpaseo/client';\nimport { gte, valid } from 'semver';\nimport { z } from 'zod';\nimport type { Layout } from './layout.js';\nimport { fail, pass, type Check } from './result.js';\nimport type { Provider } from './agents/types.js';\nimport { probe, which } from './which.js';\n\nexport const MINIMUM_VERSION = '0.8.0-beta.1';\n\nconst statusSchema = z.object({\n listen: z.string().min(1),\n localDaemon: z.enum(['running', 'stopped', 'stale_pid', 'unresponsive']),\n cliVersion: z.string(),\n daemonVersion: z.string().nullable(),\n});\n\nexport interface Daemon {\n readonly url: string;\n readonly version: string;\n}\nexport interface DaemonResult {\n readonly checks: readonly Check[];\n readonly daemon?: Daemon;\n}\n\nexport function normalizeUrl(listen: string): string | undefined {\n const match = /^(?:ws:\\/\\/)?([^:/]+|\\[[^\\]]+\\]):(\\d+)$/.exec(listen.trim());\n if (!match) return undefined;\n const [, host = '', port = ''] = match;\n const local = ['localhost', '127.0.0.1', '0.0.0.0', '[::1]', '[::]'].includes(host) ? '127.0.0.1' : host;\n return `ws://${local}:${port}`;\n}\n\n/** The whole compatibility story: is Paseo running, and is it new enough? */\nexport function assessStatus(raw: unknown): DaemonResult {\n const parsed = statusSchema.safeParse(raw);\n if (!parsed.success) {\n return { checks: [fail('paseo.status', 'Paseo status output was not understood.', 'Upgrade Paseo, then run: paseo daemon status --json')] };\n }\n const status = parsed.data;\n if (status.localDaemon !== 'running') {\n return { checks: [fail('paseo.daemon', `Paseo daemon is ${status.localDaemon}.`, 'Start it with: paseo daemon start')] };\n }\n const cli = valid(status.cliVersion);\n const daemon = status.daemonVersion === null ? null : valid(status.daemonVersion);\n if (!cli || !daemon) {\n return { checks: [fail('paseo.version', 'Paseo did not report a usable version.', 'Upgrade Paseo to a release that reports semver versions.')] };\n }\n if (cli !== daemon) {\n return { checks: [fail('paseo.version', `Paseo CLI is ${cli} but the running daemon is ${daemon}.`, 'Restart the daemon with: paseo daemon restart')] };\n }\n if (!gte(daemon, MINIMUM_VERSION)) {\n return { checks: [fail('paseo.version', `Paseo ${daemon} is older than the required ${MINIMUM_VERSION}.`, 'Upgrade Paseo, then run setup again.')] };\n }\n const url = normalizeUrl(status.listen);\n if (!url) {\n return { checks: [fail('paseo.listen', `Paseo listen address ${status.listen} was not understood.`, 'Use a host:port listen address in the Paseo config.')] };\n }\n return { checks: [pass('paseo.version', `Paseo ${daemon} is running on ${url} (compatible, needs >= ${MINIMUM_VERSION}).`)], daemon: { url, version: daemon } };\n}\n\nexport async function checkDaemon(layout: Layout, env: NodeJS.ProcessEnv = process.env): Promise<DaemonResult> {\n const binary = await which(layout.bin.paseo, layout.searchPath);\n if (!binary) {\n return { checks: [fail('paseo.bin', 'Paseo executable not found.', 'Install Paseo, or pass --paseo-bin /path/to/paseo.')] };\n }\n const output = await probe(binary, ['daemon', 'status', '--json'], {\n HOME: layout.home, PASEO_HOME: layout.paseoHome, PATH: layout.searchPath,\n ...(env.PASEO_PASSWORD === undefined ? {} : { PASEO_PASSWORD: env.PASEO_PASSWORD }),\n });\n if (!output.ok) {\n return { checks: [fail('paseo.status', 'Could not read Paseo daemon status.', 'Run: paseo daemon status --json')] };\n }\n try { return assessStatus(JSON.parse(output.stdout)); }\n catch { return assessStatus(undefined); }\n}\n\nconst configSchema = z.object({ config: z.object({ providers: z.record(z.string(), z.unknown()).optional() }) });\n\nexport interface Session {\n readProviders(): Promise<Record<string, unknown>>;\n writeProviders(providers: Readonly<Record<string, Provider>>): Promise<void>;\n removeProviders(ids: readonly string[]): Promise<void>;\n refresh(ids: readonly string[]): Promise<void>;\n}\nexport type ClientFactory = (config: PaseoClientConfig) => PaseoClient;\n\n/** One connection per command. No retries, no reconnects, no background state. */\nexport async function withSession<T>(\n daemon: Daemon,\n run: (session: Session) => Promise<T>,\n options: { readonly password?: string; readonly factory?: ClientFactory } = {},\n): Promise<T> {\n const quiet = { debug() { /* silent */ }, info() { /* silent */ }, warn() { /* silent */ }, error() { /* silent */ } };\n // Loaded here so the \"Paseo is not running\" path never pays for the SDK.\n const factory = options.factory ?? (await import('@getpaseo/client')).createPaseoClient;\n const client = factory({\n url: `${daemon.url}/ws`,\n ...(options.password === undefined ? {} : { password: options.password }),\n appVersion: MINIMUM_VERSION,\n connectTimeoutMs: 10_000,\n reconnect: { enabled: false },\n logger: quiet,\n });\n try {\n await client.connect();\n return await run({\n async readProviders() {\n const response = configSchema.parse(await client.config.get());\n return response.config.providers ?? {};\n },\n async writeProviders(providers) {\n await client.config.patch({ providers } as unknown as Parameters<PaseoClient['config']['patch']>[0]);\n },\n async removeProviders(ids) {\n await client.config.patch({ removeProviders: [...ids] });\n },\n async refresh(ids) {\n await client.providers.refresh({ providers: [...ids] });\n },\n });\n } finally {\n await client.close();\n }\n}\n\n/** Compare only the keys the room owns; unrelated fields stay the operator's. */\nexport function providerMatches(desired: Provider, live: unknown): boolean {\n if (live === null || typeof live !== 'object') return false;\n const entry = live as Record<string, unknown>;\n const env = entry.env;\n const tools = entry.paseoTools;\n const same = (left: unknown, right: unknown): boolean => JSON.stringify(left ?? null) === JSON.stringify(right ?? null);\n return entry.extends === desired.extends &&\n same(entry.command, desired.command) &&\n env !== null && typeof env === 'object' &&\n Object.entries(desired.env).every(([key, value]) => (env as Record<string, unknown>)[key] === value) &&\n tools !== null && typeof tools === 'object' &&\n (tools as { enabled?: unknown }).enabled === desired.paseoTools.enabled &&\n // Pins are the room's guarantee: drifting them silently re-enables what they block.\n same(entry.params, desired.params) &&\n same(entry.disallowedTools, desired.disallowedTools);\n}\n","export const ROLES = ['supervisor', 'lead', 'peer'] as const;\nexport type Role = (typeof ROLES)[number];\n\nexport const AGENT_IDS = ['codex', 'claude'] as const;\nexport type AgentId = (typeof AGENT_IDS)[number];\n\n/** Supervisor and Lead orchestrate; Peer executes one brief and gets no room tools. */\nexport const ROLE_PASEO_TOOLS: Record<Role, boolean> = { supervisor: true, lead: true, peer: false };\n\nexport function providerId(agent: AgentId, role: Role): string {\n return `${agent}-${role}`;\n}\nexport function providerLabel(agent: AgentId, role: Role): string {\n const title = (value: string): string => value.charAt(0).toUpperCase() + value.slice(1);\n return `${title(agent)} ${title(role)}`;\n}\n","import { join } from 'node:path';\nimport { z } from 'zod';\nimport { readIfPresent } from './fsops.js';\nimport type { Layout } from './layout.js';\nimport { AGENT_IDS, ROLES, type AgentId, type Role } from './roles.js';\n\nexport const MARKER = 'room.json';\n\nconst markerSchema = z.object({\n version: z.string(),\n agents: z.array(z.enum(AGENT_IDS)).min(1),\n roles: z.array(z.enum(ROLES)).min(1),\n});\nexport type Marker = z.infer<typeof markerSchema>;\n\n/** Deterministic on purpose: re-running setup must not show a phantom change. */\nexport function renderMarker(version: string, agents: readonly AgentId[], roles: readonly Role[]): string {\n return JSON.stringify({ version, agents: [...agents], roles: [...roles] } satisfies Marker, null, 2) + '\\n';\n}\n\n/** Records what setup created, so verify and remove touch nothing else. */\nexport async function readMarker(layout: Layout): Promise<Marker | undefined> {\n const source = await readIfPresent(join(layout.roomHome, MARKER));\n if (source === undefined) return undefined;\n try { return markerSchema.parse(JSON.parse(source)); } catch { return undefined; }\n}\n","import { join } from 'node:path';\nimport { rm } from 'node:fs/promises';\nimport metadata from '../package.json' with { type: 'json' };\nimport { claudeAgent } from './agents/claude.js';\nimport { codexAgent } from './agents/codex.js';\nimport type { Agent, Provider } from './agents/types.js';\nimport { applyEntries, exists, planEntries, type Entry } from './fsops.js';\nimport { layoutChecks, resolveLayout, roleHome, sharedRoom, type Layout, type Options } from './layout.js';\nimport { checkDaemon, providerMatches, withSession, type ClientFactory, type Session } from './paseo.js';\nimport { fail, failed, hasFailure, pass, type Check, type Operation, type Result } from './result.js';\nimport { renderInstructions } from './room/instructions.js';\nimport { MARKER, readMarker, renderMarker, type Marker } from './room.js';\nimport { providerId, providerLabel, ROLES, ROLE_PASEO_TOOLS, type AgentId, type Role } from './roles.js';\n\nexport const AGENTS: Record<AgentId, Agent> = { codex: codexAgent, claude: claudeAgent };\n\nexport interface RunOptions extends Options {\n readonly agents?: readonly AgentId[];\n readonly apply?: boolean;\n readonly env?: NodeJS.ProcessEnv;\n readonly factory?: ClientFactory;\n}\n\nfunction sessionOptions(options: RunOptions): { password?: string; factory?: ClientFactory } {\n const password = (options.env ?? process.env).PASEO_PASSWORD;\n return { ...(password === undefined ? {} : { password }), ...(options.factory ? { factory: options.factory } : {}) };\n}\n\n/** The only per-agent differences are the home variable and the provider pins. */\nfunction roleProviders(layout: Layout, agent: Agent, binary: string, roles: readonly Role[]): Record<string, Provider> {\n return Object.fromEntries(roles.map(role => [providerId(agent.id, role), {\n extends: agent.id,\n label: providerLabel(agent.id, role),\n command: [binary],\n env: { [agent.homeEnv]: roleHome(layout, agent.id, role) },\n paseoTools: { enabled: ROLE_PASEO_TOOLS[role] },\n ...agent.pins,\n }]));\n}\n\ninterface Desired {\n readonly entries: readonly Entry[];\n readonly providers: Readonly<Record<string, Provider>>;\n readonly checks: readonly Check[];\n}\nasync function buildDesired(layout: Layout, agents: readonly AgentId[], roles: readonly Role[]): Promise<Desired> {\n // Template, not linked into any seat: each repo owns its own docs/WORKSPACE_PROTOCOL.md.\n // Named exactly as RC-002 names it, so a copy needs no rename.\n const entries: Entry[] = [\n { kind: 'dir', path: layout.roomHome },\n { kind: 'dir', path: sharedRoom(layout) },\n { kind: 'file', path: join(sharedRoom(layout), 'WORKSPACE_PROTOCOL.md'), content: renderInstructions('workspace') },\n ];\n const providers: Record<string, Provider> = {};\n const checks: Check[] = [];\n for (const id of agents) {\n const agent = AGENTS[id];\n const plan = await agent.build(layout, roles);\n entries.push(...plan.entries);\n checks.push(...plan.checks);\n if (plan.binary !== undefined) Object.assign(providers, roleProviders(layout, agent, plan.binary, roles));\n }\n entries.push({ kind: 'file', path: join(layout.roomHome, MARKER), content: renderMarker(metadata.version, agents, roles) });\n return { entries, providers, checks };\n}\n\ninterface Stale {\n readonly providerIds: readonly string[];\n readonly directories: readonly string[];\n}\nconst NOTHING_STALE: Stale = { providerIds: [], directories: [] };\n\n/** A previous setup may have seated agents or roles this one does not: drop those. */\nasync function staleFrom(layout: Layout, previous: Marker | undefined, agents: readonly AgentId[], roles: readonly Role[]): Promise<Stale> {\n if (!previous) return NOTHING_STALE;\n const kept = new Set(agents.flatMap(agent => roles.map(role => providerId(agent, role))));\n const providerIds: string[] = [];\n const directories: string[] = [];\n for (const agent of previous.agents) {\n for (const role of previous.roles) {\n if (kept.has(providerId(agent, role))) continue;\n providerIds.push(providerId(agent, role));\n const path = roleHome(layout, agent, role);\n if (await exists(path)) directories.push(path);\n }\n }\n return { providerIds, directories };\n}\n\n/** One definition of drift, shared by the command that fixes it and the one that reports it. */\nasync function planRoom(session: Session, desired: Desired, stale: Stale): Promise<Operation[]> {\n const live = await session.readProviders();\n return [\n ...await planEntries(desired.entries),\n ...Object.entries(desired.providers).map(([id, provider]) => ({\n action: !(id in live) ? 'create' : providerMatches(provider, live[id]) ? 'noop' : 'update',\n kind: 'provider',\n target: id,\n }) satisfies Operation),\n ...stale.providerIds.filter(id => id in live).map(id => ({ action: 'remove', kind: 'provider', target: id }) satisfies Operation),\n ...stale.directories.map(path => ({ action: 'remove', kind: 'dir', target: path }) satisfies Operation),\n ];\n}\n\n/** The whole product: write the role homes, then register them with Paseo. */\nexport async function setup(options: RunOptions = {}): Promise<Result> {\n const layout = resolveLayout(options, options.env);\n const agents = options.agents ?? ['codex'];\n const invalid = layoutChecks(layout, agents);\n if (invalid.length > 0) return failed('setup', invalid);\n const daemon = await checkDaemon(layout, options.env);\n if (!daemon.daemon) return failed('setup', daemon.checks);\n const desired = await buildDesired(layout, agents, ROLES);\n const checks = [...daemon.checks, ...desired.checks];\n if (hasFailure(checks)) return failed('setup', checks);\n const stale = await staleFrom(layout, await readMarker(layout), agents, ROLES);\n\n return withSession(daemon.daemon, async session => {\n const operations = await planRoom(session, desired, stale);\n const pending = operations.filter(operation => operation.action !== 'noop');\n if (!options.apply) {\n return {\n command: 'setup', outcome: pending.length > 0 ? 'changes-planned' : 'ok', changed: false, checks, operations,\n } satisfies Result;\n }\n await applyEntries(desired.entries);\n for (const path of stale.directories) await rm(path, { recursive: true, force: true });\n const ids = Object.keys(desired.providers);\n await session.writeProviders(desired.providers);\n if (stale.providerIds.length > 0) await session.removeProviders(stale.providerIds);\n await session.refresh(ids);\n return {\n command: 'setup', outcome: 'ok', changed: pending.length > 0,\n checks: [...checks, pass('room.applied', `Room ready at ${layout.roomHome} with ${String(ids.length)} Paseo providers.`)],\n operations,\n } satisfies Result;\n }, sessionOptions(options));\n}\n\nexport async function verify(options: RunOptions = {}): Promise<Result> {\n const layout = resolveLayout(options, options.env);\n const marker = await readMarker(layout);\n if (!marker) {\n return failed('verify', [fail('room.marker', `No room found at ${layout.roomHome}.`, 'Run: paseo-room setup --apply')]);\n }\n const invalid = layoutChecks(layout, marker.agents);\n if (invalid.length > 0) return failed('verify', invalid);\n const daemon = await checkDaemon(layout, options.env);\n if (!daemon.daemon) return failed('verify', daemon.checks);\n const desired = await buildDesired(layout, marker.agents, marker.roles);\n const checks = [...daemon.checks, ...desired.checks];\n if (hasFailure(checks)) return failed('verify', checks);\n\n return withSession(daemon.daemon, async session => {\n const operations = await planRoom(session, desired, NOTHING_STALE);\n const drifted = operations.filter(operation => operation.action !== 'noop');\n const providers = drifted.filter(operation => operation.kind === 'provider').length;\n const files = drifted.length - providers;\n const all: Check[] = [...checks,\n files === 0\n ? pass('room.files', 'Every managed role file matches the current definition.')\n : fail('room.files', `${String(files)} managed role files are missing or outdated.`, 'Run: paseo-room setup --apply'),\n providers === 0\n ? pass('room.providers', `All ${String(Object.keys(desired.providers).length)} Paseo providers are registered as expected.`)\n : fail('room.providers', `${String(providers)} Paseo providers are missing or differ.`, 'Run: paseo-room setup --apply'),\n ];\n return {\n command: 'verify', outcome: hasFailure(all) ? 'failed' : 'ok', changed: false, checks: all, operations,\n } satisfies Result;\n }, sessionOptions(options));\n}\n\nexport async function remove(options: RunOptions = {}): Promise<Result> {\n const layout = resolveLayout(options, options.env);\n const marker = await readMarker(layout);\n if (!marker) {\n return failed('remove', [fail('room.marker', `No room found at ${layout.roomHome}.`, 'Nothing to remove; the room home was never created here.')]);\n }\n // A recursive delete needs a floor, so the layout rules gate this command too.\n const invalid = layoutChecks(layout, marker.agents);\n if (invalid.length > 0) return failed('remove', invalid);\n const ids = marker.agents.flatMap(agent => marker.roles.map(role => providerId(agent, role)));\n const operations: Operation[] = [\n ...ids.map(id => ({ action: 'remove', kind: 'provider', target: id }) satisfies Operation),\n { action: 'remove', kind: 'dir', target: layout.roomHome },\n ];\n if (!options.apply) {\n return { command: 'remove', outcome: 'changes-planned', changed: false, checks: [], operations };\n }\n const daemon = await checkDaemon(layout, options.env);\n const checks: Check[] = [];\n if (daemon.daemon) {\n await withSession(daemon.daemon, session => session.removeProviders(ids), sessionOptions(options));\n checks.push(pass('room.providers', `Removed ${String(ids.length)} Paseo providers.`));\n } else {\n checks.push({ id: 'room.providers', status: 'warn', message: 'Paseo is unreachable; provider entries were left in place.', fix: 'Start Paseo and run remove again to clear them.' });\n }\n // Only the room home is deleted; agent homes were never written to.\n await rm(layout.roomHome, { recursive: true, force: true });\n checks.push(pass('room.files', `Deleted ${layout.roomHome}.`));\n return { command: 'remove', outcome: 'ok', changed: true, checks, operations };\n}\n","import * as clack from '@clack/prompts';\nimport { AGENTS, remove, setup, verify, type RunOptions } from './commands.js';\nimport type { Result } from './result.js';\nimport { AGENT_IDS, type AgentId } from './roles.js';\n\nexport interface Prompts {\n select(options: { readonly message: string; readonly options: readonly { readonly value: string; readonly label: string }[] }): Promise<string | symbol>;\n multiselect(options: { readonly message: string; readonly options: readonly { readonly value: AgentId; readonly label: string }[] }): Promise<AgentId[] | symbol>;\n confirm(options: { readonly message: string }): Promise<boolean | symbol>;\n}\nexport const terminalPrompts: Prompts = {\n select: options => clack.select({ message: options.message, options: [...options.options] }),\n multiselect: options => clack.multiselect({ message: options.message, options: [...options.options], required: true }),\n confirm: options => clack.confirm({ message: options.message, initialValue: false }),\n};\n\n/** Guided path over the same commands the flags use; nothing extra happens here. */\nexport async function runWizard(\n prompts: Prompts,\n emit: (result: Result) => number,\n write: (text: string) => void,\n options: RunOptions = {},\n): Promise<number> {\n const cancelled = (): number => { write('Cancelled; nothing was changed.\\n'); return 0; };\n const action = await prompts.select({\n message: 'What do you want to do?',\n options: [\n { value: 'setup', label: 'Set up / update the room' },\n { value: 'verify', label: 'Verify the current room' },\n { value: 'remove', label: 'Remove the room' },\n ],\n });\n if (typeof action === 'symbol') return cancelled();\n if (action === 'verify') return emit(await verify(options));\n if (action === 'remove') {\n const preview = await remove(options);\n const status = emit(preview);\n if (preview.outcome !== 'changes-planned') return status;\n const approved = await prompts.confirm({ message: 'Delete the room home and its Paseo providers?' });\n return approved === true ? emit(await remove({ ...options, apply: true })) : cancelled();\n }\n const agents = await prompts.multiselect({\n message: 'Which coding agents should the room use?',\n options: AGENT_IDS.map(value => ({ value, label: AGENTS[value].label })),\n });\n if (typeof agents === 'symbol' || agents.length === 0) return cancelled();\n const preview = await setup({ ...options, agents });\n const status = emit(preview);\n if (preview.outcome !== 'changes-planned') return status;\n const approved = await prompts.confirm({ message: 'Apply these changes?' });\n if (approved !== true) return cancelled();\n return emit(await setup({ ...options, agents, apply: true }));\n}\n","import { Command, CommanderError } from 'commander';\nimport metadata from '../package.json' with { type: 'json' };\nimport { remove, setup, verify, type RunOptions } from './commands.js';\nimport { renderHuman, renderJson } from './render.js';\nimport { exitCode, fail, failed, type Result } from './result.js';\nimport { AGENT_IDS, type AgentId } from './roles.js';\nimport type { Prompts } from './wizard.js';\n\nexport interface Output {\n readonly stdout: (text: string) => void;\n readonly stderr: (text: string) => void;\n}\nexport interface CliContext {\n readonly isTTY?: boolean;\n readonly prompts?: Prompts;\n readonly options?: RunOptions;\n}\n\n/** Commander passes no initial value, so the first call starts the list. */\nfunction collectAgent(value: string, previous: AgentId[] | undefined): AgentId[] {\n const agent = AGENT_IDS.find(id => id === value);\n if (!agent) throw new CommanderError(2, 'agent', `Unknown agent: ${value}`);\n const seated = previous ?? [];\n return seated.includes(agent) ? seated : [...seated, agent];\n}\n\nconst PATH_FLAGS = ['roomHome', 'codexHome', 'claudeHome', 'codexBin', 'claudeBin', 'paseoBin'] as const;\n\nfunction optionsFrom(raw: Record<string, unknown>, base: RunOptions): RunOptions {\n const paths: Record<string, string> = {};\n for (const flag of PATH_FLAGS) {\n const value = raw[flag];\n if (typeof value === 'string' && value.trim()) paths[flag] = value.trim();\n }\n const agents = Array.isArray(raw.agent) && raw.agent.length > 0 ? (raw.agent as AgentId[]) : undefined;\n return { ...base, ...paths, ...(agents ? { agents } : {}), ...(raw.apply === true ? { apply: true } : {}) };\n}\n\nexport async function runCli(argv: readonly string[], output: Output, context: CliContext = {}): Promise<number> {\n const password = (context.options?.env ?? process.env).PASEO_PASSWORD;\n const redact = (text: string): string => (password ? text.split(password).join('[redacted]') : text);\n // Set once the flags are parsed; the wizard path never sees flags, so text output is right there.\n let json = false;\n const emit = (result: Result): number => {\n output.stdout(redact(json ? renderJson(result) : renderHuman(result)));\n return exitCode(result);\n };\n const isTTY = context.isTTY ?? (process.stdin.isTTY && process.stdout.isTTY);\n const base = context.options ?? {};\n\n if (argv.length === 0) {\n if (!isTTY) {\n output.stderr('paseo-room: no command given. Try: paseo-room setup, verify, remove, or --help.\\n');\n return 2;\n }\n // @clack/prompts is only reachable here, so keep it off the scripted path.\n const { runWizard, terminalPrompts } = await import('./wizard.js');\n return runWizard(context.prompts ?? terminalPrompts, emit, text => { output.stdout(text); }, base);\n }\n\n const program = new Command()\n .name('paseo-room')\n .description('Configure Codex/Claude role homes in $HOME and register them with your local Paseo daemon.')\n .version(metadata.version)\n .argument('<command>', 'setup | verify | remove')\n .option('--agent <agent>', 'codex or claude; repeat for both (default: codex)', collectAgent)\n .option('--apply', 'actually make the changes (default: dry run)')\n .option('--json', 'machine-readable output')\n .option('--room-home <path>', 'where role homes are written (default: ~/.paseo-room)')\n .option('--codex-home <path>', 'source Codex config (default: ~/.codex)')\n .option('--claude-home <path>', 'source Claude Code config (default: ~/.claude)')\n .option('--codex-bin <path>', 'Codex executable (default: found on PATH)')\n .option('--claude-bin <path>', 'Claude Code executable (default: found on PATH)')\n .option('--paseo-bin <path>', 'Paseo executable (default: found on PATH)')\n .configureOutput({ writeOut: text => { output.stdout(text); }, writeErr: text => { output.stderr(text); } })\n .exitOverride();\n\n let command: string;\n let options: RunOptions;\n try {\n program.parse([...argv], { from: 'user' });\n const raw = program.opts<Record<string, unknown>>();\n json = raw.json === true;\n command = program.args[0] ?? '';\n options = optionsFrom(raw, base);\n } catch (error) {\n if (error instanceof CommanderError && error.exitCode === 0) return 0;\n return 2;\n }\n\n try {\n if (command === 'setup') return emit(await setup(options));\n if (command === 'verify') return emit(await verify(options));\n if (command === 'remove') return emit(await remove(options));\n } catch (error) {\n const detail = error instanceof Error ? error.message : 'unknown error';\n return emit(failed(command, [fail(`${command}.error`, redact(detail), 'Check that Paseo is running and reachable, then try again.')]));\n }\n output.stderr(`paseo-room: unknown command \"${command}\". Try: setup, verify, remove.\\n`);\n return 2;\n}\n","import type { Result } from './result.js';\n\nexport function renderJson(result: Result): string {\n return `${JSON.stringify({ schemaVersion: 2, ...result }, null, 2)}\\n`;\n}\n\nconst ICONS = { pass: '✓', warn: '!', fail: '✗' } as const;\n\nexport function renderHuman(result: Result): string {\n const lines: string[] = [];\n for (const check of result.checks) {\n lines.push(`${ICONS[check.status]} ${check.message}`);\n if (check.fix) lines.push(` → ${check.fix}`);\n }\n const changes = result.operations.filter(operation => operation.action !== 'noop');\n if (changes.length > 0) {\n lines.push('', result.changed ? 'Applied:' : 'Planned changes:');\n for (const operation of changes) lines.push(` ${operation.action} ${operation.kind} ${operation.target}`);\n const unchanged = result.operations.length - changes.length;\n if (unchanged > 0) lines.push(` (${String(unchanged)} already up to date)`);\n } else if (result.operations.length > 0) {\n lines.push('', 'Everything is already up to date.');\n }\n lines.push('', `${result.command}: ${result.outcome}`);\n return `${lines.join('\\n')}\\n`;\n}\n","#!/usr/bin/env node\nimport { runCli } from './cli.js';\n\nprocess.exitCode = await runCli(process.argv.slice(2), {\n stdout: text => { process.stdout.write(text); },\n stderr: text => { process.stderr.write(text); },\n});\n"],"mappings":"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","names":["join","join","resolve","join","basename","join","SHARED","run","join","z","join","rm","preview","status","approved","runWizard","terminalPrompts"]}
1
+ {"version":3,"sources":["../package.json","../src/result.ts","../src/layout.ts","../src/fsops.ts","../src/room/clauses.ts","../src/room/workspace.ts","../src/room/instructions.ts","../src/which.ts","../src/agents/claude.ts","../src/agents/codex.ts","../src/paseo.ts","../src/roles.ts","../src/room.ts","../src/commands.ts","../src/wizard.ts","../src/cli.ts","../src/render.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"paseo-room\",\n \"version\": \"0.1.0-alpha.4\",\n \"description\": \"One CLI that configures Codex/Claude role homes in $HOME and registers them with your local Paseo daemon.\",\n \"keywords\": [\n \"paseo\",\n \"codex\",\n \"claude-code\",\n \"agent\",\n \"orchestration\",\n \"cli\"\n ],\n \"homepage\": \"https://github.com/cuongntr/paseo-room#readme\",\n \"bugs\": \"https://github.com/cuongntr/paseo-room/issues\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/cuongntr/paseo-room.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Invoker <cuongnt1987@gmail.com>\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=22\"\n },\n \"bin\": {\n \"paseo-room\": \"dist/index.js\"\n },\n \"files\": [\n \"dist/\"\n ],\n \"scripts\": {\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint . --max-warnings 0\",\n \"test\": \"vitest run\",\n \"build\": \"tsup\",\n \"prepack\": \"npm run build\",\n \"verify\": \"npm run typecheck && npm run lint && npm test && npm run build\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.8.0\",\n \"@getpaseo/client\": \"0.8.0-beta.1\",\n \"commander\": \"^14.0.3\",\n \"semver\": \"^7.8.5\",\n \"smol-toml\": \"^1.8.0\",\n \"zod\": \"^4.5.4\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@types/node\": \"^22.0.0\",\n \"@types/semver\": \"^7.7.0\",\n \"eslint\": \"^10.10.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"~5.9.3\",\n \"typescript-eslint\": \"^8.70.0\",\n \"vitest\": \"^4.1.11\"\n }\n}\n","export type Status = 'pass' | 'warn' | 'fail';\nexport interface Check {\n readonly id: string;\n readonly status: Status;\n readonly message: string;\n readonly fix?: string;\n}\nexport interface Operation {\n readonly action: 'create' | 'update' | 'remove' | 'noop';\n readonly kind: 'dir' | 'file' | 'link' | 'provider' | 'profile';\n readonly target: string;\n}\nexport type Outcome = 'ok' | 'changes-planned' | 'failed';\nexport interface Result {\n readonly command: string;\n readonly outcome: Outcome;\n readonly changed: boolean;\n readonly checks: readonly Check[];\n readonly operations: readonly Operation[];\n}\n\nexport function pass(id: string, message: string): Check {\n return { id, status: 'pass', message };\n}\nexport function fail(id: string, message: string, fix: string): Check {\n return { id, status: 'fail', message, fix };\n}\nexport function failed(command: string, checks: readonly Check[]): Result {\n return { command, outcome: 'failed', changed: false, checks, operations: [] };\n}\nexport function hasFailure(checks: readonly Check[]): boolean {\n return checks.some(check => check.status === 'fail');\n}\nexport function exitCode(result: Result): number {\n return result.outcome === 'failed' || hasFailure(result.checks) ? 1 : 0;\n}\n","import { homedir } from 'node:os';\nimport { join, resolve, sep } from 'node:path';\nimport { fail, type Check } from './result.js';\nimport type { AgentId, Role } from './roles.js';\n\nexport interface Options {\n readonly roomHome?: string;\n readonly codexHome?: string;\n readonly claudeHome?: string;\n readonly codexBin?: string;\n readonly claudeBin?: string;\n readonly paseoBin?: string;\n}\nexport interface Layout {\n readonly home: string;\n readonly roomHome: string;\n readonly paseoHome: string;\n readonly agentHome: Record<AgentId, string>;\n /** Claude keeps legacy default state beside ~/.claude, but custom config state inside it. */\n readonly claudeState: string;\n readonly bin: Record<AgentId | 'paseo', string>;\n /** The PATH executables are looked up on. Resolved here so nothing reaches for process.env. */\n readonly searchPath: string;\n}\n\nfunction pick(...candidates: readonly (string | undefined)[]): string {\n for (const candidate of candidates) if (candidate?.trim()) return candidate.trim();\n throw new Error('Could not determine HOME; pass explicit --room-home and --codex-home/--claude-home paths.');\n}\n\n/** Everything is derived from HOME; flags and environment only override defaults. */\nexport function resolveLayout(options: Options = {}, env: NodeJS.ProcessEnv = process.env): Layout {\n const home = pick(env.HOME, homedir());\n const claudeOverride = options.claudeHome?.trim() || env.CLAUDE_CONFIG_DIR?.trim() || undefined;\n const claudeHome = resolve(pick(claudeOverride, join(home, '.claude')));\n // Relative overrides resolve against the working directory, as a CLI flag should.\n return {\n home,\n roomHome: resolve(pick(options.roomHome, env.PASEO_ROOM_HOME, join(home, '.paseo-room'))),\n paseoHome: resolve(pick(env.PASEO_HOME, join(home, '.paseo'))),\n agentHome: {\n codex: resolve(pick(options.codexHome, env.CODEX_HOME, join(home, '.codex'))),\n claude: claudeHome,\n },\n claudeState: claudeOverride?.trim() ? join(claudeHome, '.claude.json') : join(home, '.claude.json'),\n bin: {\n codex: pick(options.codexBin, env.CODEX_BIN, 'codex'),\n claude: pick(options.claudeBin, env.CLAUDE_BIN, 'claude'),\n paseo: pick(options.paseoBin, env.PASEO_BIN, 'paseo'),\n },\n searchPath: env.PATH ?? '',\n };\n}\n\n/** True when `path` is the root itself or sits underneath it. */\nexport function contains(root: string, path: string): boolean {\n return path === root || path.startsWith(root.endsWith(sep) ? root : root + sep);\n}\n\n/** The room home must own its directory: no overlap with $HOME or a source agent home. */\nexport function layoutChecks(layout: Layout, agents: readonly AgentId[]): Check[] {\n const checks: Check[] = [];\n if (contains(layout.roomHome, layout.home)) {\n checks.push(fail('room.home', `Refusing to use ${layout.roomHome} as the room home: it contains your home directory.`,\n 'Point --room-home at a dedicated directory, by default ~/.paseo-room.'));\n }\n for (const id of agents) {\n const home = layout.agentHome[id];\n if (contains(layout.roomHome, home) || contains(home, layout.roomHome)) {\n checks.push(fail(`${id}.home`, `The ${id} home ${home} overlaps the room home ${layout.roomHome}.`,\n `Pass --${id}-home pointing at your own ${id} configuration (this happens when setup runs inside a room seat).`));\n }\n }\n return checks;\n}\n\nexport function roleHome(layout: Layout, agent: AgentId, role: Role): string {\n return join(layout.roomHome, 'roles', agent, role);\n}\nexport function sharedRoom(layout: Layout): string {\n return join(layout.roomHome, 'room');\n}\n","import { chmod, lstat, mkdir, readFile, readlink, rm, symlink, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport type { Operation } from './result.js';\n\nexport type Entry =\n | { readonly kind: 'dir'; readonly path: string }\n /** `once` writes the file only when absent: runtime state the agent owns after setup. */\n | { readonly kind: 'file'; readonly path: string; readonly content: string; readonly once?: true }\n | { readonly kind: 'link'; readonly path: string; readonly target: string };\n\nconst DIR_MODE = 0o700;\nconst FILE_MODE = 0o600;\n\nasync function current(entry: Entry): Promise<'absent' | 'same' | 'different'> {\n let stat;\n try { stat = await lstat(entry.path); } catch { return 'absent'; }\n if (entry.kind === 'dir') return stat.isDirectory() ? 'same' : 'different';\n if (entry.kind === 'link') {\n if (!stat.isSymbolicLink()) return 'different';\n return await readlink(entry.path) === entry.target ? 'same' : 'different';\n }\n if (!stat.isFile()) return 'different';\n if (entry.once) return 'same';\n return await readFile(entry.path, 'utf8') === entry.content ? 'same' : 'different';\n}\n\n/** Everything lives under the room home, which this CLI owns outright. */\nexport async function planEntries(entries: readonly Entry[]): Promise<Operation[]> {\n const operations: Operation[] = [];\n for (const entry of entries) {\n const state = await current(entry);\n operations.push({\n action: state === 'same' ? 'noop' : state === 'absent' ? 'create' : 'update',\n kind: entry.kind,\n target: entry.path,\n });\n }\n return operations;\n}\n\n/** Rewrites only what differs, so a repeat run costs stats rather than writes. */\nexport async function applyEntries(entries: readonly Entry[]): Promise<void> {\n for (const entry of entries) {\n if (await current(entry) === 'same') continue;\n if (entry.kind === 'dir') {\n await mkdir(entry.path, { recursive: true, mode: DIR_MODE });\n continue;\n }\n await mkdir(dirname(entry.path), { recursive: true, mode: DIR_MODE });\n await rm(entry.path, { force: true, recursive: true });\n if (entry.kind === 'link') await symlink(entry.target, entry.path);\n else {\n await writeFile(entry.path, entry.content, { mode: FILE_MODE });\n await chmod(entry.path, FILE_MODE);\n }\n }\n}\n\nexport async function exists(path: string): Promise<boolean> {\n try { await lstat(path); return true; } catch { return false; }\n}\n\n/** Which of `names` exist under `home`, probed once for all roles that share them. */\nexport async function existingPaths(home: string, names: readonly string[]): Promise<string[]> {\n const paths = names.map(name => join(home, name));\n const present = await Promise.all(paths.map(exists));\n return paths.filter((_, index) => present[index] === true);\n}\n\nexport async function readIfPresent(path: string): Promise<string | undefined> {\n try { return await readFile(path, 'utf8'); } catch { return undefined; }\n}\n","/**\n * The room's authority contract, in the wording the agents actually read.\n *\n * Write each statement as ordinary wrapped prose. Blank lines separate\n * statements; line breaks inside a statement are just there for reading and\n * collapse into single spaces when rendered.\n */\nexport function clause(source: string): readonly string[] {\n return source\n .trim()\n .split(/\\n\\s*\\n/)\n .map(statement => statement.split('\\n').map(line => line.trim()).join(' '));\n}\n\nexport const CLAUSES = {\n 'RC-001': clause(`\n Human owns product goals, priority, material-cost choices, external effects, and\n irreversible-risk decisions. No agent may take ownership of these decisions; obtain\n Human approval before crossing those boundaries.\n\n Human may direct the technical route, decomposition, and lifecycle, and may override\n an acceptance decision. Human does not normally operate the agent protocol.\n `),\n\n 'RC-002': clause(`\n A workspace protocol governs repository-local workflow: topology, verification\n commands, review rhythm, escalation routes, and project conventions. The room ships a\n default, and the part of it that bears on this role is reproduced at the end of this\n document. That default is in force wherever the repository says nothing.\n\n When the repository provides docs/WORKSPACE_PROTOCOL.md, read the parts that bear on\n your own work and follow them wherever they speak to a point. A repository rule wins\n over the default on that point; the default still holds everywhere the repository is\n silent.\n\n Neither the default nor a repository file can weaken this authority contract. No\n protocol can give Peer orchestration, give Supervisor or Peer technical acceptance,\n permit multiple writable Peers, or transfer Human decisions to an agent.\n `),\n\n 'RC-003': clause(`\n Use tests, artifacts, lifecycle states, and completion/error/attention events as\n evidence, not as automatic authorization or acceptance.\n\n Wait for state-changing events when progress depends on another actor. Do not\n repeatedly poll unchanged state; resume when new evidence or a relevant event arrives.\n `),\n\n 'RC-004': clause(`\n Preserve unrelated work. Stay within the granted repository scope and external-action\n authority; do not treat access to a tool as permission to expand either boundary.\n `),\n\n 'RC-101': clause(`\n Supervisor routes the Human directive to Lead without changing its outcome, requested\n output, constraints, or approval gates. Label added context separately; it must not\n rewrite the directive.\n `),\n\n 'RC-102': clause(`\n Supervisor observes technical work rather than choosing architecture, decomposing\n work, or moving write ownership. Prefer routing work through Lead.\n\n Supervisor must not edit project work, run project validation, or decide technical\n acceptance. Supervisor must not direct Peer while Lead is healthy; an unhealthy Lead\n calls for bounded recovery or escalation, not taking over Peer work.\n `),\n\n 'RC-103': clause(`\n Supervisor has Paseo tools enabled solely within its authority. Use the smallest Paseo\n room/session lifecycle action needed for an explicit Human request or bounded room\n recovery; preserve current ownership and inform Lead of every change.\n\n Before opening a Lead, Supervisor checks whether a healthy Lead already owns the project\n by inspecting its current and recent agents. An initializing or running Lead, an idle\n Lead after a completed turn, and a closed but unarchived, resumable Lead are the same\n project owner: route the directive, question, evidence, or review request to that Lead,\n resuming it when necessary. A pending creation, run, or permission request is unresolved\n state, not an absent Lead; wait for a state-changing event. Resolve a permission only\n within authority already granted by Human, and otherwise escalate it to Human.\n\n Only when no Lead owns the project may Supervisor open exactly one Lead as its child and\n route the Human directive to it. Workspace placement does not change parentage. Of the\n seats available, Supervisor opens Lead seats only; opening Peer seats is Lead's, and\n opening another Supervisor is Human's. Reuse the project Lead and never open another Lead\n for freshness or convenience.\n\n A fresh-session review is Lead's to arrange with a fresh read-only Peer against a stable\n candidate. Route that request to the existing Lead; freshness applies to the review Peer\n and is not a reason for Supervisor to open a fresh Lead or direct the Peer.\n\n If duplicate Leads exist, stop new parallel routing and preserve both timelines and\n artifacts. Keep the previously established healthy Lead as project owner, route the\n duplicate's stable handoff and evidence to it, and close the duplicate only after moving\n work has stopped and a stable handoff exists. If prior ownership, health, or concurrent\n writes are ambiguous, escalate to Human instead of choosing, merging, accepting, or\n directing a Peer.\n `),\n\n 'RC-104': clause(`\n Supervisor sends technical questions and evidence to Lead. Escalate product, priority,\n material-cost, external-effect, and irreversible-risk choices to Human rather than\n deciding them.\n `),\n\n 'RC-201': clause(`\n Lead owns project framing, architecture, dependencies, integration, verification, and\n technical acceptance within Human boundaries. Lead executes the Human outcome and\n constraints, escalating Human-owned choices to Human.\n\n Lead owns one project across turns. A completed turn, idle state, or closed but unarchived,\n resumable session does not end that ownership; it ends only when Human closes or reassigns\n the project, or bounded recovery replaces an unhealthy Lead after a stable handoff.\n\n Lead has Paseo tools enabled to manage project agents and direct Peer; this capability\n does not expand project or external-action authority.\n `),\n\n 'RC-202': clause(`\n Lead owns decomposition and moving write-scope assignment: give each moving scope\n exactly one owner, with at most one active writable Peer across the project at a time.\n Lead must not edit a scope concurrently with its writing Peer.\n\n Before transferring write ownership, stop the prior writer and establish a stable\n handoff. Read-only review does not create another writer.\n `),\n\n 'RC-203': clause(`\n Before delegation, Lead supplies a complete Peer brief: one bounded outcome,\n prerequisites, explicit write scope or read-only mode, stable contract and invariants,\n required acceptance evidence, and conditions that reopen the decision.\n `),\n\n 'RC-204': clause(`\n Lead permits independent Peer judgment: REOPEN_REQUEST challenges a premise;\n DEPENDENCY_REQUEST asks for an unowned prerequisite; BLOCKED reports that no safe\n progress is possible.\n\n For each signal, Peer provides evidence, consequence, and the needed decision or\n dependency. Lead resolves technical signals or escalates Human-owned choices; Peer\n must not seize unowned work while waiting.\n `),\n\n 'RC-205': clause(`\n Lead inspects the exact candidate or a deterministic snapshot and explicitly accepts\n or rejects it with a technical reason. Passing tests and completion reports are\n evidence, not acceptance. Among agents, Lead alone accepts; Human retains override\n authority.\n `),\n\n 'RC-206': clause(`\n When material uncertainty warrants independent review, Lead may dispatch a fresh\n read-only Peer with an exact stable candidate and a bounded question. Review is\n optional: do not introduce a dedicated reviewer role or a fixed reviewer count.\n\n The fresh session is the review Peer's session, never a replacement or duplicate project\n Lead. Lead remains the owner, receives the review evidence, inspects the exact candidate,\n and makes the technical acceptance decision.\n `),\n\n 'RC-207': clause(`\n Lead opens Peer seats and no others. A seat list may offer Lead and Supervisor seats;\n opening one creates a second orchestrator or inverts the Human-facing seat, so Lead\n must not, whatever the tool permits.\n\n Open each Peer on the same agent implementation as this seat unless the workspace\n protocol routes that kind of work elsewhere. A Peer belongs to one brief: close it when\n the brief closes rather than holding a standing pool.\n `),\n\n 'RC-301': clause(`\n Peer owns exactly one Lead-delegated bounded outcome and proportionate evidence. Do\n not add adjacent tasks; send technical questions to Lead and escalate Human-owned\n choices through Lead.\n `),\n\n 'RC-302': clause(`\n A writing Peer owns only its assigned moving write scope. A review Peer stays\n read-only and inspects only the named candidate or snapshot, without changing project\n files or the candidate.\n `),\n\n 'RC-303': clause(`\n Peer must not spawn, manage, coordinate, or infer room topology, direct another Peer,\n or perform Paseo room/session lifecycle operations. Peer receives no Paseo tools;\n enabled is false. This capability boundary is not an operating-system sandbox.\n `),\n\n 'RC-304': clause(`\n Peer hands off a candidate by naming an immutable commit or deterministic snapshot,\n the original base, all changed paths, verification performed and its results, and\n residual risk. Make the candidate reproducible for Lead inspection.\n `),\n\n 'RC-305': clause(`\n Peer must not self-accept any work, including difficult work. Peer tests and\n completion are evidence only; Lead alone performs technical acceptance among agents,\n subject to Human override.\n `),\n};\n\nexport type RoleContractId = keyof typeof CLAUSES;\nexport const SHARED_IDS = ['RC-001', 'RC-002', 'RC-003', 'RC-004'] as const;\n","/**\n * The room's default workspace protocol: the repository-local layer of the model,\n * in the wording the seats actually read.\n *\n * It ships in force, not as something to copy. A repository that needs different\n * rules writes its own docs/WORKSPACE_PROTOCOL.md, which wins wherever it speaks\n * (RC-002).\n *\n * Keep every statement here workflow, and keep it new. Authority belongs in\n * clauses.ts: restating a clause here teaches the seat nothing and blurs the\n * boundary the two layers depend on. Anything true of only one project belongs in\n * that project's own file.\n */\nimport { clause } from './clauses.js';\n\nexport const DEFAULT_PROTOCOL = {\n 'WP-01 Topology': clause(`\n Match the shape of the work to its difficulty. A change Lead can make correctly in one\n sitting is made by Lead, without a Peer: delegation costs a brief, a handoff and a\n review, and a trivial change does not repay them.\n\n When the route itself is uncertain, spend a read-only Peer on the question before\n spending a writable Peer on the answer.\n\n When seats from more than one agent implementation are available, a second\n implementation is worth most as an independent reader of a candidate the first one\n wrote. Absent a repository rule assigning work by kind, keep a task on the\n implementation of the seat that opened it.\n `),\n\n 'WP-02 Verification': clause(`\n The repository's own gate is the evidence. Lead names the exact command in the brief;\n Peer runs it and reports the result as it came back, failures included. A candidate\n whose gate was not run is not a candidate.\n\n Do not report part of the gate as the whole of it, and do not report work as done while\n any part of it is unrun.\n `),\n\n 'WP-03 Review': clause(`\n Review runs in a fresh session rather than a continuation of the writer's. A session\n that produced the work cannot be surprised by it.\n `),\n\n 'WP-04 Repository conventions': clause(`\n Follow the conventions already visible in the files being changed rather than importing\n a different house style alongside them.\n\n Do not add top-level files, directories, dependencies or tooling the brief did not ask\n for. A repository that wants them will say so in its own protocol.\n `),\n};\n\nexport type ProtocolId = keyof typeof DEFAULT_PROTOCOL;\n","import type { Role } from '../roles.js';\nimport { CLAUSES, SHARED_IDS, type RoleContractId } from './clauses.js';\nimport { DEFAULT_PROTOCOL, type ProtocolId } from './workspace.js';\n\nexport type InstructionKind = Role | 'workspace';\n\nconst ROLE_IDS: Record<Role, readonly RoleContractId[]> = {\n supervisor: ['RC-101', 'RC-102', 'RC-103', 'RC-104'],\n lead: ['RC-201', 'RC-202', 'RC-203', 'RC-204', 'RC-205', 'RC-206', 'RC-207'],\n // Peer needs the challenge protocol as well as its own numbered obligations.\n peer: ['RC-204', 'RC-301', 'RC-302', 'RC-303', 'RC-304', 'RC-305'],\n};\n\n// Topology is Lead's decision and Supervisor's to audit. RC-303 forbids Peer to\n// infer room topology, so handing Peer the topology rules would contradict its\n// own contract.\nconst PROTOCOL_IDS: Record<Role, readonly ProtocolId[]> = {\n supervisor: ['WP-01 Topology', 'WP-02 Verification', 'WP-03 Review', 'WP-04 Repository conventions'],\n lead: ['WP-01 Topology', 'WP-02 Verification', 'WP-03 Review', 'WP-04 Repository conventions'],\n peer: ['WP-02 Verification', 'WP-03 Review', 'WP-04 Repository conventions'],\n};\n\nconst PREFACES: Record<Role, string> = {\n supervisor: 'You are Supervisor, the Human-facing routing seat, not the project Lead.',\n lead: 'You are Lead, the project technical owner under Human authority.',\n peer: 'You are Peer, executing one brief from Lead in writing or read-only review mode.',\n};\n\nconst TITLES: Record<Role, string> = {\n supervisor: 'Supervisor role instructions',\n lead: 'Lead role instructions',\n peer: 'Peer role instructions',\n};\n\nconst PROTOCOL_TITLE = 'Workspace protocol';\n// Stated without a clause number, because this preface also heads the copy written\n// to the room home, where no clause is present to resolve the reference.\nconst PROTOCOL_PREFACE = [\n 'This is the room default, and it is in force now. A repository that needs different rules',\n 'provides `docs/WORKSPACE_PROTOCOL.md`: read it, follow it wherever it speaks to a point,',\n 'and keep what follows where it is silent.',\n].join('\\n');\n\nexport function instructionIds(role: Role): readonly RoleContractId[] {\n // Every role carries the shared authority contract plus its own obligations.\n return [...SHARED_IDS, ...ROLE_IDS[role]];\n}\n\nexport function protocolIds(role: Role): readonly ProtocolId[] {\n return PROTOCOL_IDS[role];\n}\n\nfunction sections(ids: readonly string[], source: Readonly<Record<string, readonly string[]>>): string[] {\n return ids.map(id => `## ${id}\\n${(source[id] ?? []).map(statement => `- ${statement}`).join('\\n')}`);\n}\n\n/** The protocol travels inside every role document, so no repository has to opt in. */\nfunction protocol(ids: readonly ProtocolId[]): string[] {\n return [`# ${PROTOCOL_TITLE}`, PROTOCOL_PREFACE, ...sections(ids, DEFAULT_PROTOCOL)];\n}\n\nexport function renderInstructions(kind: InstructionKind): string {\n if (kind === 'workspace') {\n return protocol(Object.keys(DEFAULT_PROTOCOL) as ProtocolId[]).join('\\n\\n') + '\\n';\n }\n return [\n `# ${TITLES[kind]}`,\n PREFACES[kind],\n ...sections(instructionIds(kind), CLAUSES),\n ...protocol(protocolIds(kind)),\n ].join('\\n\\n') + '\\n';\n}\n","import { execFile } from 'node:child_process';\nimport { access, constants } from 'node:fs/promises';\nimport { delimiter, isAbsolute, join, resolve } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst run = promisify(execFile);\n\n/**\n * Resolve a command to an absolute executable path on `searchPath`.\n *\n * Deliberately not canonicalised. Version managers point a stable name at a\n * versioned file — `~/.local/bin/claude` at `versions/2.1.267`, mise's\n * `node/latest` at `node/24.15.0` — and the resolved target is deleted by the\n * next upgrade. Providers store this path, so following the link would pin every\n * seat to a binary that stops existing.\n */\nexport async function which(command: string, searchPath: string): Promise<string | undefined> {\n const candidates = isAbsolute(command) || command.includes('/')\n ? [resolve(command)]\n : searchPath.split(delimiter).filter(Boolean).map(entry => join(entry, command));\n for (const candidate of candidates) {\n try {\n await access(candidate, constants.X_OK);\n return candidate;\n } catch { /* try the next PATH entry */ }\n }\n return undefined;\n}\n\nexport interface CommandOutput {\n readonly ok: boolean;\n readonly stdout: string;\n}\n/** Bounded, shell-free probe. Failures are reported, never thrown. */\nexport async function probe(executable: string, args: readonly string[], env: NodeJS.ProcessEnv): Promise<CommandOutput> {\n try {\n const { stdout } = await run(executable, [...args], { env, timeout: 20_000, maxBuffer: 16 * 1024 * 1024, encoding: 'utf8' });\n return { ok: true, stdout };\n } catch {\n return { ok: false, stdout: '' };\n }\n}\n","import { basename, join } from 'node:path';\nimport type { Layout } from '../layout.js';\nimport { roleHome } from '../layout.js';\nimport type { Entry } from '../fsops.js';\nimport { existingPaths, exists, readIfPresent } from '../fsops.js';\nimport { fail, pass, type Check } from '../result.js';\nimport type { Role } from '../roles.js';\nimport { renderInstructions } from '../room/instructions.js';\nimport { which } from '../which.js';\nimport type { Agent, AgentPlan } from './types.js';\n\n/** Operator-authored resources shared by reference; native agent definitions stay out. */\nconst SHARED = [\n '.credentials.json', 'skills', 'plugins', 'commands', 'hooks', 'rules',\n 'output-styles', 'keybindings.json', 'themes',\n] as const;\nconst CONTROL_PLANE_ENV = {\n CLAUDE_CODE_DISABLE_AGENT_VIEW: '1',\n CLAUDE_CODE_DISABLE_WORKFLOWS: '1',\n} as const;\n/** Copied once so a fresh role home does not re-run interactive onboarding. */\nconst SEEDED_KEYS = ['hasCompletedOnboarding', 'theme', 'installMethod', 'userID', 'mcpServers'] as const;\n\nfunction asObject(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? { ...value } : {};\n}\n/** Any unreadable or non-object source is simply an empty starting point. */\nfunction readObject(source: string | undefined): Record<string, unknown> {\n try { return asObject(source === undefined ? {} : JSON.parse(source)); } catch { return {}; }\n}\n\n/** Keep operator configuration while closing non-Paseo inbound coordination. */\nexport function renderRoleSettings(source: string | undefined, role: Role): string {\n const settings = readObject(source);\n // Claude applies settings.env after the launch environment, so repeat these\n // provider pins here after operator values to make them effective.\n settings.env = { ...asObject(settings.env), ...CONTROL_PLANE_ENV, PASEO_ROOM_ROLE: role };\n // These restrictive settings cannot be weakened by another settings scope.\n settings.disableAgentView = true;\n settings.disableWorkflows = true;\n settings.crossSessionInbound = 'refuse';\n return JSON.stringify(settings, null, 2) + '\\n';\n}\n\nexport function renderRoleState(source: string | undefined): string {\n const root = readObject(source);\n const state: Record<string, unknown> = { hasCompletedOnboarding: true };\n for (const key of SEEDED_KEYS) if (key in root) state[key] = root[key];\n return JSON.stringify(state, null, 2) + '\\n';\n}\n\n/** Preserve the operator's global memory, then add the stronger room role contract. */\nexport function renderRoleMemory(source: string | undefined, role: Role): string {\n const operator = source?.trim();\n return operator ? `${operator}\\n\\n${renderInstructions(role)}` : renderInstructions(role);\n}\n\nexport const claudeAgent: Agent = {\n id: 'claude',\n label: 'Claude Code',\n homeEnv: 'CLAUDE_CONFIG_DIR',\n // Agent View and dynamic workflows have entry points beyond model tool calls.\n providerEnv: CONTROL_PLANE_ENV,\n defaultModeId: 'bypassPermissions',\n // Keep the legacy Task name and block current native orchestration,\n // shared task/cron coordination, and cross-session paths. Paseo alone owns\n // agent lifecycle and coordination.\n pins: {\n disallowedTools: [\n 'Task', 'Agent', 'Workflow', 'ListAgents', 'SendMessage', 'TeamCreate', 'TeamDelete',\n 'TaskCreate', 'TaskGet', 'TaskList', 'TaskUpdate',\n 'CronCreate', 'CronDelete', 'CronList',\n ],\n },\n async build(layout: Layout, roles: readonly Role[]): Promise<AgentPlan> {\n const home = layout.agentHome.claude;\n const binary = await which(layout.bin.claude, layout.searchPath);\n if (!binary) {\n return { entries: [], checks: [fail('claude.bin', 'Claude Code executable not found.', 'Install Claude Code, or pass --claude-bin /path/to/claude.')] };\n }\n if (!(await exists(home))) {\n return { entries: [], checks: [fail('claude.home', `No Claude config directory at ${home}.`, 'Run claude once to initialise it, or pass --claude-home.')] };\n }\n const checks: Check[] = [pass('claude.home', `Claude Code found at ${binary} using ${home}.`)];\n\n const settingsSource = await readIfPresent(join(home, 'settings.json'));\n const stateSource = await readIfPresent(layout.claudeState);\n const memorySource = await readIfPresent(join(home, 'CLAUDE.md'));\n const shared = await existingPaths(home, SHARED);\n const entries: Entry[] = [];\n for (const role of roles) {\n const target = roleHome(layout, 'claude', role);\n entries.push({ kind: 'dir', path: target });\n entries.push({ kind: 'file', path: join(target, 'CLAUDE.md'), content: renderRoleMemory(memorySource, role) });\n entries.push({ kind: 'file', path: join(target, 'settings.json'), content: renderRoleSettings(settingsSource, role) });\n entries.push({ kind: 'file', path: join(target, '.claude.json'), content: renderRoleState(stateSource), once: true });\n for (const path of shared) entries.push({ kind: 'link', path: join(target, basename(path)), target: path });\n }\n return { entries, checks, binary };\n },\n};\n","import { basename, join } from 'node:path';\nimport { parse, stringify, type TomlTable } from 'smol-toml';\nimport type { Layout } from '../layout.js';\nimport { roleHome } from '../layout.js';\nimport type { Entry } from '../fsops.js';\nimport { existingPaths, readIfPresent } from '../fsops.js';\nimport { fail, pass, type Check } from '../result.js';\nimport type { Role } from '../roles.js';\nimport { renderInstructions } from '../room/instructions.js';\nimport { probe, which } from '../which.js';\nimport type { Agent, AgentPlan } from './types.js';\n\n/** Read-only operator resources every role shares by reference, never by copy. */\nconst SHARED = ['auth.json', 'AGENTS.md', 'skills', 'plugins', 'hooks.json'] as const;\nconst CATALOG = 'model-catalog.json';\n\nfunction table(parent: TomlTable, key: string): TomlTable {\n const value = parent[key];\n if (value === undefined || typeof value !== 'object' || Array.isArray(value) || value instanceof Date) {\n return (parent[key] = {});\n }\n return value;\n}\n\nexport interface RoleConfigInput {\n readonly roleDocument: string;\n readonly catalogPath?: string;\n}\n/**\n * Copy the operator's config, then override only the keys the room owns.\n *\n * `model_instructions_file` is deliberately untouched: it *replaces* Codex's base\n * prompt, so writing it would mean vendoring and maintaining a full copy of that\n * prompt. The room contract is additive and belongs in `developer_instructions`.\n */\nexport function renderRoleConfig(source: TomlTable, input: RoleConfigInput): string {\n const config = structuredClone(source);\n config.sandbox_mode = 'danger-full-access';\n config.approval_policy = 'never';\n // An active profile outranks the top-level keys, so the room's must land there too.\n if (typeof config.profile === 'string') {\n const profile = table(table(config, 'profiles'), config.profile);\n profile.sandbox_mode = 'danger-full-access';\n profile.approval_policy = 'never';\n }\n config.developer_instructions = input.roleDocument;\n if (input.catalogPath) config.model_catalog_json = input.catalogPath;\n // Codex's own multi-agent mode would compete with the room's role contract.\n table(config, 'agents').enabled = false;\n const features = table(config, 'features');\n features.multi_agent = false;\n // Newer configs represent v2 as a table; keep that shape rather than writing a\n // boolean at the same key, which would be a TOML conflict.\n if (typeof features.multi_agent_v2 === 'boolean' || features.multi_agent_v2 === undefined) features.multi_agent_v2 = false;\n else table(features, 'multi_agent_v2').enabled = false;\n return stringify(config) + '\\n';\n}\n\nexport function renderCatalog(catalog: unknown): string {\n return JSON.stringify(catalog, (key, value: unknown) => (key === 'multi_agent_version' ? null : value), 2) + '\\n';\n}\n\nexport const codexAgent: Agent = {\n id: 'codex',\n label: 'Codex',\n homeEnv: 'CODEX_HOME',\n defaultModeId: 'full-access',\n // Without these, Paseo's own mode preset (default auto-review) is sent to the\n // app-server and outranks the sandbox/approval keys in the generated config.\n pins: { params: { sandbox_mode: 'danger-full-access', approval_policy: 'never' } },\n async build(layout: Layout, roles: readonly Role[]): Promise<AgentPlan> {\n const checks: Check[] = [];\n const home = layout.agentHome.codex;\n const binary = await which(layout.bin.codex, layout.searchPath);\n if (!binary) {\n return { entries: [], checks: [fail('codex.bin', 'Codex executable not found.', 'Install Codex, or pass --codex-bin /path/to/codex.')] };\n }\n const configPath = join(home, 'config.toml');\n const raw = await readIfPresent(configPath);\n if (raw === undefined) {\n return { entries: [], checks: [fail('codex.home', `No config.toml in ${home}.`, 'Run codex once to initialise it, or pass --codex-home.')] };\n }\n let source: TomlTable;\n try { source = parse(raw); } catch {\n return { entries: [], checks: [fail('codex.config', `Could not read ${configPath} as TOML.`, 'Fix the syntax in your Codex config, then run setup again.')] };\n }\n checks.push(pass('codex.home', `Codex found at ${binary} using ${home}.`));\n\n const entries: Entry[] = [];\n\n // The catalog is optional: an older Codex simply keeps its built-in models.\n let catalogSource: string | undefined;\n const models = await probe(binary, ['debug', 'models'], { HOME: layout.home, CODEX_HOME: home, PATH: layout.searchPath });\n if (models.ok) {\n try { catalogSource = renderCatalog(JSON.parse(models.stdout)); } catch { catalogSource = undefined; }\n }\n if (!catalogSource) checks.push({ id: 'codex.catalog', status: 'warn', message: 'Codex model catalog unavailable; roles keep the default catalog.' });\n\n const shared = await existingPaths(home, SHARED);\n for (const role of roles) {\n const target = roleHome(layout, 'codex', role);\n const catalogPath = catalogSource ? join(target, CATALOG) : undefined;\n const roleDocument = renderInstructions(role);\n entries.push({ kind: 'dir', path: target });\n // Codex reads the brief from developer_instructions; this copy is for the operator.\n entries.push({ kind: 'file', path: join(target, 'role-instructions.md'), content: roleDocument });\n entries.push({\n kind: 'file',\n path: join(target, 'config.toml'),\n content: renderRoleConfig(source, { roleDocument, ...(catalogPath ? { catalogPath } : {}) }),\n });\n if (catalogSource && catalogPath) entries.push({ kind: 'file', path: catalogPath, content: catalogSource });\n for (const path of shared) entries.push({ kind: 'link', path: join(target, basename(path)), target: path });\n }\n return { entries, checks, binary };\n },\n};\n","import type { PaseoClient, PaseoClientConfig } from '@getpaseo/client';\nimport { gte, valid } from 'semver';\nimport { z } from 'zod';\nimport type { Layout } from './layout.js';\nimport { fail, pass, type Check } from './result.js';\nimport type { Profile, Provider } from './agents/types.js';\nimport { probe, which } from './which.js';\n\nexport const MINIMUM_VERSION = '0.8.0-beta.1';\n\nconst statusSchema = z.object({\n listen: z.string().min(1),\n localDaemon: z.enum(['running', 'stopped', 'stale_pid', 'unresponsive']),\n cliVersion: z.string(),\n daemonVersion: z.string().nullable(),\n});\n\nexport interface Daemon {\n readonly url: string;\n readonly version: string;\n}\nexport interface DaemonResult {\n readonly checks: readonly Check[];\n readonly daemon?: Daemon;\n}\n\nexport function normalizeUrl(listen: string): string | undefined {\n const match = /^(?:ws:\\/\\/)?([^:/]+|\\[[^\\]]+\\]):(\\d+)$/.exec(listen.trim());\n if (!match) return undefined;\n const [, host = '', port = ''] = match;\n const local = ['localhost', '127.0.0.1', '0.0.0.0', '[::1]', '[::]'].includes(host) ? '127.0.0.1' : host;\n return `ws://${local}:${port}`;\n}\n\n/** The whole compatibility story: is Paseo running, and is it new enough? */\nexport function assessStatus(raw: unknown): DaemonResult {\n const parsed = statusSchema.safeParse(raw);\n if (!parsed.success) {\n return { checks: [fail('paseo.status', 'Paseo status output was not understood.', 'Upgrade Paseo, then run: paseo daemon status --json')] };\n }\n const status = parsed.data;\n if (status.localDaemon !== 'running') {\n return { checks: [fail('paseo.daemon', `Paseo daemon is ${status.localDaemon}.`, 'Start it with: paseo daemon start')] };\n }\n const cli = valid(status.cliVersion);\n const daemon = status.daemonVersion === null ? null : valid(status.daemonVersion);\n if (!cli || !daemon) {\n return { checks: [fail('paseo.version', 'Paseo did not report a usable version.', 'Upgrade Paseo to a release that reports semver versions.')] };\n }\n if (cli !== daemon) {\n return { checks: [fail('paseo.version', `Paseo CLI is ${cli} but the running daemon is ${daemon}.`, 'Restart the daemon with: paseo daemon restart')] };\n }\n if (!gte(daemon, MINIMUM_VERSION)) {\n return { checks: [fail('paseo.version', `Paseo ${daemon} is older than the required ${MINIMUM_VERSION}.`, 'Upgrade Paseo, then run setup again.')] };\n }\n const url = normalizeUrl(status.listen);\n if (!url) {\n return { checks: [fail('paseo.listen', `Paseo listen address ${status.listen} was not understood.`, 'Use a host:port listen address in the Paseo config.')] };\n }\n return { checks: [pass('paseo.version', `Paseo ${daemon} is running on ${url} (compatible, needs >= ${MINIMUM_VERSION}).`)], daemon: { url, version: daemon } };\n}\n\nexport async function checkDaemon(layout: Layout, env: NodeJS.ProcessEnv = process.env): Promise<DaemonResult> {\n const binary = await which(layout.bin.paseo, layout.searchPath);\n if (!binary) {\n return { checks: [fail('paseo.bin', 'Paseo executable not found.', 'Install Paseo, or pass --paseo-bin /path/to/paseo.')] };\n }\n const output = await probe(binary, ['daemon', 'status', '--json'], {\n HOME: layout.home, PASEO_HOME: layout.paseoHome, PATH: layout.searchPath,\n ...(env.PASEO_PASSWORD === undefined ? {} : { PASEO_PASSWORD: env.PASEO_PASSWORD }),\n });\n if (!output.ok) {\n return { checks: [fail('paseo.status', 'Could not read Paseo daemon status.', 'Run: paseo daemon status --json')] };\n }\n try { return assessStatus(JSON.parse(output.stdout)); }\n catch { return assessStatus(undefined); }\n}\n\nconst configSchema = z.object({\n config: z.object({\n providers: z.record(z.string(), z.unknown()).optional(),\n // Read loosely: entries carry operator fields the room neither knows nor touches.\n agentProfiles: z.array(z.record(z.string(), z.unknown())).optional(),\n }),\n});\nexport type LiveProfile = Record<string, unknown>;\n\nexport interface Session {\n readProviders(): Promise<Record<string, unknown>>;\n writeProviders(providers: Readonly<Record<string, Provider>>): Promise<void>;\n removeProviders(ids: readonly string[]): Promise<void>;\n readProfiles(): Promise<readonly LiveProfile[]>;\n /** Paseo has no remove-one call for profiles, so this replaces the whole array. */\n writeProfiles(profiles: readonly LiveProfile[]): Promise<void>;\n refresh(ids: readonly string[]): Promise<void>;\n}\nexport type ClientFactory = (config: PaseoClientConfig) => PaseoClient;\n\n/** One connection per command. No retries, no reconnects, no background state. */\nexport async function withSession<T>(\n daemon: Daemon,\n run: (session: Session) => Promise<T>,\n options: { readonly password?: string; readonly factory?: ClientFactory } = {},\n): Promise<T> {\n const quiet = { debug() { /* silent */ }, info() { /* silent */ }, warn() { /* silent */ }, error() { /* silent */ } };\n // Loaded here so the \"Paseo is not running\" path never pays for the SDK.\n const factory = options.factory ?? (await import('@getpaseo/client')).createPaseoClient;\n const client = factory({\n url: `${daemon.url}/ws`,\n ...(options.password === undefined ? {} : { password: options.password }),\n appVersion: MINIMUM_VERSION,\n connectTimeoutMs: 10_000,\n reconnect: { enabled: false },\n logger: quiet,\n });\n try {\n await client.connect();\n return await run({\n async readProviders() {\n const response = configSchema.parse(await client.config.get());\n return response.config.providers ?? {};\n },\n async writeProviders(providers) {\n await client.config.patch({ providers } as unknown as Parameters<PaseoClient['config']['patch']>[0]);\n },\n async removeProviders(ids) {\n await client.config.patch({ removeProviders: [...ids] });\n },\n async readProfiles() {\n const response = configSchema.parse(await client.config.get());\n return response.config.agentProfiles ?? [];\n },\n async writeProfiles(profiles) {\n await client.config.patch({ agentProfiles: [...profiles] } as unknown as Parameters<PaseoClient['config']['patch']>[0]);\n },\n async refresh(ids) {\n await client.providers.refresh({ providers: [...ids] });\n },\n });\n } finally {\n await client.close();\n }\n}\n\n/** Compare only the keys the room owns; unrelated fields stay the operator's. */\nexport function providerMatches(desired: Provider, live: unknown): boolean {\n if (live === null || typeof live !== 'object') return false;\n const entry = live as Record<string, unknown>;\n const env = entry.env;\n const tools = entry.paseoTools;\n const same = (left: unknown, right: unknown): boolean => JSON.stringify(left ?? null) === JSON.stringify(right ?? null);\n return entry.extends === desired.extends &&\n same(entry.command, desired.command) &&\n env !== null && typeof env === 'object' &&\n Object.entries(desired.env).every(([key, value]) => (env as Record<string, unknown>)[key] === value) &&\n tools !== null && typeof tools === 'object' &&\n (tools as { enabled?: unknown }).enabled === desired.paseoTools.enabled &&\n // Pins are the room's guarantee: drifting them silently re-enables what they block.\n same(entry.params, desired.params) &&\n same(entry.disallowedTools, desired.disallowedTools);\n}\n\n/** Compare only the fields the room writes on an update; the rest are the operator's. */\nexport function profileMatches(desired: Profile, live: unknown): boolean {\n if (live === null || typeof live !== 'object') return false;\n const entry = live as Record<string, unknown>;\n return entry.name === desired.name && entry.icon === desired.icon && entry.color === desired.color &&\n entry.provider === desired.provider && entry.modeId === desired.modeId && entry.notes === desired.notes;\n}\n\n/**\n * Paseo stores every profile in one host-wide array, so the room rewrites that array\n * rather than patching an entry. Operator profiles pass through untouched, and so does\n * every field of a room profile that the room does not own.\n */\nexport function mergeProfiles(\n live: readonly LiveProfile[],\n desired: readonly Profile[],\n drop: readonly string[],\n): LiveProfile[] {\n const dropped = new Set(drop);\n const wanted = new Map(desired.map(profile => [profile.id, profile]));\n const seen = new Set<string>();\n const kept = live\n .filter(entry => !dropped.has(String(entry.id)))\n .map(entry => {\n const profile = wanted.get(String(entry.id));\n if (!profile) return entry;\n seen.add(profile.id);\n // Model and thinkingOptionId remain operator choices; the room owns the\n // role's visual identity and its no-prompt launch mode.\n return {\n ...entry, name: profile.name, icon: profile.icon, color: profile.color,\n provider: profile.provider, modeId: profile.modeId, notes: profile.notes,\n };\n });\n return [...kept, ...desired.filter(profile => !seen.has(profile.id)).map(profile => ({ ...profile }))];\n}\n","export const ROLES = ['supervisor', 'lead', 'peer'] as const;\nexport type Role = (typeof ROLES)[number];\n\nexport const AGENT_IDS = ['codex', 'claude'] as const;\nexport type AgentId = (typeof AGENT_IDS)[number];\n\n/** Supervisor and Lead orchestrate; Peer executes one brief and gets no room tools. */\nexport const ROLE_PASEO_TOOLS: Record<Role, boolean> = { supervisor: true, lead: true, peer: false };\n\n/**\n * Reasoning effort a seat starts at: Supervisor routes, Lead judges, Peer implements.\n * Deliberately short of the top option on either agent — `ultra` and `ultracode`\n * advertise automatic task delegation, which is a second control plane.\n */\nexport const ROLE_THINKING: Record<Role, string> = { supervisor: 'low', lead: 'high', peer: 'high' };\n\n/** Paseo profile appearance encodes the room role, independent of agent runtime. */\nexport const ROLE_ICON: Record<Role, string> = { supervisor: 'eye', lead: 'compass', peer: 'code' };\nexport const ROLE_COLOR: Record<Role, string> = { supervisor: 'violet', lead: 'blue', peer: 'emerald' };\n\n/** Paseo shows these to orchestrating agents, so each one says who may open the seat. */\nexport const ROLE_NOTES: Record<Role, string> = {\n supervisor: 'Human-facing routing seat. Opened by Human, never by another agent.',\n lead: 'Sole project technical owner. Open only when none exists; otherwise reuse it. Creates Peer seats only.',\n peer: 'Runs one Lead brief, writing or read-only. Created by Lead, one per brief, closed with it.',\n};\n\nexport function providerId(agent: AgentId, role: Role): string {\n return `${agent}-${role}`;\n}\n/** Distinct from the provider id: a host may already have a profile by that name. */\nexport function profileId(agent: AgentId, role: Role): string {\n return `room-${agent}-${role}`;\n}\nexport function providerLabel(agent: AgentId, role: Role): string {\n const title = (value: string): string => value.charAt(0).toUpperCase() + value.slice(1);\n return `${title(agent)} ${title(role)}`;\n}\n","import { join } from 'node:path';\nimport { z } from 'zod';\nimport { readIfPresent } from './fsops.js';\nimport type { Layout } from './layout.js';\nimport { AGENT_IDS, ROLES, type AgentId, type Role } from './roles.js';\n\nexport const MARKER = 'room.json';\n\nconst markerSchema = z.object({\n version: z.string(),\n agents: z.array(z.enum(AGENT_IDS)).min(1),\n roles: z.array(z.enum(ROLES)).min(1),\n});\nexport type Marker = z.infer<typeof markerSchema>;\n\n/** Deterministic on purpose: re-running setup must not show a phantom change. */\nexport function renderMarker(version: string, agents: readonly AgentId[], roles: readonly Role[]): string {\n return JSON.stringify({ version, agents: [...agents], roles: [...roles] } satisfies Marker, null, 2) + '\\n';\n}\n\n/** Records what setup created, so verify and remove touch nothing else. */\nexport async function readMarker(layout: Layout): Promise<Marker | undefined> {\n const source = await readIfPresent(join(layout.roomHome, MARKER));\n if (source === undefined) return undefined;\n try { return markerSchema.parse(JSON.parse(source)); } catch { return undefined; }\n}\n","import { join } from 'node:path';\nimport { rm } from 'node:fs/promises';\nimport metadata from '../package.json' with { type: 'json' };\nimport { claudeAgent } from './agents/claude.js';\nimport { codexAgent } from './agents/codex.js';\nimport type { Agent, Profile, Provider } from './agents/types.js';\nimport { applyEntries, exists, planEntries, type Entry } from './fsops.js';\nimport { layoutChecks, resolveLayout, roleHome, sharedRoom, type Layout, type Options } from './layout.js';\nimport { checkDaemon, mergeProfiles, profileMatches, providerMatches, withSession, type ClientFactory, type LiveProfile, type Session } from './paseo.js';\nimport { fail, failed, hasFailure, pass, type Check, type Operation, type Result } from './result.js';\nimport { renderInstructions } from './room/instructions.js';\nimport { MARKER, readMarker, renderMarker, type Marker } from './room.js';\nimport { profileId, providerId, providerLabel, ROLES, ROLE_COLOR, ROLE_ICON, ROLE_NOTES, ROLE_PASEO_TOOLS, ROLE_THINKING, type AgentId, type Role } from './roles.js';\n\nexport const AGENTS: Record<AgentId, Agent> = { codex: codexAgent, claude: claudeAgent };\n\nexport interface RunOptions extends Options {\n readonly agents?: readonly AgentId[];\n readonly apply?: boolean;\n readonly env?: NodeJS.ProcessEnv;\n readonly factory?: ClientFactory;\n}\n\nfunction sessionOptions(options: RunOptions): { password?: string; factory?: ClientFactory } {\n const password = (options.env ?? process.env).PASEO_PASSWORD;\n return { ...(password === undefined ? {} : { password }), ...(options.factory ? { factory: options.factory } : {}) };\n}\n\n/** The only per-agent differences are the home variable and the provider pins. */\nfunction roleProviders(layout: Layout, agent: Agent, binary: string, roles: readonly Role[]): Record<string, Provider> {\n return Object.fromEntries(roles.map(role => [providerId(agent.id, role), {\n extends: agent.id,\n label: providerLabel(agent.id, role),\n command: [binary],\n env: { ...agent.providerEnv, [agent.homeEnv]: roleHome(layout, agent.id, role) },\n paseoTools: { enabled: ROLE_PASEO_TOOLS[role] },\n ...agent.pins,\n }]));\n}\n\n/** The picker preset that points at a provider, so a seat is one click rather than four. */\nfunction roleProfiles(agent: Agent, roles: readonly Role[]): Profile[] {\n return roles.map(role => ({\n id: profileId(agent.id, role),\n name: providerLabel(agent.id, role),\n icon: ROLE_ICON[role],\n color: ROLE_COLOR[role],\n provider: providerId(agent.id, role),\n modeId: agent.defaultModeId,\n thinkingOptionId: ROLE_THINKING[role],\n notes: ROLE_NOTES[role],\n }));\n}\n\ninterface Desired {\n readonly entries: readonly Entry[];\n readonly providers: Readonly<Record<string, Provider>>;\n readonly profiles: readonly Profile[];\n readonly checks: readonly Check[];\n}\nasync function buildDesired(layout: Layout, agents: readonly AgentId[], roles: readonly Role[]): Promise<Desired> {\n // Template, not linked into any seat: each repo owns its own docs/WORKSPACE_PROTOCOL.md.\n // Named exactly as RC-002 names it, so a copy needs no rename.\n const entries: Entry[] = [\n { kind: 'dir', path: layout.roomHome },\n { kind: 'dir', path: sharedRoom(layout) },\n { kind: 'file', path: join(sharedRoom(layout), 'WORKSPACE_PROTOCOL.md'), content: renderInstructions('workspace') },\n ];\n const providers: Record<string, Provider> = {};\n const profiles: Profile[] = [];\n const checks: Check[] = [];\n for (const id of agents) {\n const agent = AGENTS[id];\n const plan = await agent.build(layout, roles);\n entries.push(...plan.entries);\n checks.push(...plan.checks);\n if (plan.binary === undefined) continue;\n Object.assign(providers, roleProviders(layout, agent, plan.binary, roles));\n profiles.push(...roleProfiles(agent, roles));\n }\n entries.push({ kind: 'file', path: join(layout.roomHome, MARKER), content: renderMarker(metadata.version, agents, roles) });\n return { entries, providers, profiles, checks };\n}\n\ninterface Stale {\n readonly providerIds: readonly string[];\n readonly profileIds: readonly string[];\n readonly directories: readonly string[];\n}\nconst NOTHING_STALE: Stale = { providerIds: [], profileIds: [], directories: [] };\n\n/** A previous setup may have seated agents or roles this one does not: drop those. */\nasync function staleFrom(layout: Layout, previous: Marker | undefined, agents: readonly AgentId[], roles: readonly Role[]): Promise<Stale> {\n if (!previous) return NOTHING_STALE;\n const kept = new Set(agents.flatMap(agent => roles.map(role => providerId(agent, role))));\n const providerIds: string[] = [];\n const profileIds: string[] = [];\n const directories: string[] = [];\n for (const agent of previous.agents) {\n for (const role of previous.roles) {\n if (kept.has(providerId(agent, role))) continue;\n providerIds.push(providerId(agent, role));\n profileIds.push(profileId(agent, role));\n const path = roleHome(layout, agent, role);\n if (await exists(path)) directories.push(path);\n }\n }\n return { providerIds, profileIds, directories };\n}\n\ninterface Plan {\n readonly operations: readonly Operation[];\n /** Carried out of the plan so apply rewrites the array it actually compared against. */\n readonly liveProfiles: readonly LiveProfile[];\n}\n\n/** One definition of drift, shared by the command that fixes it and the one that reports it. */\nasync function planRoom(session: Session, desired: Desired, stale: Stale): Promise<Plan> {\n const live = await session.readProviders();\n const liveProfiles = await session.readProfiles();\n const byId = new Map(liveProfiles.map(entry => [String(entry.id), entry]));\n return {\n liveProfiles,\n operations: [\n ...await planEntries(desired.entries),\n ...Object.entries(desired.providers).map(([id, provider]) => ({\n action: !(id in live) ? 'create' : providerMatches(provider, live[id]) ? 'noop' : 'update',\n kind: 'provider',\n target: id,\n }) satisfies Operation),\n ...desired.profiles.map(profile => ({\n action: !byId.has(profile.id) ? 'create' : profileMatches(profile, byId.get(profile.id)) ? 'noop' : 'update',\n kind: 'profile',\n target: profile.id,\n }) satisfies Operation),\n ...stale.providerIds.filter(id => id in live).map(id => ({ action: 'remove', kind: 'provider', target: id }) satisfies Operation),\n ...stale.profileIds.filter(id => byId.has(id)).map(id => ({ action: 'remove', kind: 'profile', target: id }) satisfies Operation),\n ...stale.directories.map(path => ({ action: 'remove', kind: 'dir', target: path }) satisfies Operation),\n ],\n };\n}\n\n/** The whole product: write the role homes, then register them with Paseo. */\nexport async function setup(options: RunOptions = {}): Promise<Result> {\n const layout = resolveLayout(options, options.env);\n const agents = options.agents ?? ['codex'];\n const invalid = layoutChecks(layout, agents);\n if (invalid.length > 0) return failed('setup', invalid);\n const daemon = await checkDaemon(layout, options.env);\n if (!daemon.daemon) return failed('setup', daemon.checks);\n const desired = await buildDesired(layout, agents, ROLES);\n const checks = [...daemon.checks, ...desired.checks];\n if (hasFailure(checks)) return failed('setup', checks);\n const stale = await staleFrom(layout, await readMarker(layout), agents, ROLES);\n\n return withSession(daemon.daemon, async session => {\n const { operations, liveProfiles } = await planRoom(session, desired, stale);\n const pending = operations.filter(operation => operation.action !== 'noop');\n if (!options.apply) {\n return {\n command: 'setup', outcome: pending.length > 0 ? 'changes-planned' : 'ok', changed: false, checks, operations,\n } satisfies Result;\n }\n await applyEntries(desired.entries);\n for (const path of stale.directories) await rm(path, { recursive: true, force: true });\n const ids = Object.keys(desired.providers);\n await session.writeProviders(desired.providers);\n if (stale.providerIds.length > 0) await session.removeProviders(stale.providerIds);\n // Profiles point at providers, so they are written once the providers exist — and\n // only when something changed, since one write replaces the host's whole array.\n if (pending.some(operation => operation.kind === 'profile')) {\n await session.writeProfiles(mergeProfiles(liveProfiles, desired.profiles, stale.profileIds));\n }\n await session.refresh(ids);\n return {\n command: 'setup', outcome: 'ok', changed: pending.length > 0,\n checks: [...checks, pass('room.applied', `Room ready at ${layout.roomHome} with ${String(ids.length)} Paseo providers.`)],\n operations,\n } satisfies Result;\n }, sessionOptions(options));\n}\n\nexport async function verify(options: RunOptions = {}): Promise<Result> {\n const layout = resolveLayout(options, options.env);\n const marker = await readMarker(layout);\n if (!marker) {\n return failed('verify', [fail('room.marker', `No room found at ${layout.roomHome}.`, 'Run: paseo-room setup --apply')]);\n }\n const invalid = layoutChecks(layout, marker.agents);\n if (invalid.length > 0) return failed('verify', invalid);\n const daemon = await checkDaemon(layout, options.env);\n if (!daemon.daemon) return failed('verify', daemon.checks);\n const desired = await buildDesired(layout, marker.agents, marker.roles);\n const checks = [...daemon.checks, ...desired.checks];\n if (hasFailure(checks)) return failed('verify', checks);\n\n return withSession(daemon.daemon, async session => {\n const { operations } = await planRoom(session, desired, NOTHING_STALE);\n const drifted = operations.filter(operation => operation.action !== 'noop');\n const count = (kind: Operation['kind']): number => drifted.filter(operation => operation.kind === kind).length;\n const providers = count('provider');\n const profiles = count('profile');\n const files = drifted.length - providers - profiles;\n const all: Check[] = [...checks,\n files === 0\n ? pass('room.files', 'Every managed role file matches the current definition.')\n : fail('room.files', `${String(files)} managed role files are missing or outdated.`, 'Run: paseo-room setup --apply'),\n providers === 0\n ? pass('room.providers', `All ${String(Object.keys(desired.providers).length)} Paseo providers are registered as expected.`)\n : fail('room.providers', `${String(providers)} Paseo providers are missing or differ.`, 'Run: paseo-room setup --apply'),\n profiles === 0\n ? pass('room.profiles', `All ${String(desired.profiles.length)} Paseo agent profiles are registered as expected.`)\n : fail('room.profiles', `${String(profiles)} Paseo agent profiles are missing or differ.`, 'Run: paseo-room setup --apply'),\n ];\n return {\n command: 'verify', outcome: hasFailure(all) ? 'failed' : 'ok', changed: false, checks: all, operations,\n } satisfies Result;\n }, sessionOptions(options));\n}\n\nexport async function remove(options: RunOptions = {}): Promise<Result> {\n const layout = resolveLayout(options, options.env);\n const marker = await readMarker(layout);\n if (!marker) {\n return failed('remove', [fail('room.marker', `No room found at ${layout.roomHome}.`, 'Nothing to remove; the room home was never created here.')]);\n }\n // A recursive delete needs a floor, so the layout rules gate this command too.\n const invalid = layoutChecks(layout, marker.agents);\n if (invalid.length > 0) return failed('remove', invalid);\n const ids = marker.agents.flatMap(agent => marker.roles.map(role => providerId(agent, role)));\n const profiles = new Set(marker.agents.flatMap(agent => marker.roles.map(role => profileId(agent, role))));\n const operations: Operation[] = [\n ...ids.map(id => ({ action: 'remove', kind: 'provider', target: id }) satisfies Operation),\n ...[...profiles].map(id => ({ action: 'remove', kind: 'profile', target: id }) satisfies Operation),\n { action: 'remove', kind: 'dir', target: layout.roomHome },\n ];\n if (!options.apply) {\n return { command: 'remove', outcome: 'changes-planned', changed: false, checks: [], operations };\n }\n const daemon = await checkDaemon(layout, options.env);\n const checks: Check[] = [];\n if (daemon.daemon) {\n await withSession(daemon.daemon, async session => {\n await session.removeProviders(ids);\n const live = await session.readProfiles();\n const kept = live.filter(entry => !profiles.has(String(entry.id)));\n if (kept.length !== live.length) await session.writeProfiles(kept);\n }, sessionOptions(options));\n checks.push(pass('room.providers', `Removed ${String(ids.length)} Paseo providers and their agent profiles.`));\n } else {\n checks.push({ id: 'room.providers', status: 'warn', message: 'Paseo is unreachable; provider and profile entries were left in place.', fix: 'Start Paseo and run remove again to clear them.' });\n }\n // Only the room home is deleted; agent homes were never written to.\n await rm(layout.roomHome, { recursive: true, force: true });\n checks.push(pass('room.files', `Deleted ${layout.roomHome}.`));\n return { command: 'remove', outcome: 'ok', changed: true, checks, operations };\n}\n","import * as clack from '@clack/prompts';\nimport { AGENTS, remove, setup, verify, type RunOptions } from './commands.js';\nimport type { Result } from './result.js';\nimport { AGENT_IDS, type AgentId } from './roles.js';\n\nexport interface Prompts {\n select(options: { readonly message: string; readonly options: readonly { readonly value: string; readonly label: string }[] }): Promise<string | symbol>;\n multiselect(options: { readonly message: string; readonly options: readonly { readonly value: AgentId; readonly label: string }[] }): Promise<AgentId[] | symbol>;\n confirm(options: { readonly message: string }): Promise<boolean | symbol>;\n}\nexport const terminalPrompts: Prompts = {\n select: options => clack.select({ message: options.message, options: [...options.options] }),\n multiselect: options => clack.multiselect({ message: options.message, options: [...options.options], required: true }),\n confirm: options => clack.confirm({ message: options.message, initialValue: false }),\n};\n\n/** Guided path over the same commands the flags use; nothing extra happens here. */\nexport async function runWizard(\n prompts: Prompts,\n emit: (result: Result) => number,\n write: (text: string) => void,\n options: RunOptions = {},\n): Promise<number> {\n const cancelled = (): number => { write('Cancelled; nothing was changed.\\n'); return 0; };\n const action = await prompts.select({\n message: 'What do you want to do?',\n options: [\n { value: 'setup', label: 'Set up / update the room' },\n { value: 'verify', label: 'Verify the current room' },\n { value: 'remove', label: 'Remove the room' },\n ],\n });\n if (typeof action === 'symbol') return cancelled();\n if (action === 'verify') return emit(await verify(options));\n if (action === 'remove') {\n const preview = await remove(options);\n const status = emit(preview);\n if (preview.outcome !== 'changes-planned') return status;\n const approved = await prompts.confirm({ message: 'Delete the room home and its Paseo providers?' });\n return approved === true ? emit(await remove({ ...options, apply: true })) : cancelled();\n }\n const agents = await prompts.multiselect({\n message: 'Which coding agents should the room use?',\n options: AGENT_IDS.map(value => ({ value, label: AGENTS[value].label })),\n });\n if (typeof agents === 'symbol' || agents.length === 0) return cancelled();\n const preview = await setup({ ...options, agents });\n const status = emit(preview);\n if (preview.outcome !== 'changes-planned') return status;\n const approved = await prompts.confirm({ message: 'Apply these changes?' });\n if (approved !== true) return cancelled();\n return emit(await setup({ ...options, agents, apply: true }));\n}\n","import { Command, CommanderError } from 'commander';\nimport metadata from '../package.json' with { type: 'json' };\nimport { remove, setup, verify, type RunOptions } from './commands.js';\nimport { renderHuman, renderJson } from './render.js';\nimport { exitCode, fail, failed, type Result } from './result.js';\nimport { AGENT_IDS, type AgentId } from './roles.js';\nimport type { Prompts } from './wizard.js';\n\nexport interface Output {\n readonly stdout: (text: string) => void;\n readonly stderr: (text: string) => void;\n}\nexport interface CliContext {\n readonly isTTY?: boolean;\n readonly prompts?: Prompts;\n readonly options?: RunOptions;\n}\n\n/** Commander passes no initial value, so the first call starts the list. */\nfunction collectAgent(value: string, previous: AgentId[] | undefined): AgentId[] {\n const agent = AGENT_IDS.find(id => id === value);\n if (!agent) throw new CommanderError(2, 'agent', `Unknown agent: ${value}`);\n const seated = previous ?? [];\n return seated.includes(agent) ? seated : [...seated, agent];\n}\n\nconst PATH_FLAGS = ['roomHome', 'codexHome', 'claudeHome', 'codexBin', 'claudeBin', 'paseoBin'] as const;\n\nfunction optionsFrom(raw: Record<string, unknown>, base: RunOptions): RunOptions {\n const paths: Record<string, string> = {};\n for (const flag of PATH_FLAGS) {\n const value = raw[flag];\n if (typeof value === 'string' && value.trim()) paths[flag] = value.trim();\n }\n const agents = Array.isArray(raw.agent) && raw.agent.length > 0 ? (raw.agent as AgentId[]) : undefined;\n return { ...base, ...paths, ...(agents ? { agents } : {}), ...(raw.apply === true ? { apply: true } : {}) };\n}\n\nexport async function runCli(argv: readonly string[], output: Output, context: CliContext = {}): Promise<number> {\n const password = (context.options?.env ?? process.env).PASEO_PASSWORD;\n const redact = (text: string): string => (password ? text.split(password).join('[redacted]') : text);\n // Set once the flags are parsed; the wizard path never sees flags, so text output is right there.\n let json = false;\n const emit = (result: Result): number => {\n output.stdout(redact(json ? renderJson(result) : renderHuman(result)));\n return exitCode(result);\n };\n const isTTY = context.isTTY ?? (process.stdin.isTTY && process.stdout.isTTY);\n const base = context.options ?? {};\n\n if (argv.length === 0) {\n if (!isTTY) {\n output.stderr('paseo-room: no command given. Try: paseo-room setup, verify, remove, or --help.\\n');\n return 2;\n }\n // @clack/prompts is only reachable here, so keep it off the scripted path.\n const { runWizard, terminalPrompts } = await import('./wizard.js');\n return runWizard(context.prompts ?? terminalPrompts, emit, text => { output.stdout(text); }, base);\n }\n\n const program = new Command()\n .name('paseo-room')\n .description('Configure Codex/Claude role homes in $HOME and register them with your local Paseo daemon.')\n .version(metadata.version)\n .argument('<command>', 'setup | verify | remove')\n .option('--agent <agent>', 'codex or claude; repeat for both (default: codex)', collectAgent)\n .option('--apply', 'actually make the changes (default: dry run)')\n .option('--json', 'machine-readable output')\n .option('--room-home <path>', 'where role homes are written (default: ~/.paseo-room)')\n .option('--codex-home <path>', 'source Codex config (default: ~/.codex)')\n .option('--claude-home <path>', 'source Claude Code config (default: ~/.claude)')\n .option('--codex-bin <path>', 'Codex executable (default: found on PATH)')\n .option('--claude-bin <path>', 'Claude Code executable (default: found on PATH)')\n .option('--paseo-bin <path>', 'Paseo executable (default: found on PATH)')\n .configureOutput({ writeOut: text => { output.stdout(text); }, writeErr: text => { output.stderr(text); } })\n .exitOverride();\n\n let command: string;\n let options: RunOptions;\n try {\n program.parse([...argv], { from: 'user' });\n const raw = program.opts<Record<string, unknown>>();\n json = raw.json === true;\n command = program.args[0] ?? '';\n options = optionsFrom(raw, base);\n } catch (error) {\n if (error instanceof CommanderError && error.exitCode === 0) return 0;\n return 2;\n }\n\n try {\n if (command === 'setup') return emit(await setup(options));\n if (command === 'verify') return emit(await verify(options));\n if (command === 'remove') return emit(await remove(options));\n } catch (error) {\n const detail = error instanceof Error ? error.message : 'unknown error';\n return emit(failed(command, [fail(`${command}.error`, redact(detail), 'Check that Paseo is running and reachable, then try again.')]));\n }\n output.stderr(`paseo-room: unknown command \"${command}\". Try: setup, verify, remove.\\n`);\n return 2;\n}\n","import type { Result } from './result.js';\n\nexport function renderJson(result: Result): string {\n return `${JSON.stringify({ schemaVersion: 2, ...result }, null, 2)}\\n`;\n}\n\nconst ICONS = { pass: '✓', warn: '!', fail: '✗' } as const;\n\nexport function renderHuman(result: Result): string {\n const lines: string[] = [];\n for (const check of result.checks) {\n lines.push(`${ICONS[check.status]} ${check.message}`);\n if (check.fix) lines.push(` → ${check.fix}`);\n }\n const changes = result.operations.filter(operation => operation.action !== 'noop');\n if (changes.length > 0) {\n lines.push('', result.changed ? 'Applied:' : 'Planned changes:');\n for (const operation of changes) lines.push(` ${operation.action} ${operation.kind} ${operation.target}`);\n const unchanged = result.operations.length - changes.length;\n if (unchanged > 0) lines.push(` (${String(unchanged)} already up to date)`);\n } else if (result.operations.length > 0) {\n lines.push('', 'Everything is already up to date.');\n }\n lines.push('', `${result.command}: ${result.outcome}`);\n return `${lines.join('\\n')}\\n`;\n}\n","#!/usr/bin/env node\nimport { runCli } from './cli.js';\n\nprocess.exitCode = await runCli(process.argv.slice(2), {\n stdout: text => { process.stdout.write(text); },\n stderr: text => { process.stderr.write(text); },\n});\n"],"mappings":"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","names":["join","join","resolve","join","basename","join","SHARED","run","join","z","join","rm","preview","status","approved","runWizard","terminalPrompts"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paseo-room",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.4",
4
4
  "description": "One CLI that configures Codex/Claude role homes in $HOME and registers them with your local Paseo daemon.",
5
5
  "keywords": [
6
6
  "paseo",