switchroom 0.13.47 → 0.13.49

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.
@@ -27507,6 +27507,206 @@ function verifyAuditLog(fullText) {
27507
27507
  var CHAIN_GENESIS = "GENESIS", SEP = "\x00";
27508
27508
  var init_audit_hashchain = () => {};
27509
27509
 
27510
+ // src/host-control/protocol.ts
27511
+ function buildEnvelope(code, human, fix, opts = {}) {
27512
+ return {
27513
+ v: 1,
27514
+ code,
27515
+ human,
27516
+ ...opts.why !== undefined ? { why: opts.why } : {},
27517
+ ...fix !== undefined ? { fix } : {},
27518
+ ...opts.docs !== undefined ? { docs: opts.docs } : {},
27519
+ ...opts.request_id !== undefined ? { request_id: opts.request_id } : {}
27520
+ };
27521
+ }
27522
+ function encodeRequest3(req) {
27523
+ const json = JSON.stringify(req);
27524
+ if (Buffer.byteLength(json, "utf8") > MAX_FRAME_BYTES3) {
27525
+ throw new Error(`hostd: request frame too large (${Buffer.byteLength(json, "utf8")} bytes; max ${MAX_FRAME_BYTES3})`);
27526
+ }
27527
+ return json + `
27528
+ `;
27529
+ }
27530
+ function decodeResponse3(line) {
27531
+ if (Buffer.byteLength(line, "utf8") > MAX_FRAME_BYTES3) {
27532
+ throw new RangeError(`hostd: response frame too large (${Buffer.byteLength(line, "utf8")} bytes; max ${MAX_FRAME_BYTES3})`);
27533
+ }
27534
+ const obj = JSON.parse(line);
27535
+ return ResponseSchema3.parse(obj);
27536
+ }
27537
+ var MAX_FRAME_BYTES3, RequestEnvelope, AgentRestartRequestSchema, UpgradeStatusRequestSchema, GetStatusRequestSchema, AgentNameSchema2, UpdateCheckRequestSchema, UpdateApplyRequestSchema, ApplyRequestSchema, AgentStartRequestSchema, AgentStopRequestSchema, AgentLogsRequestSchema, AgentExecRequestSchema, DoctorRequestSchema, AgentSmokeRequestSchema, ConfigProposeEditRequestSchema, RequestSchema3, ResultSchema, ErrorFixSchema, ErrorEnvelopeSchema, ResponseEnvelope, ResponseSchema3;
27538
+ var init_protocol3 = __esm(() => {
27539
+ init_zod();
27540
+ MAX_FRAME_BYTES3 = 64 * 1024;
27541
+ RequestEnvelope = {
27542
+ v: exports_external.literal(1),
27543
+ request_id: exports_external.string().min(1).max(128),
27544
+ idempotency_key: exports_external.string().min(1).max(128).optional()
27545
+ };
27546
+ AgentRestartRequestSchema = exports_external.object({
27547
+ ...RequestEnvelope,
27548
+ op: exports_external.literal("agent_restart"),
27549
+ args: exports_external.object({
27550
+ name: exports_external.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, "agent name must be kebab-case ASCII"),
27551
+ reason: exports_external.string().max(512).optional(),
27552
+ force: exports_external.boolean().optional()
27553
+ })
27554
+ });
27555
+ UpgradeStatusRequestSchema = exports_external.object({
27556
+ ...RequestEnvelope,
27557
+ op: exports_external.literal("upgrade_status"),
27558
+ args: exports_external.object({}).optional()
27559
+ });
27560
+ GetStatusRequestSchema = exports_external.object({
27561
+ ...RequestEnvelope,
27562
+ op: exports_external.literal("get_status"),
27563
+ args: exports_external.object({
27564
+ target_request_id: exports_external.string().min(1).max(128)
27565
+ })
27566
+ });
27567
+ AgentNameSchema2 = exports_external.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, "agent name must be kebab-case ASCII");
27568
+ UpdateCheckRequestSchema = exports_external.object({
27569
+ ...RequestEnvelope,
27570
+ op: exports_external.literal("update_check"),
27571
+ args: exports_external.object({}).optional()
27572
+ });
27573
+ UpdateApplyRequestSchema = exports_external.object({
27574
+ ...RequestEnvelope,
27575
+ op: exports_external.literal("update_apply"),
27576
+ args: exports_external.object({
27577
+ skip_images: exports_external.boolean().optional(),
27578
+ rebuild: exports_external.boolean().optional(),
27579
+ channel: exports_external.enum(["dev", "rc", "latest"]).nullable().optional(),
27580
+ pin: exports_external.string().regex(/^(sha-[0-9a-f]{7,40}|v\d+\.\d+\.\d+)$/).nullable().optional()
27581
+ }).optional()
27582
+ });
27583
+ ApplyRequestSchema = exports_external.object({
27584
+ ...RequestEnvelope,
27585
+ op: exports_external.literal("apply"),
27586
+ args: exports_external.object({}).optional()
27587
+ });
27588
+ AgentStartRequestSchema = exports_external.object({
27589
+ ...RequestEnvelope,
27590
+ op: exports_external.literal("agent_start"),
27591
+ args: exports_external.object({
27592
+ name: AgentNameSchema2
27593
+ })
27594
+ });
27595
+ AgentStopRequestSchema = exports_external.object({
27596
+ ...RequestEnvelope,
27597
+ op: exports_external.literal("agent_stop"),
27598
+ args: exports_external.object({
27599
+ name: AgentNameSchema2
27600
+ })
27601
+ });
27602
+ AgentLogsRequestSchema = exports_external.object({
27603
+ ...RequestEnvelope,
27604
+ op: exports_external.literal("agent_logs"),
27605
+ args: exports_external.object({
27606
+ name: AgentNameSchema2,
27607
+ tail: exports_external.number().int().positive().max(2000).optional()
27608
+ })
27609
+ });
27610
+ AgentExecRequestSchema = exports_external.object({
27611
+ ...RequestEnvelope,
27612
+ op: exports_external.literal("agent_exec"),
27613
+ args: exports_external.object({
27614
+ name: AgentNameSchema2,
27615
+ argv: exports_external.array(exports_external.string().min(1)).min(1).max(32)
27616
+ })
27617
+ });
27618
+ DoctorRequestSchema = exports_external.object({
27619
+ ...RequestEnvelope,
27620
+ op: exports_external.literal("doctor"),
27621
+ args: exports_external.object({}).optional()
27622
+ });
27623
+ AgentSmokeRequestSchema = exports_external.object({
27624
+ ...RequestEnvelope,
27625
+ op: exports_external.literal("agent_smoke"),
27626
+ args: exports_external.object({
27627
+ name: AgentNameSchema2,
27628
+ deep: exports_external.boolean().optional()
27629
+ })
27630
+ });
27631
+ ConfigProposeEditRequestSchema = exports_external.object({
27632
+ ...RequestEnvelope,
27633
+ op: exports_external.literal("config_propose_edit"),
27634
+ args: exports_external.object({
27635
+ unified_diff: exports_external.string().min(1).max(MAX_FRAME_BYTES3 - 1024),
27636
+ reason: exports_external.string().min(1).max(500),
27637
+ target_path: exports_external.literal("/state/config/switchroom.yaml")
27638
+ })
27639
+ });
27640
+ RequestSchema3 = exports_external.discriminatedUnion("op", [
27641
+ AgentRestartRequestSchema,
27642
+ UpgradeStatusRequestSchema,
27643
+ GetStatusRequestSchema,
27644
+ UpdateCheckRequestSchema,
27645
+ UpdateApplyRequestSchema,
27646
+ ApplyRequestSchema,
27647
+ AgentStartRequestSchema,
27648
+ AgentStopRequestSchema,
27649
+ AgentLogsRequestSchema,
27650
+ AgentExecRequestSchema,
27651
+ DoctorRequestSchema,
27652
+ AgentSmokeRequestSchema,
27653
+ ConfigProposeEditRequestSchema
27654
+ ]);
27655
+ ResultSchema = exports_external.enum(["started", "completed", "denied", "error"]);
27656
+ ErrorFixSchema = exports_external.discriminatedUnion("kind", [
27657
+ exports_external.object({
27658
+ kind: exports_external.literal("flip_yaml_flag"),
27659
+ yaml_path: exports_external.string(),
27660
+ to: exports_external.unknown()
27661
+ }),
27662
+ exports_external.object({
27663
+ kind: exports_external.literal("request_vault_grant"),
27664
+ vault_key: exports_external.string()
27665
+ }),
27666
+ exports_external.object({
27667
+ kind: exports_external.literal("operator_action"),
27668
+ subkind: exports_external.enum(["policy_denied", "infra", "out_of_scope"]),
27669
+ operator_steps: exports_external.array(exports_external.string()).min(1).optional()
27670
+ }),
27671
+ exports_external.object({
27672
+ kind: exports_external.literal("retry_after"),
27673
+ retry_at: exports_external.string()
27674
+ }),
27675
+ exports_external.object({
27676
+ kind: exports_external.literal("quota_exceeded"),
27677
+ quota: exports_external.string(),
27678
+ current: exports_external.number(),
27679
+ limit: exports_external.number()
27680
+ }),
27681
+ exports_external.object({
27682
+ kind: exports_external.literal("bad_input"),
27683
+ field: exports_external.string().optional()
27684
+ })
27685
+ ]);
27686
+ ErrorEnvelopeSchema = exports_external.object({
27687
+ v: exports_external.literal(1),
27688
+ code: exports_external.string().regex(/^(E_[A-Z0-9_]+|VAULT-[A-Z-]+)$/),
27689
+ human: exports_external.string().min(1),
27690
+ why: exports_external.string().optional(),
27691
+ fix: ErrorFixSchema.optional(),
27692
+ docs: exports_external.string().url().optional(),
27693
+ request_id: exports_external.string().min(1).optional()
27694
+ });
27695
+ ResponseEnvelope = {
27696
+ v: exports_external.literal(1),
27697
+ request_id: exports_external.string().min(1).max(128),
27698
+ result: ResultSchema,
27699
+ exit_code: exports_external.number().int().nullable(),
27700
+ duration_ms: exports_external.number().int().nonnegative(),
27701
+ audit_id: exports_external.string().min(1).optional(),
27702
+ stdout_tail: exports_external.string().optional(),
27703
+ stderr_tail: exports_external.string().optional(),
27704
+ error: exports_external.string().optional(),
27705
+ error_envelope: ErrorEnvelopeSchema.optional()
27706
+ };
27707
+ ResponseSchema3 = exports_external.object(ResponseEnvelope);
27708
+ });
27709
+
27510
27710
  // src/host-control/audit-reader.ts
27511
27711
  import { homedir as homedir18 } from "node:os";
27512
27712
  import { join as join35 } from "node:path";
@@ -29114,195 +29314,6 @@ var init_doctor_audit_integrity = __esm(() => {
29114
29314
  init_audit_hashchain();
29115
29315
  });
29116
29316
 
29117
- // src/host-control/protocol.ts
29118
- function encodeRequest3(req) {
29119
- const json = JSON.stringify(req);
29120
- if (Buffer.byteLength(json, "utf8") > MAX_FRAME_BYTES3) {
29121
- throw new Error(`hostd: request frame too large (${Buffer.byteLength(json, "utf8")} bytes; max ${MAX_FRAME_BYTES3})`);
29122
- }
29123
- return json + `
29124
- `;
29125
- }
29126
- function decodeResponse3(line) {
29127
- if (Buffer.byteLength(line, "utf8") > MAX_FRAME_BYTES3) {
29128
- throw new RangeError(`hostd: response frame too large (${Buffer.byteLength(line, "utf8")} bytes; max ${MAX_FRAME_BYTES3})`);
29129
- }
29130
- const obj = JSON.parse(line);
29131
- return ResponseSchema3.parse(obj);
29132
- }
29133
- var MAX_FRAME_BYTES3, RequestEnvelope, AgentRestartRequestSchema, UpgradeStatusRequestSchema, GetStatusRequestSchema, AgentNameSchema2, UpdateCheckRequestSchema, UpdateApplyRequestSchema, ApplyRequestSchema, AgentStartRequestSchema, AgentStopRequestSchema, AgentLogsRequestSchema, AgentExecRequestSchema, DoctorRequestSchema, AgentSmokeRequestSchema, ConfigProposeEditRequestSchema, RequestSchema3, ResultSchema, ErrorFixSchema, ErrorEnvelopeSchema, ResponseEnvelope, ResponseSchema3;
29134
- var init_protocol3 = __esm(() => {
29135
- init_zod();
29136
- MAX_FRAME_BYTES3 = 64 * 1024;
29137
- RequestEnvelope = {
29138
- v: exports_external.literal(1),
29139
- request_id: exports_external.string().min(1).max(128),
29140
- idempotency_key: exports_external.string().min(1).max(128).optional()
29141
- };
29142
- AgentRestartRequestSchema = exports_external.object({
29143
- ...RequestEnvelope,
29144
- op: exports_external.literal("agent_restart"),
29145
- args: exports_external.object({
29146
- name: exports_external.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, "agent name must be kebab-case ASCII"),
29147
- reason: exports_external.string().max(512).optional(),
29148
- force: exports_external.boolean().optional()
29149
- })
29150
- });
29151
- UpgradeStatusRequestSchema = exports_external.object({
29152
- ...RequestEnvelope,
29153
- op: exports_external.literal("upgrade_status"),
29154
- args: exports_external.object({}).optional()
29155
- });
29156
- GetStatusRequestSchema = exports_external.object({
29157
- ...RequestEnvelope,
29158
- op: exports_external.literal("get_status"),
29159
- args: exports_external.object({
29160
- target_request_id: exports_external.string().min(1).max(128)
29161
- })
29162
- });
29163
- AgentNameSchema2 = exports_external.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, "agent name must be kebab-case ASCII");
29164
- UpdateCheckRequestSchema = exports_external.object({
29165
- ...RequestEnvelope,
29166
- op: exports_external.literal("update_check"),
29167
- args: exports_external.object({}).optional()
29168
- });
29169
- UpdateApplyRequestSchema = exports_external.object({
29170
- ...RequestEnvelope,
29171
- op: exports_external.literal("update_apply"),
29172
- args: exports_external.object({
29173
- skip_images: exports_external.boolean().optional(),
29174
- rebuild: exports_external.boolean().optional(),
29175
- channel: exports_external.enum(["dev", "rc", "latest"]).nullable().optional(),
29176
- pin: exports_external.string().regex(/^(sha-[0-9a-f]{7,40}|v\d+\.\d+\.\d+)$/).nullable().optional()
29177
- }).optional()
29178
- });
29179
- ApplyRequestSchema = exports_external.object({
29180
- ...RequestEnvelope,
29181
- op: exports_external.literal("apply"),
29182
- args: exports_external.object({}).optional()
29183
- });
29184
- AgentStartRequestSchema = exports_external.object({
29185
- ...RequestEnvelope,
29186
- op: exports_external.literal("agent_start"),
29187
- args: exports_external.object({
29188
- name: AgentNameSchema2
29189
- })
29190
- });
29191
- AgentStopRequestSchema = exports_external.object({
29192
- ...RequestEnvelope,
29193
- op: exports_external.literal("agent_stop"),
29194
- args: exports_external.object({
29195
- name: AgentNameSchema2
29196
- })
29197
- });
29198
- AgentLogsRequestSchema = exports_external.object({
29199
- ...RequestEnvelope,
29200
- op: exports_external.literal("agent_logs"),
29201
- args: exports_external.object({
29202
- name: AgentNameSchema2,
29203
- tail: exports_external.number().int().positive().max(2000).optional()
29204
- })
29205
- });
29206
- AgentExecRequestSchema = exports_external.object({
29207
- ...RequestEnvelope,
29208
- op: exports_external.literal("agent_exec"),
29209
- args: exports_external.object({
29210
- name: AgentNameSchema2,
29211
- argv: exports_external.array(exports_external.string().min(1)).min(1).max(32)
29212
- })
29213
- });
29214
- DoctorRequestSchema = exports_external.object({
29215
- ...RequestEnvelope,
29216
- op: exports_external.literal("doctor"),
29217
- args: exports_external.object({}).optional()
29218
- });
29219
- AgentSmokeRequestSchema = exports_external.object({
29220
- ...RequestEnvelope,
29221
- op: exports_external.literal("agent_smoke"),
29222
- args: exports_external.object({
29223
- name: AgentNameSchema2,
29224
- deep: exports_external.boolean().optional()
29225
- })
29226
- });
29227
- ConfigProposeEditRequestSchema = exports_external.object({
29228
- ...RequestEnvelope,
29229
- op: exports_external.literal("config_propose_edit"),
29230
- args: exports_external.object({
29231
- unified_diff: exports_external.string().min(1).max(MAX_FRAME_BYTES3 - 1024),
29232
- reason: exports_external.string().min(1).max(500),
29233
- target_path: exports_external.literal("/state/config/switchroom.yaml")
29234
- })
29235
- });
29236
- RequestSchema3 = exports_external.discriminatedUnion("op", [
29237
- AgentRestartRequestSchema,
29238
- UpgradeStatusRequestSchema,
29239
- GetStatusRequestSchema,
29240
- UpdateCheckRequestSchema,
29241
- UpdateApplyRequestSchema,
29242
- ApplyRequestSchema,
29243
- AgentStartRequestSchema,
29244
- AgentStopRequestSchema,
29245
- AgentLogsRequestSchema,
29246
- AgentExecRequestSchema,
29247
- DoctorRequestSchema,
29248
- AgentSmokeRequestSchema,
29249
- ConfigProposeEditRequestSchema
29250
- ]);
29251
- ResultSchema = exports_external.enum(["started", "completed", "denied", "error"]);
29252
- ErrorFixSchema = exports_external.discriminatedUnion("kind", [
29253
- exports_external.object({
29254
- kind: exports_external.literal("flip_yaml_flag"),
29255
- yaml_path: exports_external.string(),
29256
- to: exports_external.unknown()
29257
- }),
29258
- exports_external.object({
29259
- kind: exports_external.literal("request_vault_grant"),
29260
- vault_key: exports_external.string()
29261
- }),
29262
- exports_external.object({
29263
- kind: exports_external.literal("operator_action"),
29264
- subkind: exports_external.enum(["policy_denied", "infra", "out_of_scope"]),
29265
- operator_steps: exports_external.array(exports_external.string()).min(1).optional()
29266
- }),
29267
- exports_external.object({
29268
- kind: exports_external.literal("retry_after"),
29269
- retry_at: exports_external.string()
29270
- }),
29271
- exports_external.object({
29272
- kind: exports_external.literal("quota_exceeded"),
29273
- quota: exports_external.string(),
29274
- current: exports_external.number(),
29275
- limit: exports_external.number()
29276
- }),
29277
- exports_external.object({
29278
- kind: exports_external.literal("bad_input"),
29279
- field: exports_external.string().optional()
29280
- })
29281
- ]);
29282
- ErrorEnvelopeSchema = exports_external.object({
29283
- v: exports_external.literal(1),
29284
- code: exports_external.string().regex(/^(E_[A-Z0-9_]+|VAULT-[A-Z-]+)$/),
29285
- human: exports_external.string().min(1),
29286
- why: exports_external.string().optional(),
29287
- fix: ErrorFixSchema.optional(),
29288
- docs: exports_external.string().url().optional(),
29289
- request_id: exports_external.string().min(1)
29290
- });
29291
- ResponseEnvelope = {
29292
- v: exports_external.literal(1),
29293
- request_id: exports_external.string().min(1).max(128),
29294
- result: ResultSchema,
29295
- exit_code: exports_external.number().int().nullable(),
29296
- duration_ms: exports_external.number().int().nonnegative(),
29297
- audit_id: exports_external.string().min(1).optional(),
29298
- stdout_tail: exports_external.string().optional(),
29299
- stderr_tail: exports_external.string().optional(),
29300
- error: exports_external.string().optional(),
29301
- error_envelope: ErrorEnvelopeSchema.optional()
29302
- };
29303
- ResponseSchema3 = exports_external.object(ResponseEnvelope);
29304
- });
29305
-
29306
29317
  // src/host-control/client.ts
29307
29318
  import { connect as connect2 } from "node:net";
29308
29319
  async function hostdRequest(opts, req) {
@@ -47902,8 +47913,8 @@ var {
47902
47913
  } = import__.default;
47903
47914
 
47904
47915
  // src/build-info.ts
47905
- var VERSION = "0.13.47";
47906
- var COMMIT_SHA = "f8dcdada";
47916
+ var VERSION = "0.13.49";
47917
+ var COMMIT_SHA = "d8226915";
47907
47918
 
47908
47919
  // src/cli/agent.ts
47909
47920
  init_source();
@@ -49944,6 +49955,16 @@ function buildSettingsHooksBlock(p) {
49944
49955
  timeout: 5
49945
49956
  }
49946
49957
  ]
49958
+ },
49959
+ {
49960
+ matcher: "^(Read|Edit|Write|MultiEdit|NotebookEdit|Bash)$",
49961
+ hooks: [
49962
+ {
49963
+ type: "command",
49964
+ command: wrap("hook:repo-context-pretool", `node "${join8(DOCKER_HOOKS_PATH, "repo-context-pretool.mjs")}"`),
49965
+ timeout: 5
49966
+ }
49967
+ ]
49947
49968
  }
49948
49969
  ] : [];
49949
49970
  const switchroomPostToolUse = useSwitchroomPlugin ? [
@@ -61651,18 +61672,10 @@ function registerVaultBackupCommand(vault, program3) {
61651
61672
  }
61652
61673
 
61653
61674
  // src/cli/vault-denied-envelope.ts
61675
+ init_protocol3();
61654
61676
  var ENVELOPE_SENTINEL = "ERROR-ENVELOPE:";
61655
61677
  function writeVaultDeniedEnvelope(vaultKey, brokerCode, human) {
61656
- const envelope = {
61657
- v: 1,
61658
- code: "VAULT-BROKER-DENIED",
61659
- human: `${brokerCode}: ${human}`,
61660
- fix: {
61661
- kind: "request_vault_grant",
61662
- vault_key: vaultKey
61663
- },
61664
- request_id: `vault-cli-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`
61665
- };
61678
+ const envelope = buildEnvelope("VAULT-BROKER-DENIED", `${brokerCode}: ${human}`, { kind: "request_vault_grant", vault_key: vaultKey });
61666
61679
  process.stderr.write(`${ENVELOPE_SENTINEL} ${JSON.stringify(envelope)}
61667
61680
  `);
61668
61681
  }
@@ -76297,8 +76310,8 @@ function denyPendingScheduleEntry(opts) {
76297
76310
  }
76298
76311
 
76299
76312
  // src/cli/agent-config-write.ts
76313
+ init_protocol3();
76300
76314
  import { existsSync as existsSync73, readFileSync as readFileSync59 } from "node:fs";
76301
- import { randomUUID as randomUUID5 } from "node:crypto";
76302
76315
  var MAX_ENTRIES_PER_AGENT = 20;
76303
76316
  var MIN_CRON_INTERVAL_MIN = 5;
76304
76317
  function extractCronSmallestGapMin(expr) {
@@ -76339,35 +76352,22 @@ function checkOperatorContext(verb, env2 = process.env) {
76339
76352
  return { ok: true };
76340
76353
  }
76341
76354
  function buildEnvelopeForCode(code, message, extra) {
76342
- const request_id = `agent-config-${randomUUID5()}`;
76343
76355
  if (code === "E_CRON_TOO_FREQUENT") {
76344
- return {
76345
- v: 1,
76346
- code,
76347
- human: message,
76348
- fix: {
76349
- kind: "quota_exceeded",
76350
- quota: "cron_min_interval_minutes",
76351
- current: typeof extra.requested_interval_min === "number" ? extra.requested_interval_min : 0,
76352
- limit: MIN_CRON_INTERVAL_MIN
76353
- },
76354
- request_id
76355
- };
76356
+ return buildEnvelope(code, message, {
76357
+ kind: "quota_exceeded",
76358
+ quota: "cron_min_interval_minutes",
76359
+ current: typeof extra.requested_interval_min === "number" ? extra.requested_interval_min : 0,
76360
+ limit: MIN_CRON_INTERVAL_MIN
76361
+ });
76356
76362
  }
76357
76363
  if (code === "E_QUOTA_EXCEEDED") {
76358
76364
  const current = typeof extra.current === "number" ? extra.current : MAX_ENTRIES_PER_AGENT;
76359
- return {
76360
- v: 1,
76361
- code,
76362
- human: message,
76363
- fix: {
76364
- kind: "quota_exceeded",
76365
- quota: "schedule_entries_per_agent",
76366
- current,
76367
- limit: MAX_ENTRIES_PER_AGENT
76368
- },
76369
- request_id
76370
- };
76365
+ return buildEnvelope(code, message, {
76366
+ kind: "quota_exceeded",
76367
+ quota: "schedule_entries_per_agent",
76368
+ current,
76369
+ limit: MAX_ENTRIES_PER_AGENT
76370
+ });
76371
76371
  }
76372
76372
  return;
76373
76373
  }
@@ -14880,8 +14880,19 @@ var ErrorEnvelopeSchema = exports_external.object({
14880
14880
  why: exports_external.string().optional(),
14881
14881
  fix: ErrorFixSchema.optional(),
14882
14882
  docs: exports_external.string().url().optional(),
14883
- request_id: exports_external.string().min(1)
14883
+ request_id: exports_external.string().min(1).optional()
14884
14884
  });
14885
+ function buildEnvelope(code, human, fix, opts = {}) {
14886
+ return {
14887
+ v: 1,
14888
+ code,
14889
+ human,
14890
+ ...opts.why !== undefined ? { why: opts.why } : {},
14891
+ ...fix !== undefined ? { fix } : {},
14892
+ ...opts.docs !== undefined ? { docs: opts.docs } : {},
14893
+ ...opts.request_id !== undefined ? { request_id: opts.request_id } : {}
14894
+ };
14895
+ }
14885
14896
  var ResponseEnvelope = {
14886
14897
  v: exports_external.literal(1),
14887
14898
  request_id: exports_external.string().min(1).max(128),
@@ -19530,15 +19541,11 @@ class ErrorBuilder {
19530
19541
  return this;
19531
19542
  }
19532
19543
  build(requestId, durationMs) {
19533
- const envelope = {
19534
- v: 1,
19535
- code: this._code,
19536
- human: this._human,
19537
- ...this._why !== undefined ? { why: this._why } : {},
19538
- ...this._fix !== undefined ? { fix: this._fix } : {},
19539
- ...this._docs !== undefined ? { docs: this._docs } : {},
19544
+ const envelope = buildEnvelope(this._code, this._human, this._fix, {
19545
+ why: this._why,
19546
+ docs: this._docs,
19540
19547
  request_id: requestId
19541
- };
19548
+ });
19542
19549
  const legacy = `${this._code}: ${this._human}` + (this._why ? ` — ${this._why}` : "");
19543
19550
  const ctx = {
19544
19551
  op: this._op,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchroom",
3
- "version": "0.13.47",
3
+ "version": "0.13.49",
4
4
  "description": "Run Claude Code 24/7 on your Claude Pro/Max subscription over Telegram. Open-source alternative to OpenClaw and NanoClaw — no API keys.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -43456,7 +43456,7 @@ var ErrorEnvelopeSchema = exports_external.object({
43456
43456
  why: exports_external.string().optional(),
43457
43457
  fix: ErrorFixSchema.optional(),
43458
43458
  docs: exports_external.string().url().optional(),
43459
- request_id: exports_external.string().min(1)
43459
+ request_id: exports_external.string().min(1).optional()
43460
43460
  });
43461
43461
  var ResponseEnvelope = {
43462
43462
  v: exports_external.literal(1),
@@ -48732,10 +48732,10 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
48732
48732
  }
48733
48733
 
48734
48734
  // ../src/build-info.ts
48735
- var VERSION = "0.13.47";
48736
- var COMMIT_SHA = "f8dcdada";
48737
- var COMMIT_DATE = "2026-05-25T19:41:23Z";
48738
- var LATEST_PR = 1835;
48735
+ var VERSION = "0.13.49";
48736
+ var COMMIT_SHA = "d8226915";
48737
+ var COMMIT_DATE = "2026-05-25T21:14:02Z";
48738
+ var LATEST_PR = 1840;
48739
48739
  var COMMITS_AHEAD_OF_TAG = 0;
48740
48740
 
48741
48741
  // gateway/boot-version.ts
@@ -28,6 +28,16 @@
28
28
  "timeout": 5
29
29
  }
30
30
  ]
31
+ },
32
+ {
33
+ "matcher": "^(Read|Edit|Write|MultiEdit|NotebookEdit|Bash)$",
34
+ "hooks": [
35
+ {
36
+ "type": "command",
37
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/repo-context-pretool.mjs\"",
38
+ "timeout": 5
39
+ }
40
+ ]
31
41
  }
32
42
  ],
33
43
  "PostToolUse": [