@mattstack/rt-client 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -171,14 +171,13 @@ export interface GateRow {
171
171
  at: number;
172
172
  } | null;
173
173
  released: boolean;
174
- /** Set once the nudged pane has provably read the answer: either it
175
- self-answered (stamped in the same transaction as the answer) or a
176
- later `markConsumed` call recorded that it acted on a push. `null`
177
- until then, so a sweep can tell an answered-but-unread row from a
178
- settled one. Currently only stamped for herd-subject gates (the
179
- self-answer path and `rt herd answer`'s nudged-session read); a
180
- non-herd gate with a nudge stays `null` even after its pane
181
- reconciles. */
174
+ /** Set once the nudged pane has provably read the answer: it self-answered
175
+ or lost the CAS to one (both stamped in the answer's own transaction),
176
+ or a later `markConsumed` call recorded that it acted on a push
177
+ (`rt herd answer` and `rt gate wait`, each on the nudged session's own
178
+ read). `null` until then, so a sweep can tell an answered-but-unread row
179
+ from a settled one. Every nudge-bearing subject has a stamping read;
180
+ a gate with no nudge never carries one, having no pane to read it. */
182
181
  consumedAt: number | null;
183
182
  owner: string | null;
184
183
  escalatedAt: number | null;
@@ -228,19 +227,20 @@ export interface HerdJobInfo {
228
227
  agentSession: string | null;
229
228
  agentId: string | null;
230
229
  handle: string;
231
- status: "spawning" | "active" | "at-gate" | "at-milestone" | "done" | "closed" | "crashed";
230
+ status: "spawning" | "active" | "at-gate" | "at-milestone" | "done" | "closed" | "crashed" | "stuck-at-modal";
232
231
  disposable: boolean;
233
232
  lastGate: string | null;
234
233
  lastReport: number | null;
235
234
  createdAt: number;
236
235
  updatedAt: number;
237
236
  }
238
- /** `lastGateStatus`/`lastGateDelivery` come from the job's `lastGate` row: an `answered` gate whose delivery is `dead-pane` is the "answered, worker not woken" case the shepherd must act on. `lastGateConsumed` is `null` when there is nothing to consume (no last gate, not answered, or not nudged), and otherwise reports whether the nudged pane has read its answer. */
237
+ /** `lastGateStatus`/`lastGateDelivery` come from the job's `lastGate` row: a TERMINAL gate (answered or closed) whose delivery is `dead-pane` is the "worker not woken" case the shepherd must act on. `lastGateConsumed` is `null` when there is nothing to consume (no last gate, not answered, or not nudged), and otherwise reports whether the nudged pane has read its answer. */
239
238
  export interface HerdStatusData {
240
239
  herd: HerdInfo;
241
240
  jobs: Array<HerdJobInfo & {
242
241
  openGate: string | null;
243
- paneStatus: string | null;
242
+ paneStatus: string | null; /** The worker session behind this job's pane is gone while the job still reads in-flight: herdr lists the pane but no claude is on it. Null when herdr does not list the pane at all (it closed, or herdr is unreachable), which proves nothing either way. */
243
+ sessionDead: boolean | null;
244
244
  lastGateStatus: GateStatus | null;
245
245
  lastGateDelivery: "delivered" | "dead-pane" | "confirmed" | "stuck" | null;
246
246
  lastGateConsumed: boolean | null;
@@ -507,6 +507,7 @@ export interface AgentRecord {
507
507
  extraArgs?: string;
508
508
  exitCode?: number;
509
509
  resultPath?: string;
510
+ yolo?: boolean;
510
511
  createdAt: number;
511
512
  lastResumedAt?: number;
512
513
  finishedAt?: number;
@@ -1141,6 +1142,7 @@ export interface Commands {
1141
1142
  cwd: string;
1142
1143
  prompt?: string;
1143
1144
  surface?: AgentSurface;
1145
+ provider?: string;
1144
1146
  model?: string;
1145
1147
  effort?: string;
1146
1148
  account?: string;
@@ -1154,6 +1156,7 @@ export interface Commands {
1154
1156
  handle?: string;
1155
1157
  bg?: boolean;
1156
1158
  subject?: string;
1159
+ yolo?: boolean;
1157
1160
  };
1158
1161
  data: AgentRecord;
1159
1162
  };
@@ -1503,11 +1506,15 @@ export interface Commands {
1503
1506
  worktree?: string;
1504
1507
  };
1505
1508
  };
1509
+ /** `contextOmitted` appears only when the caller's context exceeded the
1510
+ 8192-byte cap and was dropped: the gate still opened, but with none of
1511
+ the material the reader needs. */
1506
1512
  data: {
1507
1513
  id: string;
1508
1514
  presentation: "form" | "wait";
1509
1515
  subject: string;
1510
1516
  supersededId: string | null;
1517
+ contextOmitted?: true;
1511
1518
  };
1512
1519
  };
1513
1520
  /**
@@ -1538,10 +1545,14 @@ export interface Commands {
1538
1545
  };
1539
1546
  /** `ok:false "not-found"` on an unknown id is terminal; the CLI loop must not re-enter on it.
1540
1547
  * `timeout` carries no row (nothing settled); `answered`/`closed` always carry the settled row. */
1548
+ /** `sessionId` is the caller's own session: an answered result returned to
1549
+ * the gate's nudged session is a recorded read and stamps `consumedAt`.
1550
+ * Omitting it reads without consuming. */
1541
1551
  "gate:wait": {
1542
1552
  payload: {
1543
1553
  id: string;
1544
1554
  waitMs?: number;
1555
+ sessionId?: string;
1545
1556
  };
1546
1557
  data: {
1547
1558
  status: "timeout";
@@ -1689,7 +1700,8 @@ export interface Commands {
1689
1700
  wasOnDeck: boolean | null;
1690
1701
  agentId: string;
1691
1702
  sessionId: string;
1692
- handle: string;
1703
+ handle: string; /** What the folder-trust check established: no modal was up, one was accepted and verified gone, one is still up (the job reads `stuck-at-modal`), or herdr could not be read. */
1704
+ trust: "none" | "accepted" | "stuck" | "unchecked";
1693
1705
  };
1694
1706
  };
1695
1707
  "herd:gates": {
package/dist/index.js CHANGED
@@ -243,7 +243,7 @@ function eventsList(payload, o = {}) {
243
243
  }
244
244
  function agentStart(a, o = {}) {
245
245
  const payload = { repo: a.repo, cwd: a.cwd };
246
- for (const k of ["prompt", "surface", "model", "effort", "account", "label", "caller", "workspace", "tab", "extraArgs", "env", "herdrSocket", "handle", "bg", "subject"]) {
246
+ for (const k of ["prompt", "surface", "provider", "model", "effort", "account", "label", "caller", "workspace", "tab", "extraArgs", "env", "herdrSocket", "handle", "bg", "subject", "yolo"]) {
247
247
  if (a[k] !== undefined)
248
248
  payload[k] = a[k];
249
249
  }
@@ -344,6 +344,8 @@ function gateWait(a, o = {}) {
344
344
  const payload = { id: a.id };
345
345
  if (a.waitMs !== undefined)
346
346
  payload.waitMs = a.waitMs;
347
+ if (a.sessionId !== undefined)
348
+ payload.sessionId = a.sessionId;
347
349
  return rtCommand("gate:wait", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 250000 });
348
350
  }
349
351
  function gateList(a, o = {}) {
@@ -1519,32 +1521,75 @@ var REGISTRY = [
1519
1521
  description: "Destination (topic/URL/token) the configured chat.push.provider sends to."
1520
1522
  },
1521
1523
  {
1522
- key: "agent.model",
1524
+ key: "agent.provider",
1525
+ type: "string",
1526
+ scopes: ["user", "machine"],
1527
+ default: "claude",
1528
+ merge: "replace",
1529
+ description: 'Which provider rt agent start uses when --provider is not given: "claude" or "codex".'
1530
+ },
1531
+ {
1532
+ key: "agent.claude.model",
1533
+ type: "string",
1534
+ scopes: ["user", "machine"],
1535
+ merge: "replace",
1536
+ description: "Default --model for claude rt agent launches; unset omits the flag."
1537
+ },
1538
+ {
1539
+ key: "agent.claude.effort",
1540
+ type: "string",
1541
+ scopes: ["user", "machine"],
1542
+ merge: "replace",
1543
+ description: "Default --effort for claude rt agent launches; unset omits the flag."
1544
+ },
1545
+ {
1546
+ key: "agent.claude.account",
1523
1547
  type: "string",
1524
1548
  scopes: ["user", "machine"],
1525
1549
  merge: "replace",
1526
- description: "Default --model for rt agent launches; unset omits the flag."
1550
+ description: "cswap account email claude rt agent launches under; unset uses the default claude profile."
1527
1551
  },
1528
1552
  {
1529
- key: "agent.effort",
1553
+ key: "agent.claude.extraArgs",
1530
1554
  type: "string",
1531
1555
  scopes: ["user", "machine"],
1532
1556
  merge: "replace",
1533
- description: "Default --effort for rt agent launches; unset omits the flag."
1557
+ description: "Opaque extra claude arguments appended to every claude rt agent launch (escape hatch)."
1558
+ },
1559
+ {
1560
+ key: "agent.claude.yolo",
1561
+ type: "boolean",
1562
+ scopes: ["user", "machine"],
1563
+ merge: "replace",
1564
+ description: "Default --yolo (--dangerously-skip-permissions) for claude rt agent launches; unset behaves as false."
1534
1565
  },
1535
1566
  {
1536
- key: "agent.account",
1567
+ key: "agent.codex.model",
1537
1568
  type: "string",
1538
1569
  scopes: ["user", "machine"],
1539
1570
  merge: "replace",
1540
- description: "cswap account email rt agent launches under; unset uses the default claude profile."
1571
+ description: "Default -m/--model for codex rt agent launches; unset omits the flag."
1541
1572
  },
1542
1573
  {
1543
- key: "agent.extraArgs",
1574
+ key: "agent.codex.effort",
1544
1575
  type: "string",
1545
1576
  scopes: ["user", "machine"],
1546
1577
  merge: "replace",
1547
- description: "Opaque extra claude arguments appended to every rt agent launch (escape hatch)."
1578
+ description: "Default reasoning effort for codex rt agent launches, passed as -c model_reasoning_effort=<value>; unset omits the override."
1579
+ },
1580
+ {
1581
+ key: "agent.codex.extraArgs",
1582
+ type: "string",
1583
+ scopes: ["user", "machine"],
1584
+ merge: "replace",
1585
+ description: "Opaque extra codex arguments appended to every codex rt agent launch (escape hatch)."
1586
+ },
1587
+ {
1588
+ key: "agent.codex.yolo",
1589
+ type: "boolean",
1590
+ scopes: ["user", "machine"],
1591
+ merge: "replace",
1592
+ description: "Default --yolo (--dangerously-bypass-approvals-and-sandbox) for codex rt agent launches; unset behaves as false. codex has no per-agent account setting (see spec's Non-goals)."
1548
1593
  },
1549
1594
  {
1550
1595
  key: "rt.gates.escalationTtlMinutes",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mattstack/rt-client",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/src/client.ts CHANGED
@@ -356,7 +356,7 @@ export function agentStart(
356
356
  a: Commands["agent:start"]["payload"], o: RtClientOptions = {},
357
357
  ): Promise<RtResponse<AgentRecord>> {
358
358
  const payload: Record<string, unknown> = { repo: a.repo, cwd: a.cwd };
359
- for (const k of ["prompt", "surface", "model", "effort", "account", "label", "caller", "workspace", "tab", "extraArgs", "env", "herdrSocket", "handle", "bg", "subject"] as const) {
359
+ for (const k of ["prompt", "surface", "provider", "model", "effort", "account", "label", "caller", "workspace", "tab", "extraArgs", "env", "herdrSocket", "handle", "bg", "subject", "yolo"] as const) {
360
360
  if (a[k] !== undefined) payload[k] = a[k];
361
361
  }
362
362
  return rtCommand<AgentRecord>("agent:start", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 30_000 });
@@ -499,6 +499,7 @@ export function gateWait(
499
499
  ): Promise<RtResponse<Commands["gate:wait"]["data"]>> {
500
500
  const payload: Record<string, unknown> = { id: a.id };
501
501
  if (a.waitMs !== undefined) payload.waitMs = a.waitMs;
502
+ if (a.sessionId !== undefined) payload.sessionId = a.sessionId;
502
503
  return rtCommand<Commands["gate:wait"]["data"]>("gate:wait", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 250_000 });
503
504
  }
504
505
 
package/src/commands.ts CHANGED
@@ -134,14 +134,13 @@ export interface GateRow {
134
134
  nudge: { session: string } | null;
135
135
  delivery: { outcome: "delivered" | "dead-pane" | "confirmed" | "stuck"; at: number } | null;
136
136
  released: boolean;
137
- /** Set once the nudged pane has provably read the answer: either it
138
- self-answered (stamped in the same transaction as the answer) or a
139
- later `markConsumed` call recorded that it acted on a push. `null`
140
- until then, so a sweep can tell an answered-but-unread row from a
141
- settled one. Currently only stamped for herd-subject gates (the
142
- self-answer path and `rt herd answer`'s nudged-session read); a
143
- non-herd gate with a nudge stays `null` even after its pane
144
- reconciles. */
137
+ /** Set once the nudged pane has provably read the answer: it self-answered
138
+ or lost the CAS to one (both stamped in the answer's own transaction),
139
+ or a later `markConsumed` call recorded that it acted on a push
140
+ (`rt herd answer` and `rt gate wait`, each on the nudged session's own
141
+ read). `null` until then, so a sweep can tell an answered-but-unread row
142
+ from a settled one. Every nudge-bearing subject has a stamping read;
143
+ a gate with no nudge never carries one, having no pane to read it. */
145
144
  consumedAt: number | null;
146
145
  owner: string | null;
147
146
  escalatedAt: number | null;
@@ -166,11 +165,11 @@ export interface GateSubscription {
166
165
  export interface HerdInfo { id: string; repo: string; room: string; workspace: string; shepherdSession: string; shepherdHandle: string; herdrSocket: string | null; hidden: boolean; status: "active" | "wrapped"; createdAt: number; wrappedAt: number | null }
167
166
  /** A herd row as `herd:list` reports it: the registry row plus how many jobs hang off it. */
168
167
  export interface HerdListRow extends HerdInfo { jobs: number }
169
- export interface HerdJobInfo { herd: string; name: string; worktree: string; branch: string | null; tree: string | null; pane: string | null; agentSession: string | null; agentId: string | null; handle: string; status: "spawning" | "active" | "at-gate" | "at-milestone" | "done" | "closed" | "crashed"; disposable: boolean; lastGate: string | null; lastReport: number | null; createdAt: number; updatedAt: number }
170
- /** `lastGateStatus`/`lastGateDelivery` come from the job's `lastGate` row: an `answered` gate whose delivery is `dead-pane` is the "answered, worker not woken" case the shepherd must act on. `lastGateConsumed` is `null` when there is nothing to consume (no last gate, not answered, or not nudged), and otherwise reports whether the nudged pane has read its answer. */
168
+ export interface HerdJobInfo { herd: string; name: string; worktree: string; branch: string | null; tree: string | null; pane: string | null; agentSession: string | null; agentId: string | null; handle: string; status: "spawning" | "active" | "at-gate" | "at-milestone" | "done" | "closed" | "crashed" | "stuck-at-modal"; disposable: boolean; lastGate: string | null; lastReport: number | null; createdAt: number; updatedAt: number }
169
+ /** `lastGateStatus`/`lastGateDelivery` come from the job's `lastGate` row: a TERMINAL gate (answered or closed) whose delivery is `dead-pane` is the "worker not woken" case the shepherd must act on. `lastGateConsumed` is `null` when there is nothing to consume (no last gate, not answered, or not nudged), and otherwise reports whether the nudged pane has read its answer. */
171
170
  export interface HerdStatusData {
172
171
  herd: HerdInfo;
173
- jobs: Array<HerdJobInfo & { openGate: string | null; paneStatus: string | null; lastGateStatus: GateStatus | null; lastGateDelivery: "delivered" | "dead-pane" | "confirmed" | "stuck" | null; lastGateConsumed: boolean | null }>;
172
+ jobs: Array<HerdJobInfo & { openGate: string | null; paneStatus: string | null; /** The worker session behind this job's pane is gone while the job still reads in-flight: herdr lists the pane but no claude is on it. Null when herdr does not list the pane at all (it closed, or herdr is unreachable), which proves nothing either way. */ sessionDead: boolean | null; lastGateStatus: GateStatus | null; lastGateDelivery: "delivered" | "dead-pane" | "confirmed" | "stuck" | null; lastGateConsumed: boolean | null }>;
174
173
  unread: number;
175
174
  lifecycleConnected: boolean;
176
175
  hiddenUp: boolean | null;
@@ -360,7 +359,7 @@ export interface AgentRecord {
360
359
  PreToolUse hook gets injected at all. */
361
360
  subject?: string;
362
361
  paneId?: string; tabId?: string; workspaceId?: string;
363
- extraArgs?: string; exitCode?: number; resultPath?: string;
362
+ extraArgs?: string; exitCode?: number; resultPath?: string; yolo?: boolean;
364
363
  createdAt: number; lastResumedAt?: number; finishedAt?: number;
365
364
  }
366
365
 
@@ -617,7 +616,7 @@ export interface Commands {
617
616
  "chat:dm-open": { payload: { from: string; to: string; sessionId?: string }; data: { room: string; created: boolean } };
618
617
 
619
618
  // ─── Agent handoff (rt agent) ────────────────────────────────────────────
620
- "agent:start": { payload: { repo: string; cwd: string; prompt?: string; surface?: AgentSurface; model?: string; effort?: string; account?: string; label?: string; caller?: string; workspace?: string; tab?: string; extraArgs?: string; env?: Record<string, string>; herdrSocket?: string; handle?: string; bg?: boolean; subject?: string }; data: AgentRecord };
619
+ "agent:start": { payload: { repo: string; cwd: string; prompt?: string; surface?: AgentSurface; provider?: string; model?: string; effort?: string; account?: string; label?: string; caller?: string; workspace?: string; tab?: string; extraArgs?: string; env?: Record<string, string>; herdrSocket?: string; handle?: string; bg?: boolean; subject?: string; yolo?: boolean }; data: AgentRecord };
621
620
  "agent:resume": { payload: { id: string; prompt?: string; surface?: AgentSurface; workspace?: string; tab?: string }; data: AgentRecord };
622
621
  "agent:get": { payload: { id: string }; data: AgentRecord };
623
622
  "agent:list": { payload: { repo?: string }; data: { agents: AgentRecord[] } };
@@ -712,7 +711,10 @@ export interface Commands {
712
711
  agent?: string;
713
712
  origin?: { surface?: string; tabId?: string; worktree?: string };
714
713
  };
715
- data: { id: string; presentation: "form" | "wait"; subject: string; supersededId: string | null };
714
+ /** `contextOmitted` appears only when the caller's context exceeded the
715
+ 8192-byte cap and was dropped: the gate still opened, but with none of
716
+ the material the reader needs. */
717
+ data: { id: string; presentation: "form" | "wait"; subject: string; supersededId: string | null; contextOmitted?: true };
716
718
  };
717
719
  /**
718
720
  * A CAS loss is a DEFINED OUTCOME, not an error: `ok:true` with
@@ -730,7 +732,10 @@ export interface Commands {
730
732
  "gate:answer": { payload: { id: string; answers: GateAnswer["answers"]; by: string; session?: string; override?: boolean }; data: { row: GateRow; conflict?: true } };
731
733
  /** `ok:false "not-found"` on an unknown id is terminal; the CLI loop must not re-enter on it.
732
734
  * `timeout` carries no row (nothing settled); `answered`/`closed` always carry the settled row. */
733
- "gate:wait": { payload: { id: string; waitMs?: number }; data: { status: "timeout" } | { status: "answered" | "closed"; row: GateRow } };
735
+ /** `sessionId` is the caller's own session: an answered result returned to
736
+ * the gate's nudged session is a recorded read and stamps `consumedAt`.
737
+ * Omitting it reads without consuming. */
738
+ "gate:wait": { payload: { id: string; waitMs?: number; sessionId?: string }; data: { status: "timeout" } | { status: "answered" | "closed"; row: GateRow } };
734
739
  /** Paged like events:list: an omitted `limit` clamps daemon-side rather than
735
740
  * forcing a full-table read; `cursor` is the paging rowid to resume from. */
736
741
  "gate:list": { payload: { open?: boolean; subjectPrefix?: string; kind?: string; limit?: number; cursor?: number }; data: { gates: GateRow[]; cursor: number } };
@@ -750,7 +755,7 @@ export interface Commands {
750
755
  "herd:list": { payload: { all?: boolean }; data: { herds: HerdListRow[] } };
751
756
  "herd:close": { payload: { herd: string; job: string }; data: { job: string; status: "closed"; /** Advisory: a resumable run can still write into this job's worktree after close, so this warns rather than blocking. */ warning?: string } };
752
757
  /** `brief` is the brief TEXT, not a path: the CLI reads the file. It is stored at `<jobsRoot>/<herd>/<job>/job.md`, so a respawn with `dir` and no `brief` reads it back. */
753
- "herd:spawn": { payload: { herd: string; job: string; brief?: string; dir?: string; model?: string; effort?: string; account?: string; disposable?: boolean }; data: { herd: string; job: string; pane: string; worktree: string; branch: string | null; tree: string | null; /** null = no provisioning ran (--dir); false = cold create, worth announcing. */ wasOnDeck: boolean | null; agentId: string; sessionId: string; handle: string } };
758
+ "herd:spawn": { payload: { herd: string; job: string; brief?: string; dir?: string; model?: string; effort?: string; account?: string; disposable?: boolean }; data: { herd: string; job: string; pane: string; worktree: string; branch: string | null; tree: string | null; /** null = no provisioning ran (--dir); false = cold create, worth announcing. */ wasOnDeck: boolean | null; agentId: string; sessionId: string; handle: string; /** What the folder-trust check established: no modal was up, one was accepted and verified gone, one is still up (the job reads `stuck-at-modal`), or herdr could not be read. */ trust: "none" | "accepted" | "stuck" | "unchecked" } };
754
759
  "herd:gates": { payload: { herd: string }; data: { gates: GateRow[] } };
755
760
  "herd:ask": { payload: { herd: string; job: string; session: string; pane?: string; questions: GateQuestion[]; context?: string }; data: { gate: string } };
756
761
  "herd:milestone": { payload: { herd: string; job: string; session: string; pane?: string; artifact: string; summary?: string }; data: { gate: string; message: number } };
@@ -666,35 +666,80 @@ export const REGISTRY: readonly SettingDef[] = [
666
666
  },
667
667
 
668
668
  // --- agent (rt agent handoff) --------------------------------------------
669
- // No defaults by design: an unset key means the flag is omitted from the
670
- // claude invocation entirely (spec "Settings").
669
+ // No defaults on any per-provider row, by design: an unset key means the
670
+ // flag is omitted from the launch entirely (spec "Settings"). agent.provider
671
+ // is the one exception -- it needs a concrete fallback to preserve
672
+ // claude-only behavior with zero code changes for callers who never set it.
671
673
  {
672
- key: "agent.model",
674
+ key: "agent.provider",
673
675
  type: "string",
674
676
  scopes: ["user", "machine"],
677
+ default: "claude",
675
678
  merge: "replace",
676
- description: "Default --model for rt agent launches; unset omits the flag.",
679
+ description: "Which provider rt agent start uses when --provider is not given: \"claude\" or \"codex\".",
677
680
  },
678
681
  {
679
- key: "agent.effort",
682
+ key: "agent.claude.model",
680
683
  type: "string",
681
684
  scopes: ["user", "machine"],
682
685
  merge: "replace",
683
- description: "Default --effort for rt agent launches; unset omits the flag.",
686
+ description: "Default --model for claude rt agent launches; unset omits the flag.",
684
687
  },
685
688
  {
686
- key: "agent.account",
689
+ key: "agent.claude.effort",
687
690
  type: "string",
688
691
  scopes: ["user", "machine"],
689
692
  merge: "replace",
690
- description: "cswap account email rt agent launches under; unset uses the default claude profile.",
693
+ description: "Default --effort for claude rt agent launches; unset omits the flag.",
691
694
  },
692
695
  {
693
- key: "agent.extraArgs",
696
+ key: "agent.claude.account",
694
697
  type: "string",
695
698
  scopes: ["user", "machine"],
696
699
  merge: "replace",
697
- description: "Opaque extra claude arguments appended to every rt agent launch (escape hatch).",
700
+ description: "cswap account email claude rt agent launches under; unset uses the default claude profile.",
701
+ },
702
+ {
703
+ key: "agent.claude.extraArgs",
704
+ type: "string",
705
+ scopes: ["user", "machine"],
706
+ merge: "replace",
707
+ description: "Opaque extra claude arguments appended to every claude rt agent launch (escape hatch).",
708
+ },
709
+ {
710
+ key: "agent.claude.yolo",
711
+ type: "boolean",
712
+ scopes: ["user", "machine"],
713
+ merge: "replace",
714
+ description: "Default --yolo (--dangerously-skip-permissions) for claude rt agent launches; unset behaves as false.",
715
+ },
716
+ {
717
+ key: "agent.codex.model",
718
+ type: "string",
719
+ scopes: ["user", "machine"],
720
+ merge: "replace",
721
+ description: "Default -m/--model for codex rt agent launches; unset omits the flag.",
722
+ },
723
+ {
724
+ key: "agent.codex.effort",
725
+ type: "string",
726
+ scopes: ["user", "machine"],
727
+ merge: "replace",
728
+ description: "Default reasoning effort for codex rt agent launches, passed as -c model_reasoning_effort=<value>; unset omits the override.",
729
+ },
730
+ {
731
+ key: "agent.codex.extraArgs",
732
+ type: "string",
733
+ scopes: ["user", "machine"],
734
+ merge: "replace",
735
+ description: "Opaque extra codex arguments appended to every codex rt agent launch (escape hatch).",
736
+ },
737
+ {
738
+ key: "agent.codex.yolo",
739
+ type: "boolean",
740
+ scopes: ["user", "machine"],
741
+ merge: "replace",
742
+ description: "Default --yolo (--dangerously-bypass-approvals-and-sandbox) for codex rt agent launches; unset behaves as false. codex has no per-agent account setting (see spec's Non-goals).",
698
743
  },
699
744
 
700
745
  // --- gates (escalation) ----------------------------------------------------