reflex-skills 0.5.0 → 0.5.1

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/dist/reflex.js CHANGED
@@ -590,8 +590,8 @@ var require_help = __commonJS({
590
590
  helper.visibleCommands(cmd),
591
591
  (sub) => sub.helpGroup() || "Commands:"
592
592
  );
593
- commandGroups.forEach((commands, group) => {
594
- const commandList = commands.map((sub) => {
593
+ commandGroups.forEach((commands2, group) => {
594
+ const commandList = commands2.map((sub) => {
595
595
  return callFormatItem(
596
596
  helper.styleSubcommandTerm(helper.subcommandTerm(sub)),
597
597
  helper.styleSubcommandDescription(helper.subcommandDescription(sub))
@@ -742,8 +742,8 @@ ${itemIndentStr}`);
742
742
  const rawLines = str3.split(/\r\n|\n/);
743
743
  const chunkPattern = /[\s]*[^\s]+/g;
744
744
  const wrappedLines = [];
745
- rawLines.forEach((line) => {
746
- const chunks = line.match(chunkPattern);
745
+ rawLines.forEach((line2) => {
746
+ const chunks = line2.match(chunkPattern);
747
747
  if (chunks === null) {
748
748
  wrappedLines.push("");
749
749
  return;
@@ -3571,12 +3571,103 @@ var require_picocolors = __commonJS({
3571
3571
  });
3572
3572
 
3573
3573
  // src/guard.ts
3574
+ import dgram from "node:dgram";
3575
+ import dns from "node:dns";
3576
+ import { syncBuiltinESMExports } from "node:module";
3574
3577
  import net from "node:net";
3578
+ import threads from "node:worker_threads";
3579
+ var MESSAGE = "Reflex does not make network connections";
3580
+ var MODEL_HOSTS = ["huggingface.co", "hf.co"];
3581
+ var DNS_QUERIES = /^(lookup|lookupService|resolve\w*|reverse)$/;
3582
+ var WORKER_GUARD = `{
3583
+ const blocked = () => { throw new Error(${JSON.stringify(`${MESSAGE}.`)}); };
3584
+ const get = process.getBuiltinModule;
3585
+ get("node:net").Socket.prototype.connect = blocked;
3586
+ const udp = get("node:dgram").Socket.prototype;
3587
+ udp.send = udp.connect = blocked;
3588
+ const dns = get("node:dns");
3589
+ for (const target of [dns, dns.promises, dns.Resolver.prototype, dns.promises.Resolver.prototype])
3590
+ for (const key of Object.getOwnPropertyNames(target))
3591
+ if (${DNS_QUERIES}.test(key) && typeof target[key] === "function") target[key] = blocked;
3592
+ }`;
3593
+ var allowed = [];
3594
+ function hostAllowed(host) {
3595
+ if (typeof host !== "string") return false;
3596
+ const h2 = host.toLowerCase().replace(/\.$/, "");
3597
+ return allowed.some((a) => h2 === a || h2.endsWith(`.${a}`));
3598
+ }
3599
+ function connectHost(args) {
3600
+ const first = Array.isArray(args[0]) ? args[0][0] : args[0];
3601
+ if (typeof first === "object" && first !== null) {
3602
+ const o2 = first;
3603
+ return o2.path === void 0 ? o2.host ?? "localhost" : void 0;
3604
+ }
3605
+ if (typeof first === "number" || /^\d+$/.test(String(first))) return typeof args[1] === "string" ? args[1] : "localhost";
3606
+ return void 0;
3607
+ }
3608
+ var refuse = (host) => {
3609
+ throw new Error(typeof host === "string" ? `${MESSAGE} (blocked ${host}).` : `${MESSAGE}.`);
3610
+ };
3575
3611
  function installNetworkGuard() {
3576
- const blocked = function connect() {
3577
- throw new Error("Reflex does not make network connections.");
3612
+ const undo = [];
3613
+ const patch = (target, key3, make) => {
3614
+ const t = target;
3615
+ const original = t[key3];
3616
+ t[key3] = make(original);
3617
+ undo.push(() => t[key3] = original);
3618
+ };
3619
+ patch(
3620
+ net.Socket.prototype,
3621
+ "connect",
3622
+ (original) => function connect(...args) {
3623
+ const host = connectHost(args);
3624
+ return hostAllowed(host) ? original.apply(this, args) : refuse(host);
3625
+ }
3626
+ );
3627
+ for (const key3 of ["send", "connect"]) patch(dgram.Socket.prototype, key3, () => () => refuse(void 0));
3628
+ for (const target of [dns, dns.promises, dns.Resolver.prototype, dns.promises.Resolver.prototype]) {
3629
+ for (const key3 of Object.getOwnPropertyNames(target)) {
3630
+ if (!DNS_QUERIES.test(key3) || typeof target[key3] !== "function") continue;
3631
+ patch(
3632
+ target,
3633
+ key3,
3634
+ (original) => key3 === "lookup" ? function lookup(...args) {
3635
+ return hostAllowed(args[0]) ? original.apply(this, args) : refuse(args[0]);
3636
+ } : () => refuse(void 0)
3637
+ );
3638
+ }
3639
+ }
3640
+ const Base = threads.Worker;
3641
+ class GuardedWorker extends Base {
3642
+ constructor(filename, options = {}) {
3643
+ const inline = options.eval === true && typeof filename === "string";
3644
+ const guard = ["--import", `data:text/javascript,${encodeURIComponent(WORKER_GUARD)}`];
3645
+ super(inline ? `${WORKER_GUARD}
3646
+ ${filename}` : filename, inline ? options : { ...options, execArgv: [...options.execArgv ?? process.execArgv, ...guard] });
3647
+ }
3648
+ }
3649
+ patch(threads, "Worker", () => GuardedWorker);
3650
+ syncBuiltinESMExports();
3651
+ return () => {
3652
+ for (const fn of undo.reverse()) fn();
3653
+ syncBuiltinESMExports();
3654
+ };
3655
+ }
3656
+ function allowHosts(hosts) {
3657
+ const before = allowed;
3658
+ allowed = [...before, ...hosts, ...proxyHosts()];
3659
+ return () => {
3660
+ allowed = before;
3578
3661
  };
3579
- net.Socket.prototype.connect = blocked;
3662
+ }
3663
+ function proxyHosts() {
3664
+ if (!process.env.NODE_USE_ENV_PROXY) return [];
3665
+ const url2 = process.env.HTTPS_PROXY ?? process.env.https_proxy;
3666
+ try {
3667
+ return url2 ? [new URL(url2).hostname.toLowerCase()] : [];
3668
+ } catch {
3669
+ return [];
3670
+ }
3580
3671
  }
3581
3672
  function quietSqliteWarning() {
3582
3673
  const listeners = process.listeners("warning");
@@ -4286,8 +4377,8 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
4286
4377
  var import_picocolors3 = __toESM(require_picocolors(), 1);
4287
4378
  var c = import_picocolors3.default;
4288
4379
  var interactive = () => Boolean(process.stdin.isTTY && process.stdout.isTTY);
4289
- function out(line = "") {
4290
- process.stdout.write(line + "\n");
4380
+ function out(line2 = "") {
4381
+ process.stdout.write(line2 + "\n");
4291
4382
  }
4292
4383
  function title(text) {
4293
4384
  out();
@@ -4359,7 +4450,7 @@ async function ask(message, initial, validate3) {
4359
4450
  }
4360
4451
  function fileBlock(path, content) {
4361
4452
  out(c.dim(`\u250C\u2500 ${path}`));
4362
- for (const line of content.trimEnd().split("\n")) out(`${c.dim("\u2502")} ${line}`);
4453
+ for (const line2 of content.trimEnd().split("\n")) out(`${c.dim("\u2502")} ${line2}`);
4363
4454
  out(c.dim("\u2514\u2500"));
4364
4455
  }
4365
4456
  function spinner() {
@@ -6473,8 +6564,8 @@ function emoji() {
6473
6564
  }
6474
6565
  var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
6475
6566
  var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
6476
- var mac = (delimiter4) => {
6477
- const escapedDelim = escapeRegex(delimiter4 ?? ":");
6567
+ var mac = (delimiter3) => {
6568
+ const escapedDelim = escapeRegex(delimiter3 ?? ":");
6478
6569
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
6479
6570
  };
6480
6571
  var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -7048,8 +7139,8 @@ var Doc = class {
7048
7139
  const lines = content.split("\n").filter((x2) => x2);
7049
7140
  const minIndent = Math.min(...lines.map((x2) => x2.length - x2.trimStart().length));
7050
7141
  const dedented = lines.map((x2) => x2.slice(minIndent)).map((x2) => " ".repeat(this.indent * 2) + x2);
7051
- for (const line of dedented) {
7052
- this.content.push(line);
7142
+ for (const line2 of dedented) {
7143
+ this.content.push(line2);
7053
7144
  }
7054
7145
  }
7055
7146
  compile() {
@@ -17337,10 +17428,10 @@ var $ZodRegistry = class {
17337
17428
  this._idmap = /* @__PURE__ */ new Map();
17338
17429
  }
17339
17430
  add(schema, ..._meta) {
17340
- const meta3 = _meta[0];
17341
- this._map.set(schema, meta3);
17342
- if (meta3 && typeof meta3 === "object" && "id" in meta3) {
17343
- this._idmap.set(meta3.id, schema);
17431
+ const meta4 = _meta[0];
17432
+ this._map.set(schema, meta4);
17433
+ if (meta4 && typeof meta4 === "object" && "id" in meta4) {
17434
+ this._idmap.set(meta4.id, schema);
17344
17435
  }
17345
17436
  return this;
17346
17437
  }
@@ -17350,9 +17441,9 @@ var $ZodRegistry = class {
17350
17441
  return this;
17351
17442
  }
17352
17443
  remove(schema) {
17353
- const meta3 = this._map.get(schema);
17354
- if (meta3 && typeof meta3 === "object" && "id" in meta3) {
17355
- this._idmap.delete(meta3.id);
17444
+ const meta4 = this._map.get(schema);
17445
+ if (meta4 && typeof meta4 === "object" && "id" in meta4) {
17446
+ this._idmap.delete(meta4.id);
17356
17447
  }
17357
17448
  this._map.delete(schema);
17358
17449
  return this;
@@ -20074,13 +20165,13 @@ function initializeContext(params) {
20074
20165
  external: params?.external ?? void 0
20075
20166
  };
20076
20167
  }
20077
- function handleUnrepresentable(schema, ctx, json2, params, message) {
20168
+ function handleUnrepresentable(schema, ctx, json3, params, message) {
20078
20169
  const result = typeof ctx.unrepresentable === "function" ? ctx.unrepresentable({ zodSchema: schema, path: params.path, message }) : ctx.unrepresentable;
20079
20170
  if (result === "any")
20080
20171
  return false;
20081
20172
  if (result === void 0 || result === "throw")
20082
20173
  throw new Error(message);
20083
- Object.assign(json2, result);
20174
+ Object.assign(json3, result);
20084
20175
  return true;
20085
20176
  }
20086
20177
  function processSchema(schema, ctx, _params = { path: [], schemaPath: [] }) {
@@ -20126,9 +20217,9 @@ function processSchema(schema, ctx, _params = { path: [], schemaPath: [] }) {
20126
20217
  ctx.seen.get(parent).isParent = true;
20127
20218
  }
20128
20219
  }
20129
- const meta3 = ctx.metadataRegistry.get(schema);
20130
- if (meta3)
20131
- assignProps(result.schema, meta3);
20220
+ const meta4 = ctx.metadataRegistry.get(schema);
20221
+ if (meta4)
20222
+ assignProps(result.schema, meta4);
20132
20223
  if (ctx.io === "input" && isTransforming(schema)) {
20133
20224
  delete result.schema.examples;
20134
20225
  delete result.schema.default;
@@ -20316,12 +20407,12 @@ function foldObjects(members2) {
20316
20407
  }
20317
20408
  return folded;
20318
20409
  }
20319
- function foldIntersection(json2) {
20320
- const allOf = json2.allOf;
20410
+ function foldIntersection(json3) {
20411
+ const allOf = json3.allOf;
20321
20412
  if (!Array.isArray(allOf) || allOf.length < 2)
20322
20413
  return;
20323
20414
  for (const key3 of FOLDABLE_KEYS)
20324
- if (key3 in json2)
20415
+ if (key3 in json3)
20325
20416
  return;
20326
20417
  const unions = allOf.filter((m2) => UNION_KEYS.some((k3) => Array.isArray(m2[k3])));
20327
20418
  let folded = null;
@@ -20340,8 +20431,8 @@ function foldIntersection(json2) {
20340
20431
  }
20341
20432
  if (!folded)
20342
20433
  return;
20343
- delete json2.allOf;
20344
- assignProps(json2, folded);
20434
+ delete json3.allOf;
20435
+ assignProps(json3, folded);
20345
20436
  }
20346
20437
  function finalize(ctx, schema) {
20347
20438
  const root = ctx.seen.get(schema);
@@ -20423,20 +20514,20 @@ function finalize(ctx, schema) {
20423
20514
  if (ctx.intersections.length) {
20424
20515
  const carriers = /* @__PURE__ */ new Map();
20425
20516
  for (const seen of ctx.seen.values()) {
20426
- for (const json2 of [seen.schema, seen.def]) {
20427
- const allOf = json2?.allOf;
20517
+ for (const json3 of [seen.schema, seen.def]) {
20518
+ const allOf = json3?.allOf;
20428
20519
  if (!Array.isArray(allOf))
20429
20520
  continue;
20430
20521
  const existing = carriers.get(allOf);
20431
20522
  if (existing)
20432
- existing.push(json2);
20523
+ existing.push(json3);
20433
20524
  else
20434
- carriers.set(allOf, [json2]);
20525
+ carriers.set(allOf, [json3]);
20435
20526
  }
20436
20527
  }
20437
20528
  for (const allOf of ctx.intersections) {
20438
- for (const json2 of carriers.get(allOf) ?? [])
20439
- foldIntersection(json2);
20529
+ for (const json3 of carriers.get(allOf) ?? [])
20530
+ foldIntersection(json3);
20440
20531
  }
20441
20532
  }
20442
20533
  }
@@ -20671,29 +20762,29 @@ var exactPatterns = /* @__PURE__ */ new Map([
20671
20762
  ]);
20672
20763
  var exactPattern = (p3) => exactPatterns.get(p3) ?? p3;
20673
20764
  var stringProcessor = (schema, ctx, _json, _params) => {
20674
- const json2 = _json;
20675
- json2.type = "string";
20765
+ const json3 = _json;
20766
+ json3.type = "string";
20676
20767
  const { minimum, maximum, format, patterns, contentEncoding, laxFormat } = aggregateChecks(schema);
20677
20768
  if (typeof minimum === "number")
20678
- json2.minLength = minimum;
20769
+ json3.minLength = minimum;
20679
20770
  if (typeof maximum === "number")
20680
- json2.maxLength = maximum;
20771
+ json3.maxLength = maximum;
20681
20772
  if (format) {
20682
- json2.format = formatMap[format] ?? format;
20683
- if (json2.format === "")
20684
- delete json2.format;
20773
+ json3.format = formatMap[format] ?? format;
20774
+ if (json3.format === "")
20775
+ delete json3.format;
20685
20776
  if (format === "time" || laxFormat) {
20686
- delete json2.format;
20777
+ delete json3.format;
20687
20778
  }
20688
20779
  }
20689
20780
  if (contentEncoding)
20690
- json2.contentEncoding = contentEncoding;
20781
+ json3.contentEncoding = contentEncoding;
20691
20782
  if (patterns && patterns.size > 0) {
20692
20783
  const patternList = [...patterns].map(exactPattern);
20693
20784
  if (patternList.length === 1)
20694
- json2.pattern = patternList[0].source;
20785
+ json3.pattern = patternList[0].source;
20695
20786
  else if (patternList.length > 1) {
20696
- json2.allOf = [
20787
+ json3.allOf = [
20697
20788
  ...patternList.map((regex) => ({
20698
20789
  ...ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0" ? { type: "string" } : {},
20699
20790
  pattern: regex.source
@@ -20703,31 +20794,31 @@ var stringProcessor = (schema, ctx, _json, _params) => {
20703
20794
  }
20704
20795
  };
20705
20796
  var numberProcessor = (schema, ctx, _json, params) => {
20706
- const json2 = _json;
20797
+ const json3 = _json;
20707
20798
  const { minimum, maximum, multipleOf, exclusiveMaximum, exclusiveMinimum, isInt: isInt2 } = aggregateChecks(schema);
20708
- json2.type = isInt2 ? "integer" : "number";
20799
+ json3.type = isInt2 ? "integer" : "number";
20709
20800
  const exMin = typeof exclusiveMinimum === "number" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);
20710
20801
  const exMax = typeof exclusiveMaximum === "number" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);
20711
20802
  const legacy = ctx.target === "draft-04" || ctx.target === "openapi-3.0";
20712
20803
  if (exMin) {
20713
20804
  if (legacy) {
20714
- json2.minimum = exclusiveMinimum;
20715
- json2.exclusiveMinimum = true;
20805
+ json3.minimum = exclusiveMinimum;
20806
+ json3.exclusiveMinimum = true;
20716
20807
  } else {
20717
- json2.exclusiveMinimum = exclusiveMinimum;
20808
+ json3.exclusiveMinimum = exclusiveMinimum;
20718
20809
  }
20719
20810
  } else if (typeof minimum === "number") {
20720
- json2.minimum = minimum;
20811
+ json3.minimum = minimum;
20721
20812
  }
20722
20813
  if (exMax) {
20723
20814
  if (legacy) {
20724
- json2.maximum = exclusiveMaximum;
20725
- json2.exclusiveMaximum = true;
20815
+ json3.maximum = exclusiveMaximum;
20816
+ json3.exclusiveMaximum = true;
20726
20817
  } else {
20727
- json2.exclusiveMaximum = exclusiveMaximum;
20818
+ json3.exclusiveMaximum = exclusiveMaximum;
20728
20819
  }
20729
20820
  } else if (typeof maximum === "number") {
20730
- json2.maximum = maximum;
20821
+ json3.maximum = maximum;
20731
20822
  }
20732
20823
  if (multipleOf) {
20733
20824
  const divisors = /* @__PURE__ */ new Set();
@@ -20735,75 +20826,75 @@ var numberProcessor = (schema, ctx, _json, params) => {
20735
20826
  if (Number.isFinite(divisor) && divisor !== 0)
20736
20827
  divisors.add(Math.abs(divisor));
20737
20828
  else
20738
- handleUnrepresentable(schema, ctx, json2, params, `A multipleOf divisor of ${divisor} cannot be represented in JSON Schema`);
20829
+ handleUnrepresentable(schema, ctx, json3, params, `A multipleOf divisor of ${divisor} cannot be represented in JSON Schema`);
20739
20830
  }
20740
20831
  const [first, ...rest] = divisors;
20741
20832
  if (first !== void 0)
20742
- json2.multipleOf = first;
20833
+ json3.multipleOf = first;
20743
20834
  if (rest.length)
20744
- json2.allOf = [...json2.allOf ?? [], ...rest.map((m2) => ({ multipleOf: m2 }))];
20835
+ json3.allOf = [...json3.allOf ?? [], ...rest.map((m2) => ({ multipleOf: m2 }))];
20745
20836
  }
20746
20837
  };
20747
- var booleanProcessor = (_schema, _ctx, json2, _params) => {
20748
- json2.type = "boolean";
20838
+ var booleanProcessor = (_schema, _ctx, json3, _params) => {
20839
+ json3.type = "boolean";
20749
20840
  };
20750
- var bigintProcessor = (schema, ctx, json2, params) => {
20751
- handleUnrepresentable(schema, ctx, json2, params, "BigInt cannot be represented in JSON Schema");
20841
+ var bigintProcessor = (schema, ctx, json3, params) => {
20842
+ handleUnrepresentable(schema, ctx, json3, params, "BigInt cannot be represented in JSON Schema");
20752
20843
  };
20753
- var symbolProcessor = (schema, ctx, json2, params) => {
20754
- handleUnrepresentable(schema, ctx, json2, params, "Symbols cannot be represented in JSON Schema");
20844
+ var symbolProcessor = (schema, ctx, json3, params) => {
20845
+ handleUnrepresentable(schema, ctx, json3, params, "Symbols cannot be represented in JSON Schema");
20755
20846
  };
20756
- var nullProcessor = (_schema, ctx, json2, _params) => {
20847
+ var nullProcessor = (_schema, ctx, json3, _params) => {
20757
20848
  if (ctx.target === "openapi-3.0") {
20758
- json2.type = "string";
20759
- json2.nullable = true;
20760
- json2.enum = [null];
20849
+ json3.type = "string";
20850
+ json3.nullable = true;
20851
+ json3.enum = [null];
20761
20852
  } else {
20762
- json2.type = "null";
20853
+ json3.type = "null";
20763
20854
  }
20764
20855
  };
20765
- var undefinedProcessor = (schema, ctx, json2, params) => {
20766
- handleUnrepresentable(schema, ctx, json2, params, "Undefined cannot be represented in JSON Schema");
20856
+ var undefinedProcessor = (schema, ctx, json3, params) => {
20857
+ handleUnrepresentable(schema, ctx, json3, params, "Undefined cannot be represented in JSON Schema");
20767
20858
  };
20768
- var voidProcessor = (schema, ctx, json2, params) => {
20769
- handleUnrepresentable(schema, ctx, json2, params, "Void cannot be represented in JSON Schema");
20859
+ var voidProcessor = (schema, ctx, json3, params) => {
20860
+ handleUnrepresentable(schema, ctx, json3, params, "Void cannot be represented in JSON Schema");
20770
20861
  };
20771
- var neverProcessor = (_schema, _ctx, json2, _params) => {
20772
- json2.not = {};
20862
+ var neverProcessor = (_schema, _ctx, json3, _params) => {
20863
+ json3.not = {};
20773
20864
  };
20774
20865
  var anyProcessor = (_schema, _ctx, _json, _params) => {
20775
20866
  };
20776
20867
  var unknownProcessor = (_schema, _ctx, _json, _params) => {
20777
20868
  };
20778
- var dateProcessor = (schema, ctx, json2, params) => {
20779
- handleUnrepresentable(schema, ctx, json2, params, "Date cannot be represented in JSON Schema");
20869
+ var dateProcessor = (schema, ctx, json3, params) => {
20870
+ handleUnrepresentable(schema, ctx, json3, params, "Date cannot be represented in JSON Schema");
20780
20871
  };
20781
- var enumProcessor = (schema, _ctx, json2, _params) => {
20872
+ var enumProcessor = (schema, _ctx, json3, _params) => {
20782
20873
  const def = schema._zod.def;
20783
20874
  const values = getEnumValues(def.entries);
20784
20875
  if (values.length === 0) {
20785
- json2.not = {};
20876
+ json3.not = {};
20786
20877
  return;
20787
20878
  }
20788
20879
  if (values.every((v2) => typeof v2 === "number"))
20789
- json2.type = "number";
20880
+ json3.type = "number";
20790
20881
  if (values.every((v2) => typeof v2 === "string"))
20791
- json2.type = "string";
20792
- json2.enum = values;
20882
+ json3.type = "string";
20883
+ json3.enum = values;
20793
20884
  };
20794
- var literalProcessor = (schema, ctx, json2, params) => {
20885
+ var literalProcessor = (schema, ctx, json3, params) => {
20795
20886
  const def = schema._zod.def;
20796
20887
  if (def.values.length === 0) {
20797
- json2.not = {};
20888
+ json3.not = {};
20798
20889
  return;
20799
20890
  }
20800
20891
  const vals = [];
20801
20892
  for (const val of def.values) {
20802
20893
  if (val === void 0) {
20803
- if (handleUnrepresentable(schema, ctx, json2, params, "Literal `undefined` cannot be represented in JSON Schema"))
20894
+ if (handleUnrepresentable(schema, ctx, json3, params, "Literal `undefined` cannot be represented in JSON Schema"))
20804
20895
  return;
20805
20896
  } else if (typeof val === "bigint") {
20806
- if (handleUnrepresentable(schema, ctx, json2, params, "BigInt literals cannot be represented in JSON Schema"))
20897
+ if (handleUnrepresentable(schema, ctx, json3, params, "BigInt literals cannot be represented in JSON Schema"))
20807
20898
  return;
20808
20899
  vals.push(Number(val));
20809
20900
  } else {
@@ -20813,37 +20904,37 @@ var literalProcessor = (schema, ctx, json2, params) => {
20813
20904
  if (vals.length === 0) {
20814
20905
  } else if (vals.length === 1) {
20815
20906
  const val = vals[0];
20816
- json2.type = val === null ? "null" : typeof val;
20907
+ json3.type = val === null ? "null" : typeof val;
20817
20908
  if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") {
20818
- json2.enum = [val];
20909
+ json3.enum = [val];
20819
20910
  } else {
20820
- json2.const = val;
20911
+ json3.const = val;
20821
20912
  }
20822
20913
  } else {
20823
20914
  if (vals.every((v2) => typeof v2 === "number"))
20824
- json2.type = "number";
20915
+ json3.type = "number";
20825
20916
  if (vals.every((v2) => typeof v2 === "string"))
20826
- json2.type = "string";
20917
+ json3.type = "string";
20827
20918
  if (vals.every((v2) => typeof v2 === "boolean"))
20828
- json2.type = "boolean";
20919
+ json3.type = "boolean";
20829
20920
  if (vals.every((v2) => v2 === null))
20830
- json2.type = "null";
20831
- json2.enum = vals;
20921
+ json3.type = "null";
20922
+ json3.enum = vals;
20832
20923
  }
20833
20924
  };
20834
- var nanProcessor = (schema, ctx, json2, params) => {
20835
- handleUnrepresentable(schema, ctx, json2, params, "NaN cannot be represented in JSON Schema");
20925
+ var nanProcessor = (schema, ctx, json3, params) => {
20926
+ handleUnrepresentable(schema, ctx, json3, params, "NaN cannot be represented in JSON Schema");
20836
20927
  };
20837
- var templateLiteralProcessor = (schema, _ctx, json2, _params) => {
20838
- const _json = json2;
20928
+ var templateLiteralProcessor = (schema, _ctx, json3, _params) => {
20929
+ const _json = json3;
20839
20930
  const pattern = schema._zod.pattern;
20840
20931
  if (!pattern)
20841
20932
  throw new Error("Pattern not found in template literal");
20842
20933
  _json.type = "string";
20843
20934
  _json.pattern = pattern.source;
20844
20935
  };
20845
- var fileProcessor = (schema, _ctx, json2, _params) => {
20846
- const _json = json2;
20936
+ var fileProcessor = (schema, _ctx, json3, _params) => {
20937
+ const _json = json3;
20847
20938
  _json.type = "string";
20848
20939
  _json.format = "binary";
20849
20940
  _json.contentEncoding = "binary";
@@ -20861,34 +20952,34 @@ var fileProcessor = (schema, _ctx, json2, _params) => {
20861
20952
  else
20862
20953
  _json.anyOf = mime.map((m2) => ({ contentMediaType: m2 }));
20863
20954
  };
20864
- var successProcessor = (_schema, _ctx, json2, _params) => {
20865
- json2.type = "boolean";
20955
+ var successProcessor = (_schema, _ctx, json3, _params) => {
20956
+ json3.type = "boolean";
20866
20957
  };
20867
- var customProcessor = (schema, ctx, json2, params) => {
20868
- handleUnrepresentable(schema, ctx, json2, params, "Custom types cannot be represented in JSON Schema");
20958
+ var customProcessor = (schema, ctx, json3, params) => {
20959
+ handleUnrepresentable(schema, ctx, json3, params, "Custom types cannot be represented in JSON Schema");
20869
20960
  };
20870
- var functionProcessor = (schema, ctx, json2, params) => {
20871
- handleUnrepresentable(schema, ctx, json2, params, "Function types cannot be represented in JSON Schema");
20961
+ var functionProcessor = (schema, ctx, json3, params) => {
20962
+ handleUnrepresentable(schema, ctx, json3, params, "Function types cannot be represented in JSON Schema");
20872
20963
  };
20873
- var transformProcessor = (schema, ctx, json2, params) => {
20874
- handleUnrepresentable(schema, ctx, json2, params, "Transforms cannot be represented in JSON Schema");
20964
+ var transformProcessor = (schema, ctx, json3, params) => {
20965
+ handleUnrepresentable(schema, ctx, json3, params, "Transforms cannot be represented in JSON Schema");
20875
20966
  };
20876
- var mapProcessor = (schema, ctx, json2, params) => {
20877
- handleUnrepresentable(schema, ctx, json2, params, "Map cannot be represented in JSON Schema");
20967
+ var mapProcessor = (schema, ctx, json3, params) => {
20968
+ handleUnrepresentable(schema, ctx, json3, params, "Map cannot be represented in JSON Schema");
20878
20969
  };
20879
- var setProcessor = (schema, ctx, json2, params) => {
20880
- handleUnrepresentable(schema, ctx, json2, params, "Set cannot be represented in JSON Schema");
20970
+ var setProcessor = (schema, ctx, json3, params) => {
20971
+ handleUnrepresentable(schema, ctx, json3, params, "Set cannot be represented in JSON Schema");
20881
20972
  };
20882
20973
  var arrayProcessor = (schema, ctx, _json, params) => {
20883
- const json2 = _json;
20974
+ const json3 = _json;
20884
20975
  const def = schema._zod.def;
20885
20976
  const { minimum, maximum } = aggregateChecks(schema);
20886
20977
  if (typeof minimum === "number")
20887
- json2.minItems = minimum;
20978
+ json3.minItems = minimum;
20888
20979
  if (typeof maximum === "number")
20889
- json2.maxItems = maximum;
20890
- json2.type = "array";
20891
- json2.items = processSchema(def.element, ctx, {
20980
+ json3.maxItems = maximum;
20981
+ json3.type = "array";
20982
+ json3.items = processSchema(def.element, ctx, {
20892
20983
  ...params,
20893
20984
  path: [...params.path, "items"]
20894
20985
  });
@@ -20904,17 +20995,17 @@ function inputOptin(schema) {
20904
20995
  return schema._zod.optin;
20905
20996
  }
20906
20997
  var objectProcessor = (schema, ctx, _json, params) => {
20907
- const json2 = _json;
20998
+ const json3 = _json;
20908
20999
  const def = schema._zod.def;
20909
21000
  const shape = def.shape;
20910
21001
  const symbolKeys = Object.getOwnPropertySymbols(shape);
20911
- if (symbolKeys.length && handleUnrepresentable(schema, ctx, json2, params, "Symbol keys cannot be represented in JSON Schema")) {
21002
+ if (symbolKeys.length && handleUnrepresentable(schema, ctx, json3, params, "Symbol keys cannot be represented in JSON Schema")) {
20912
21003
  return;
20913
21004
  }
20914
- json2.type = "object";
20915
- json2.properties = {};
21005
+ json3.type = "object";
21006
+ json3.properties = {};
20916
21007
  for (const key3 in shape) {
20917
- assignProp(json2.properties, key3, processSchema(shape[key3], ctx, {
21008
+ assignProp(json3.properties, key3, processSchema(shape[key3], ctx, {
20918
21009
  ...params,
20919
21010
  path: [...params.path, "properties", key3]
20920
21011
  }));
@@ -20927,21 +21018,21 @@ var objectProcessor = (schema, ctx, _json, params) => {
20927
21018
  }
20928
21019
  }
20929
21020
  if (requiredKeys.length > 0) {
20930
- json2.required = requiredKeys;
21021
+ json3.required = requiredKeys;
20931
21022
  }
20932
21023
  if (def.catchall?._zod.def.type === "never") {
20933
- json2.additionalProperties = false;
21024
+ json3.additionalProperties = false;
20934
21025
  } else if (!def.catchall) {
20935
21026
  if (ctx.io === "output")
20936
- json2.additionalProperties = false;
21027
+ json3.additionalProperties = false;
20937
21028
  } else if (def.catchall) {
20938
- json2.additionalProperties = processSchema(def.catchall, ctx, {
21029
+ json3.additionalProperties = processSchema(def.catchall, ctx, {
20939
21030
  ...params,
20940
21031
  path: [...params.path, "additionalProperties"]
20941
21032
  });
20942
21033
  }
20943
21034
  };
20944
- var unionProcessor = (schema, ctx, json2, params) => {
21035
+ var unionProcessor = (schema, ctx, json3, params) => {
20945
21036
  const def = schema._zod.def;
20946
21037
  const isExclusive = def.inclusive === false;
20947
21038
  const options = def.options.map((x2, i) => processSchema(x2, ctx, {
@@ -20949,12 +21040,12 @@ var unionProcessor = (schema, ctx, json2, params) => {
20949
21040
  path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
20950
21041
  }));
20951
21042
  if (isExclusive) {
20952
- json2.oneOf = options;
21043
+ json3.oneOf = options;
20953
21044
  } else {
20954
- json2.anyOf = options;
21045
+ json3.anyOf = options;
20955
21046
  }
20956
21047
  };
20957
- var intersectionProcessor = (schema, ctx, json2, params) => {
21048
+ var intersectionProcessor = (schema, ctx, json3, params) => {
20958
21049
  const def = schema._zod.def;
20959
21050
  const a = processSchema(def.left, ctx, {
20960
21051
  ...params,
@@ -20969,13 +21060,13 @@ var intersectionProcessor = (schema, ctx, json2, params) => {
20969
21060
  ...isSimpleIntersection(a) ? a.allOf : [a],
20970
21061
  ...isSimpleIntersection(b3) ? b3.allOf : [b3]
20971
21062
  ];
20972
- json2.allOf = allOf;
21063
+ json3.allOf = allOf;
20973
21064
  ctx.intersections.push(allOf);
20974
21065
  };
20975
21066
  var tupleProcessor = (schema, ctx, _json, params) => {
20976
- const json2 = _json;
21067
+ const json3 = _json;
20977
21068
  const def = schema._zod.def;
20978
- json2.type = "array";
21069
+ json3.type = "array";
20979
21070
  const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
20980
21071
  const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
20981
21072
  const prefixItems = def.items.map((x2, i) => processSchema(x2, ctx, {
@@ -20997,70 +21088,70 @@ var tupleProcessor = (schema, ctx, _json, params) => {
20997
21088
  const maxItems = def.items.length;
20998
21089
  const isClosed = !def.rest;
20999
21090
  if (ctx.target === "draft-2020-12") {
21000
- json2.prefixItems = prefixItems;
21091
+ json3.prefixItems = prefixItems;
21001
21092
  if (isClosed) {
21002
- json2.items = false;
21093
+ json3.items = false;
21003
21094
  } else if (rest) {
21004
- json2.items = rest;
21095
+ json3.items = rest;
21005
21096
  }
21006
21097
  if (minItems > 0)
21007
- json2.minItems = minItems;
21098
+ json3.minItems = minItems;
21008
21099
  if (isClosed)
21009
- json2.maxItems = maxItems;
21100
+ json3.maxItems = maxItems;
21010
21101
  } else if (ctx.target === "openapi-3.0") {
21011
- json2.items = {
21102
+ json3.items = {
21012
21103
  anyOf: prefixItems
21013
21104
  };
21014
21105
  if (rest) {
21015
- json2.items.anyOf.push(rest);
21106
+ json3.items.anyOf.push(rest);
21016
21107
  }
21017
21108
  if (minItems > 0)
21018
- json2.minItems = minItems;
21109
+ json3.minItems = minItems;
21019
21110
  if (isClosed)
21020
- json2.maxItems = maxItems;
21111
+ json3.maxItems = maxItems;
21021
21112
  } else {
21022
- json2.items = prefixItems;
21113
+ json3.items = prefixItems;
21023
21114
  if (isClosed) {
21024
- json2.additionalItems = false;
21115
+ json3.additionalItems = false;
21025
21116
  } else if (rest) {
21026
- json2.additionalItems = rest;
21117
+ json3.additionalItems = rest;
21027
21118
  }
21028
21119
  if (minItems > 0)
21029
- json2.minItems = minItems;
21120
+ json3.minItems = minItems;
21030
21121
  if (isClosed)
21031
- json2.maxItems = maxItems;
21122
+ json3.maxItems = maxItems;
21032
21123
  }
21033
21124
  const { minimum, maximum } = aggregateChecks(schema);
21034
21125
  if (typeof minimum === "number")
21035
- json2.minItems = minimum;
21126
+ json3.minItems = minimum;
21036
21127
  if (typeof maximum === "number")
21037
- json2.maxItems = maximum;
21128
+ json3.maxItems = maximum;
21038
21129
  };
21039
- function stringifyKeyNames(bySchema, json2, visited) {
21040
- if (json2.$ref) {
21041
- if (visited.has(json2))
21042
- return json2;
21043
- visited.add(json2);
21044
- const def = bySchema.get(json2)?.def;
21130
+ function stringifyKeyNames(bySchema, json3, visited) {
21131
+ if (json3.$ref) {
21132
+ if (visited.has(json3))
21133
+ return json3;
21134
+ visited.add(json3);
21135
+ const def = bySchema.get(json3)?.def;
21045
21136
  if (!def)
21046
- return json2;
21137
+ return json3;
21047
21138
  const inlined = stringifyKeyNames(bySchema, def, visited);
21048
- return inlined === def ? json2 : inlined;
21139
+ return inlined === def ? json3 : inlined;
21049
21140
  }
21050
21141
  for (const keyword of ["anyOf", "oneOf"]) {
21051
- const branches = json2[keyword];
21142
+ const branches = json3[keyword];
21052
21143
  if (!Array.isArray(branches))
21053
21144
  continue;
21054
21145
  const mapped = branches.map((branch) => stringifyKeyNames(bySchema, branch, visited));
21055
21146
  if (mapped.some((branch, i) => branch !== branches[i]))
21056
- json2 = { ...json2, [keyword]: mapped };
21147
+ json3 = { ...json3, [keyword]: mapped };
21057
21148
  }
21058
- const types = Array.isArray(json2.type) ? json2.type : [json2.type];
21149
+ const types = Array.isArray(json3.type) ? json3.type : [json3.type];
21059
21150
  const numericType = !types.includes("string") && types.some((t) => t === "number" || t === "integer");
21060
- const values = json2.enum ?? (json2.const !== void 0 ? [json2.const] : void 0);
21151
+ const values = json3.enum ?? (json3.const !== void 0 ? [json3.const] : void 0);
21061
21152
  if (!numericType && !values?.some((v2) => typeof v2 === "number"))
21062
- return json2;
21063
- const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json2;
21153
+ return json3;
21154
+ const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json3;
21064
21155
  if (rest.enum)
21065
21156
  rest.enum = rest.enum.map((v2) => typeof v2 === "number" ? String(v2) : v2);
21066
21157
  else if (typeof rest.const === "number")
@@ -21100,9 +21191,9 @@ function rewriteKeyNames(ctx) {
21100
21191
  }
21101
21192
  }
21102
21193
  var recordProcessor = (schema, ctx, _json, params) => {
21103
- const json2 = _json;
21194
+ const json3 = _json;
21104
21195
  const def = schema._zod.def;
21105
- json2.type = "object";
21196
+ json3.type = "object";
21106
21197
  const keyType = def.keyType;
21107
21198
  const patterns = aggregateChecks(keyType).patterns;
21108
21199
  if (def.mode === "loose" && patterns && patterns.size > 0) {
@@ -21110,13 +21201,13 @@ var recordProcessor = (schema, ctx, _json, params) => {
21110
21201
  ...params,
21111
21202
  path: [...params.path, "patternProperties", "*"]
21112
21203
  });
21113
- json2.patternProperties = {};
21204
+ json3.patternProperties = {};
21114
21205
  for (const pattern of patterns) {
21115
- assignProp(json2.patternProperties, exactPattern(pattern).source, valueSchema);
21206
+ assignProp(json3.patternProperties, exactPattern(pattern).source, valueSchema);
21116
21207
  }
21117
21208
  } else {
21118
21209
  if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
21119
- json2.propertyNames = processSchema(def.keyType, ctx, {
21210
+ json3.propertyNames = processSchema(def.keyType, ctx, {
21120
21211
  ...params,
21121
21212
  path: [...params.path, "propertyNames"]
21122
21213
  });
@@ -21128,7 +21219,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
21128
21219
  }
21129
21220
  pending.push(schema);
21130
21221
  }
21131
- json2.additionalProperties = processSchema(def.valueType, ctx, {
21222
+ json3.additionalProperties = processSchema(def.valueType, ctx, {
21132
21223
  ...params,
21133
21224
  path: [...params.path, "additionalProperties"]
21134
21225
  });
@@ -21138,19 +21229,19 @@ var recordProcessor = (schema, ctx, _json, params) => {
21138
21229
  if (keyValues && !def.partial && !omittableOnInput) {
21139
21230
  const validKeyValues = [...keyValues].filter((v2) => typeof v2 === "string" || typeof v2 === "number");
21140
21231
  if (validKeyValues.length > 0) {
21141
- json2.required = validKeyValues.map(String);
21232
+ json3.required = validKeyValues.map(String);
21142
21233
  }
21143
21234
  }
21144
21235
  };
21145
- var nullableProcessor = (schema, ctx, json2, params) => {
21236
+ var nullableProcessor = (schema, ctx, json3, params) => {
21146
21237
  const def = schema._zod.def;
21147
21238
  const inner = processSchema(def.innerType, ctx, params);
21148
21239
  const seen = ctx.seen.get(schema);
21149
21240
  if (ctx.target === "openapi-3.0") {
21150
21241
  seen.ref = def.innerType;
21151
- json2.nullable = true;
21242
+ json3.nullable = true;
21152
21243
  } else {
21153
- json2.anyOf = [inner, { type: "null" }];
21244
+ json3.anyOf = [inner, { type: "null" }];
21154
21245
  }
21155
21246
  };
21156
21247
  var nonoptionalProcessor = (schema, ctx, _json, params) => {
@@ -21160,7 +21251,7 @@ var nonoptionalProcessor = (schema, ctx, _json, params) => {
21160
21251
  seen.ref = def.innerType;
21161
21252
  };
21162
21253
  var UNREPRESENTABLE_DEFAULT = /* @__PURE__ */ Symbol();
21163
- function serializeDefaultValue(value, schema, ctx, json2, params) {
21254
+ function serializeDefaultValue(value, schema, ctx, json3, params) {
21164
21255
  let unrepresentable = false;
21165
21256
  const serialized = JSON.stringify(value, (_3, val) => {
21166
21257
  if (typeof val !== "bigint")
@@ -21170,30 +21261,30 @@ function serializeDefaultValue(value, schema, ctx, json2, params) {
21170
21261
  });
21171
21262
  if (!unrepresentable)
21172
21263
  return JSON.parse(serialized);
21173
- handleUnrepresentable(schema, ctx, json2, params, "BigInt defaults cannot be represented in JSON Schema");
21264
+ handleUnrepresentable(schema, ctx, json3, params, "BigInt defaults cannot be represented in JSON Schema");
21174
21265
  return UNREPRESENTABLE_DEFAULT;
21175
21266
  }
21176
- var defaultProcessor = (schema, ctx, json2, params) => {
21267
+ var defaultProcessor = (schema, ctx, json3, params) => {
21177
21268
  const def = schema._zod.def;
21178
21269
  processSchema(def.innerType, ctx, params);
21179
21270
  const seen = ctx.seen.get(schema);
21180
21271
  seen.ref = def.innerType;
21181
- const value = serializeDefaultValue(def.defaultValue, schema, ctx, json2, params);
21272
+ const value = serializeDefaultValue(def.defaultValue, schema, ctx, json3, params);
21182
21273
  if (value !== UNREPRESENTABLE_DEFAULT)
21183
- json2.default = value;
21274
+ json3.default = value;
21184
21275
  };
21185
- var prefaultProcessor = (schema, ctx, json2, params) => {
21276
+ var prefaultProcessor = (schema, ctx, json3, params) => {
21186
21277
  const def = schema._zod.def;
21187
21278
  processSchema(def.innerType, ctx, params);
21188
21279
  const seen = ctx.seen.get(schema);
21189
21280
  seen.ref = def.innerType;
21190
21281
  if (ctx.io !== "input")
21191
21282
  return;
21192
- const value = serializeDefaultValue(def.defaultValue, schema, ctx, json2, params);
21283
+ const value = serializeDefaultValue(def.defaultValue, schema, ctx, json3, params);
21193
21284
  if (value !== UNREPRESENTABLE_DEFAULT)
21194
- json2._prefault = value;
21285
+ json3._prefault = value;
21195
21286
  };
21196
- var catchProcessor = (schema, ctx, json2, params) => {
21287
+ var catchProcessor = (schema, ctx, json3, params) => {
21197
21288
  const def = schema._zod.def;
21198
21289
  processSchema(def.innerType, ctx, params);
21199
21290
  const seen = ctx.seen.get(schema);
@@ -21202,10 +21293,10 @@ var catchProcessor = (schema, ctx, json2, params) => {
21202
21293
  try {
21203
21294
  catchValue = def.catchValue(void 0);
21204
21295
  } catch {
21205
- handleUnrepresentable(schema, ctx, json2, params, "Dynamic catch values are not supported in JSON Schema");
21296
+ handleUnrepresentable(schema, ctx, json3, params, "Dynamic catch values are not supported in JSON Schema");
21206
21297
  return;
21207
21298
  }
21208
- json2.default = catchValue;
21299
+ json3.default = catchValue;
21209
21300
  };
21210
21301
  var pipeProcessor = (schema, ctx, _json, params) => {
21211
21302
  const def = schema._zod.def;
@@ -21215,12 +21306,12 @@ var pipeProcessor = (schema, ctx, _json, params) => {
21215
21306
  const seen = ctx.seen.get(schema);
21216
21307
  seen.ref = innerType;
21217
21308
  };
21218
- var readonlyProcessor = (schema, ctx, json2, params) => {
21309
+ var readonlyProcessor = (schema, ctx, json3, params) => {
21219
21310
  const def = schema._zod.def;
21220
21311
  processSchema(def.innerType, ctx, params);
21221
21312
  const seen = ctx.seen.get(schema);
21222
21313
  seen.ref = def.innerType;
21223
- json2.readOnly = true;
21314
+ json3.readOnly = true;
21224
21315
  };
21225
21316
  var promiseProcessor = (schema, ctx, _json, params) => {
21226
21317
  const def = schema._zod.def;
@@ -21707,8 +21798,8 @@ var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
21707
21798
  brand() {
21708
21799
  return this;
21709
21800
  },
21710
- register(reg, meta3) {
21711
- reg.add(this, meta3);
21801
+ register(reg, meta4) {
21802
+ reg.add(this, meta4);
21712
21803
  return this;
21713
21804
  },
21714
21805
  refine(check2, params) {
@@ -21862,7 +21953,7 @@ var _ZodString = /* @__PURE__ */ $constructor(
21862
21953
  (inst, def) => {
21863
21954
  $ZodString.init(inst, def);
21864
21955
  ZodType.init(inst, def);
21865
- inst._zod.processJSONSchema = (ctx, json2, params) => stringProcessor(inst, ctx, json2, params);
21956
+ inst._zod.processJSONSchema = (ctx, json3, params) => stringProcessor(inst, ctx, json3, params);
21866
21957
  },
21867
21958
  /* @__PURE__ */ util_exports.derived({
21868
21959
  format: (inst) => aggregateChecks(inst).format ?? null,
@@ -22221,7 +22312,7 @@ var ZodNumber = /* @__PURE__ */ $constructor(
22221
22312
  (inst, def) => {
22222
22313
  $ZodNumber.init(inst, def);
22223
22314
  ZodType.init(inst, def);
22224
- inst._zod.processJSONSchema = (ctx, json2, params) => numberProcessor(inst, ctx, json2, params);
22315
+ inst._zod.processJSONSchema = (ctx, json3, params) => numberProcessor(inst, ctx, json3, params);
22225
22316
  inst.isFinite = true;
22226
22317
  },
22227
22318
  /* @__PURE__ */ util_exports.derived({
@@ -22311,7 +22402,7 @@ function uint32(params) {
22311
22402
  var ZodBoolean = /* @__PURE__ */ $constructor("ZodBoolean", (inst, def) => {
22312
22403
  $ZodBoolean.init(inst, def);
22313
22404
  ZodType.init(inst, def);
22314
- inst._zod.processJSONSchema = (ctx, json2, params) => booleanProcessor(inst, ctx, json2, params);
22405
+ inst._zod.processJSONSchema = (ctx, json3, params) => booleanProcessor(inst, ctx, json3, params);
22315
22406
  });
22316
22407
  function boolean2(params) {
22317
22408
  return _boolean(ZodBoolean, params);
@@ -22321,7 +22412,7 @@ var ZodBigInt = /* @__PURE__ */ $constructor(
22321
22412
  (inst, def) => {
22322
22413
  $ZodBigInt.init(inst, def);
22323
22414
  ZodType.init(inst, def);
22324
- inst._zod.processJSONSchema = (ctx, json2, params) => bigintProcessor(inst, ctx, json2, params);
22415
+ inst._zod.processJSONSchema = (ctx, json3, params) => bigintProcessor(inst, ctx, json3, params);
22325
22416
  },
22326
22417
  /* @__PURE__ */ util_exports.derived({
22327
22418
  minValue: (inst) => aggregateChecks(inst).minimum ?? null,
@@ -22379,7 +22470,7 @@ function uint64(params) {
22379
22470
  var ZodSymbol = /* @__PURE__ */ $constructor("ZodSymbol", (inst, def) => {
22380
22471
  $ZodSymbol.init(inst, def);
22381
22472
  ZodType.init(inst, def);
22382
- inst._zod.processJSONSchema = (ctx, json2, params) => symbolProcessor(inst, ctx, json2, params);
22473
+ inst._zod.processJSONSchema = (ctx, json3, params) => symbolProcessor(inst, ctx, json3, params);
22383
22474
  });
22384
22475
  function symbol(params) {
22385
22476
  return _symbol(ZodSymbol, params);
@@ -22387,7 +22478,7 @@ function symbol(params) {
22387
22478
  var ZodUndefined = /* @__PURE__ */ $constructor("ZodUndefined", (inst, def) => {
22388
22479
  $ZodUndefined.init(inst, def);
22389
22480
  ZodType.init(inst, def);
22390
- inst._zod.processJSONSchema = (ctx, json2, params) => undefinedProcessor(inst, ctx, json2, params);
22481
+ inst._zod.processJSONSchema = (ctx, json3, params) => undefinedProcessor(inst, ctx, json3, params);
22391
22482
  });
22392
22483
  function _undefined3(params) {
22393
22484
  return _undefined2(ZodUndefined, params);
@@ -22395,7 +22486,7 @@ function _undefined3(params) {
22395
22486
  var ZodNull = /* @__PURE__ */ $constructor("ZodNull", (inst, def) => {
22396
22487
  $ZodNull.init(inst, def);
22397
22488
  ZodType.init(inst, def);
22398
- inst._zod.processJSONSchema = (ctx, json2, params) => nullProcessor(inst, ctx, json2, params);
22489
+ inst._zod.processJSONSchema = (ctx, json3, params) => nullProcessor(inst, ctx, json3, params);
22399
22490
  });
22400
22491
  function _null3(params) {
22401
22492
  return _null2(ZodNull, params);
@@ -22403,7 +22494,7 @@ function _null3(params) {
22403
22494
  var ZodAny = /* @__PURE__ */ $constructor("ZodAny", (inst, def) => {
22404
22495
  $ZodAny.init(inst, def);
22405
22496
  ZodType.init(inst, def);
22406
- inst._zod.processJSONSchema = (ctx, json2, params) => anyProcessor(inst, ctx, json2, params);
22497
+ inst._zod.processJSONSchema = (ctx, json3, params) => anyProcessor(inst, ctx, json3, params);
22407
22498
  });
22408
22499
  function any() {
22409
22500
  return _any(ZodAny);
@@ -22411,7 +22502,7 @@ function any() {
22411
22502
  var ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
22412
22503
  $ZodUnknown.init(inst, def);
22413
22504
  ZodType.init(inst, def);
22414
- inst._zod.processJSONSchema = (ctx, json2, params) => unknownProcessor(inst, ctx, json2, params);
22505
+ inst._zod.processJSONSchema = (ctx, json3, params) => unknownProcessor(inst, ctx, json3, params);
22415
22506
  });
22416
22507
  function unknown() {
22417
22508
  return _unknown(ZodUnknown);
@@ -22419,7 +22510,7 @@ function unknown() {
22419
22510
  var ZodNever = /* @__PURE__ */ $constructor("ZodNever", (inst, def) => {
22420
22511
  $ZodNever.init(inst, def);
22421
22512
  ZodType.init(inst, def);
22422
- inst._zod.processJSONSchema = (ctx, json2, params) => neverProcessor(inst, ctx, json2, params);
22513
+ inst._zod.processJSONSchema = (ctx, json3, params) => neverProcessor(inst, ctx, json3, params);
22423
22514
  });
22424
22515
  function never(params) {
22425
22516
  return _never(ZodNever, params);
@@ -22427,7 +22518,7 @@ function never(params) {
22427
22518
  var ZodVoid = /* @__PURE__ */ $constructor("ZodVoid", (inst, def) => {
22428
22519
  $ZodVoid.init(inst, def);
22429
22520
  ZodType.init(inst, def);
22430
- inst._zod.processJSONSchema = (ctx, json2, params) => voidProcessor(inst, ctx, json2, params);
22521
+ inst._zod.processJSONSchema = (ctx, json3, params) => voidProcessor(inst, ctx, json3, params);
22431
22522
  });
22432
22523
  function _void2(params) {
22433
22524
  return _void(ZodVoid, params);
@@ -22437,7 +22528,7 @@ var ZodDate = /* @__PURE__ */ $constructor(
22437
22528
  (inst, def) => {
22438
22529
  $ZodDate.init(inst, def);
22439
22530
  ZodType.init(inst, def);
22440
- inst._zod.processJSONSchema = (ctx, json2, params) => dateProcessor(inst, ctx, json2, params);
22531
+ inst._zod.processJSONSchema = (ctx, json3, params) => dateProcessor(inst, ctx, json3, params);
22441
22532
  inst.min = (value, params) => inst.check(_gte(value, params));
22442
22533
  inst.max = (value, params) => inst.check(_lte(value, params));
22443
22534
  },
@@ -22459,7 +22550,7 @@ var ZodArray = /* @__PURE__ */ $constructor("ZodArray", (inst, def) => {
22459
22550
  _ensureDefaultMemoizer();
22460
22551
  $ZodArray.init(inst, def);
22461
22552
  ZodType.init(inst, def);
22462
- inst._zod.processJSONSchema = (ctx, json2, params) => arrayProcessor(inst, ctx, json2, params);
22553
+ inst._zod.processJSONSchema = (ctx, json3, params) => arrayProcessor(inst, ctx, json3, params);
22463
22554
  inst.element = def.element;
22464
22555
  }, {
22465
22556
  min(n, params) {
@@ -22489,7 +22580,7 @@ var ZodObject = /* @__PURE__ */ $constructor("ZodObject", (inst, def) => {
22489
22580
  _ensureDefaultMemoizer();
22490
22581
  $ZodObjectJIT.init(inst, def);
22491
22582
  ZodType.init(inst, def);
22492
- inst._zod.processJSONSchema = (ctx, json2, params) => objectProcessor(inst, ctx, json2, params);
22583
+ inst._zod.processJSONSchema = (ctx, json3, params) => objectProcessor(inst, ctx, json3, params);
22493
22584
  util_exports.installLazyProp(inst, "shape", (self) => self._zod.def.shape, false);
22494
22585
  }, {
22495
22586
  keyof() {
@@ -22562,7 +22653,7 @@ function looseObject(shape, params) {
22562
22653
  var ZodUnion = /* @__PURE__ */ $constructor("ZodUnion", (inst, def) => {
22563
22654
  $ZodUnion.init(inst, def);
22564
22655
  ZodType.init(inst, def);
22565
- inst._zod.processJSONSchema = (ctx, json2, params) => unionProcessor(inst, ctx, json2, params);
22656
+ inst._zod.processJSONSchema = (ctx, json3, params) => unionProcessor(inst, ctx, json3, params);
22566
22657
  inst.options = def.options;
22567
22658
  });
22568
22659
  function union(options, params) {
@@ -22575,7 +22666,7 @@ function union(options, params) {
22575
22666
  var ZodXor = /* @__PURE__ */ $constructor("ZodXor", (inst, def) => {
22576
22667
  ZodUnion.init(inst, def);
22577
22668
  $ZodXor.init(inst, def);
22578
- inst._zod.processJSONSchema = (ctx, json2, params) => unionProcessor(inst, ctx, json2, params);
22669
+ inst._zod.processJSONSchema = (ctx, json3, params) => unionProcessor(inst, ctx, json3, params);
22579
22670
  inst.options = def.options;
22580
22671
  });
22581
22672
  function xor(options, params) {
@@ -22601,7 +22692,7 @@ function discriminatedUnion(discriminator, options, params) {
22601
22692
  var ZodIntersection = /* @__PURE__ */ $constructor("ZodIntersection", (inst, def) => {
22602
22693
  $ZodIntersection.init(inst, def);
22603
22694
  ZodType.init(inst, def);
22604
- inst._zod.processJSONSchema = (ctx, json2, params) => intersectionProcessor(inst, ctx, json2, params);
22695
+ inst._zod.processJSONSchema = (ctx, json3, params) => intersectionProcessor(inst, ctx, json3, params);
22605
22696
  });
22606
22697
  function intersection(left, right) {
22607
22698
  return new ZodIntersection({
@@ -22614,7 +22705,7 @@ var ZodTuple = /* @__PURE__ */ $constructor("ZodTuple", (inst, def) => {
22614
22705
  _ensureDefaultMemoizer();
22615
22706
  $ZodTuple.init(inst, def);
22616
22707
  ZodType.init(inst, def);
22617
- inst._zod.processJSONSchema = (ctx, json2, params) => tupleProcessor(inst, ctx, json2, params);
22708
+ inst._zod.processJSONSchema = (ctx, json3, params) => tupleProcessor(inst, ctx, json3, params);
22618
22709
  }, {
22619
22710
  rest(rest) {
22620
22711
  return this.clone({
@@ -22647,7 +22738,7 @@ var ZodRecord = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
22647
22738
  _ensureDefaultMemoizer();
22648
22739
  $ZodRecord.init(inst, def);
22649
22740
  ZodType.init(inst, def);
22650
- inst._zod.processJSONSchema = (ctx, json2, params) => recordProcessor(inst, ctx, json2, params);
22741
+ inst._zod.processJSONSchema = (ctx, json3, params) => recordProcessor(inst, ctx, json3, params);
22651
22742
  inst.keyType = def.keyType;
22652
22743
  inst.valueType = def.valueType;
22653
22744
  });
@@ -22689,7 +22780,7 @@ var ZodMap = /* @__PURE__ */ $constructor("ZodMap", (inst, def) => {
22689
22780
  _ensureDefaultMemoizer();
22690
22781
  $ZodMap.init(inst, def);
22691
22782
  ZodType.init(inst, def);
22692
- inst._zod.processJSONSchema = (ctx, json2, params) => mapProcessor(inst, ctx, json2, params);
22783
+ inst._zod.processJSONSchema = (ctx, json3, params) => mapProcessor(inst, ctx, json3, params);
22693
22784
  inst.keyType = def.keyType;
22694
22785
  inst.valueType = def.valueType;
22695
22786
  inst.min = (...args) => inst.check(_minSize(...args));
@@ -22709,7 +22800,7 @@ var ZodSet = /* @__PURE__ */ $constructor("ZodSet", (inst, def) => {
22709
22800
  _ensureDefaultMemoizer();
22710
22801
  $ZodSet.init(inst, def);
22711
22802
  ZodType.init(inst, def);
22712
- inst._zod.processJSONSchema = (ctx, json2, params) => setProcessor(inst, ctx, json2, params);
22803
+ inst._zod.processJSONSchema = (ctx, json3, params) => setProcessor(inst, ctx, json3, params);
22713
22804
  inst.min = (...args) => inst.check(_minSize(...args));
22714
22805
  inst.nonempty = (params) => inst.check(_minSize(1, params));
22715
22806
  inst.max = (...args) => inst.check(_maxSize(...args));
@@ -22725,7 +22816,7 @@ function set(valueType, params) {
22725
22816
  var ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
22726
22817
  $ZodEnum.init(inst, def);
22727
22818
  ZodType.init(inst, def);
22728
- inst._zod.processJSONSchema = (ctx, json2, params) => enumProcessor(inst, ctx, json2, params);
22819
+ inst._zod.processJSONSchema = (ctx, json3, params) => enumProcessor(inst, ctx, json3, params);
22729
22820
  inst.enum = def.entries;
22730
22821
  inst.options = [...inst._zod.values];
22731
22822
  const keys = new Set(Object.keys(def.entries));
@@ -22778,7 +22869,7 @@ function nativeEnum(entries, params) {
22778
22869
  var ZodLiteral = /* @__PURE__ */ $constructor("ZodLiteral", (inst, def) => {
22779
22870
  $ZodLiteral.init(inst, def);
22780
22871
  ZodType.init(inst, def);
22781
- inst._zod.processJSONSchema = (ctx, json2, params) => literalProcessor(inst, ctx, json2, params);
22872
+ inst._zod.processJSONSchema = (ctx, json3, params) => literalProcessor(inst, ctx, json3, params);
22782
22873
  inst.values = new Set(def.values);
22783
22874
  Object.defineProperty(inst, "value", {
22784
22875
  get() {
@@ -22799,7 +22890,7 @@ function literal(value, params) {
22799
22890
  var ZodFile = /* @__PURE__ */ $constructor("ZodFile", (inst, def) => {
22800
22891
  $ZodFile.init(inst, def);
22801
22892
  ZodType.init(inst, def);
22802
- inst._zod.processJSONSchema = (ctx, json2, params) => fileProcessor(inst, ctx, json2, params);
22893
+ inst._zod.processJSONSchema = (ctx, json3, params) => fileProcessor(inst, ctx, json3, params);
22803
22894
  inst.min = (size2, params) => inst.check(_minSize(size2, params));
22804
22895
  inst.max = (size2, params) => inst.check(_maxSize(size2, params));
22805
22896
  inst.mime = (types, params) => inst.check(_mime(Array.isArray(types) ? types : [types], params));
@@ -22811,7 +22902,7 @@ var ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
22811
22902
  _ensureDefaultMemoizer();
22812
22903
  $ZodTransform.init(inst, def);
22813
22904
  ZodType.init(inst, def);
22814
- inst._zod.processJSONSchema = (ctx, json2, params) => transformProcessor(inst, ctx, json2, params);
22905
+ inst._zod.processJSONSchema = (ctx, json3, params) => transformProcessor(inst, ctx, json3, params);
22815
22906
  inst._zod.parse = (payload, _ctx) => {
22816
22907
  if (_ctx.direction === "backward") {
22817
22908
  throw new $ZodEncodeError(inst.constructor.name);
@@ -22850,7 +22941,7 @@ function transform(fn) {
22850
22941
  var ZodOptional = /* @__PURE__ */ $constructor("ZodOptional", (inst, def) => {
22851
22942
  $ZodOptional.init(inst, def);
22852
22943
  ZodType.init(inst, def);
22853
- inst._zod.processJSONSchema = (ctx, json2, params) => optionalProcessor(inst, ctx, json2, params);
22944
+ inst._zod.processJSONSchema = (ctx, json3, params) => optionalProcessor(inst, ctx, json3, params);
22854
22945
  inst.unwrap = () => inst._zod.def.innerType;
22855
22946
  });
22856
22947
  function optional(innerType) {
@@ -22862,7 +22953,7 @@ function optional(innerType) {
22862
22953
  var ZodExactOptional = /* @__PURE__ */ $constructor("ZodExactOptional", (inst, def) => {
22863
22954
  $ZodExactOptional.init(inst, def);
22864
22955
  ZodType.init(inst, def);
22865
- inst._zod.processJSONSchema = (ctx, json2, params) => optionalProcessor(inst, ctx, json2, params);
22956
+ inst._zod.processJSONSchema = (ctx, json3, params) => optionalProcessor(inst, ctx, json3, params);
22866
22957
  inst.unwrap = () => inst._zod.def.innerType;
22867
22958
  });
22868
22959
  function exactOptional(innerType) {
@@ -22874,7 +22965,7 @@ function exactOptional(innerType) {
22874
22965
  var ZodNullable = /* @__PURE__ */ $constructor("ZodNullable", (inst, def) => {
22875
22966
  $ZodNullable.init(inst, def);
22876
22967
  ZodType.init(inst, def);
22877
- inst._zod.processJSONSchema = (ctx, json2, params) => nullableProcessor(inst, ctx, json2, params);
22968
+ inst._zod.processJSONSchema = (ctx, json3, params) => nullableProcessor(inst, ctx, json3, params);
22878
22969
  inst.unwrap = () => inst._zod.def.innerType;
22879
22970
  });
22880
22971
  function nullable(innerType) {
@@ -22889,7 +22980,7 @@ function nullish2(innerType) {
22889
22980
  var ZodDefault = /* @__PURE__ */ $constructor("ZodDefault", (inst, def) => {
22890
22981
  $ZodDefault.init(inst, def);
22891
22982
  ZodType.init(inst, def);
22892
- inst._zod.processJSONSchema = (ctx, json2, params) => defaultProcessor(inst, ctx, json2, params);
22983
+ inst._zod.processJSONSchema = (ctx, json3, params) => defaultProcessor(inst, ctx, json3, params);
22893
22984
  inst.unwrap = () => inst._zod.def.innerType;
22894
22985
  inst.removeDefault = inst.unwrap;
22895
22986
  });
@@ -22905,7 +22996,7 @@ function _default2(innerType, defaultValue) {
22905
22996
  var ZodPrefault = /* @__PURE__ */ $constructor("ZodPrefault", (inst, def) => {
22906
22997
  $ZodPrefault.init(inst, def);
22907
22998
  ZodType.init(inst, def);
22908
- inst._zod.processJSONSchema = (ctx, json2, params) => prefaultProcessor(inst, ctx, json2, params);
22999
+ inst._zod.processJSONSchema = (ctx, json3, params) => prefaultProcessor(inst, ctx, json3, params);
22909
23000
  inst.unwrap = () => inst._zod.def.innerType;
22910
23001
  });
22911
23002
  function prefault(innerType, defaultValue) {
@@ -22920,7 +23011,7 @@ function prefault(innerType, defaultValue) {
22920
23011
  var ZodNonOptional = /* @__PURE__ */ $constructor("ZodNonOptional", (inst, def) => {
22921
23012
  $ZodNonOptional.init(inst, def);
22922
23013
  ZodType.init(inst, def);
22923
- inst._zod.processJSONSchema = (ctx, json2, params) => nonoptionalProcessor(inst, ctx, json2, params);
23014
+ inst._zod.processJSONSchema = (ctx, json3, params) => nonoptionalProcessor(inst, ctx, json3, params);
22924
23015
  inst.unwrap = () => inst._zod.def.innerType;
22925
23016
  });
22926
23017
  function nonoptional(innerType, params) {
@@ -22933,7 +23024,7 @@ function nonoptional(innerType, params) {
22933
23024
  var ZodSuccess = /* @__PURE__ */ $constructor("ZodSuccess", (inst, def) => {
22934
23025
  $ZodSuccess.init(inst, def);
22935
23026
  ZodType.init(inst, def);
22936
- inst._zod.processJSONSchema = (ctx, json2, params) => successProcessor(inst, ctx, json2, params);
23027
+ inst._zod.processJSONSchema = (ctx, json3, params) => successProcessor(inst, ctx, json3, params);
22937
23028
  inst.unwrap = () => inst._zod.def.innerType;
22938
23029
  });
22939
23030
  function success(innerType) {
@@ -22945,7 +23036,7 @@ function success(innerType) {
22945
23036
  var ZodCatch = /* @__PURE__ */ $constructor("ZodCatch", (inst, def) => {
22946
23037
  $ZodCatch.init(inst, def);
22947
23038
  ZodType.init(inst, def);
22948
- inst._zod.processJSONSchema = (ctx, json2, params) => catchProcessor(inst, ctx, json2, params);
23039
+ inst._zod.processJSONSchema = (ctx, json3, params) => catchProcessor(inst, ctx, json3, params);
22949
23040
  inst.unwrap = () => inst._zod.def.innerType;
22950
23041
  inst.removeCatch = inst.unwrap;
22951
23042
  });
@@ -22959,7 +23050,7 @@ function _catch2(innerType, catchValue) {
22959
23050
  var ZodNaN = /* @__PURE__ */ $constructor("ZodNaN", (inst, def) => {
22960
23051
  $ZodNaN.init(inst, def);
22961
23052
  ZodType.init(inst, def);
22962
- inst._zod.processJSONSchema = (ctx, json2, params) => nanProcessor(inst, ctx, json2, params);
23053
+ inst._zod.processJSONSchema = (ctx, json3, params) => nanProcessor(inst, ctx, json3, params);
22963
23054
  });
22964
23055
  function nan(params) {
22965
23056
  return _nan(ZodNaN, params);
@@ -22967,7 +23058,7 @@ function nan(params) {
22967
23058
  var ZodPipe = /* @__PURE__ */ $constructor("ZodPipe", (inst, def) => {
22968
23059
  $ZodPipe.init(inst, def);
22969
23060
  ZodType.init(inst, def);
22970
- inst._zod.processJSONSchema = (ctx, json2, params) => pipeProcessor(inst, ctx, json2, params);
23061
+ inst._zod.processJSONSchema = (ctx, json3, params) => pipeProcessor(inst, ctx, json3, params);
22971
23062
  inst.in = def.in;
22972
23063
  inst.out = def.out;
22973
23064
  });
@@ -23009,7 +23100,7 @@ var ZodPreprocess = /* @__PURE__ */ $constructor("ZodPreprocess", (inst, def) =>
23009
23100
  var ZodReadonly = /* @__PURE__ */ $constructor("ZodReadonly", (inst, def) => {
23010
23101
  $ZodReadonly.init(inst, def);
23011
23102
  ZodType.init(inst, def);
23012
- inst._zod.processJSONSchema = (ctx, json2, params) => readonlyProcessor(inst, ctx, json2, params);
23103
+ inst._zod.processJSONSchema = (ctx, json3, params) => readonlyProcessor(inst, ctx, json3, params);
23013
23104
  inst.unwrap = () => inst._zod.def.innerType;
23014
23105
  });
23015
23106
  function readonly(innerType) {
@@ -23021,7 +23112,7 @@ function readonly(innerType) {
23021
23112
  var ZodTemplateLiteral = /* @__PURE__ */ $constructor("ZodTemplateLiteral", (inst, def) => {
23022
23113
  $ZodTemplateLiteral.init(inst, def);
23023
23114
  ZodType.init(inst, def);
23024
- inst._zod.processJSONSchema = (ctx, json2, params) => templateLiteralProcessor(inst, ctx, json2, params);
23115
+ inst._zod.processJSONSchema = (ctx, json3, params) => templateLiteralProcessor(inst, ctx, json3, params);
23025
23116
  });
23026
23117
  function templateLiteral(parts, params) {
23027
23118
  return new ZodTemplateLiteral({
@@ -23033,7 +23124,7 @@ function templateLiteral(parts, params) {
23033
23124
  var ZodLazy = /* @__PURE__ */ $constructor("ZodLazy", (inst, def) => {
23034
23125
  $ZodLazy.init(inst, def);
23035
23126
  ZodType.init(inst, def);
23036
- inst._zod.processJSONSchema = (ctx, json2, params) => lazyProcessor(inst, ctx, json2, params);
23127
+ inst._zod.processJSONSchema = (ctx, json3, params) => lazyProcessor(inst, ctx, json3, params);
23037
23128
  inst.unwrap = () => inst._zod.def.getter();
23038
23129
  });
23039
23130
  function lazy(getter) {
@@ -23045,7 +23136,7 @@ function lazy(getter) {
23045
23136
  var ZodPromise = /* @__PURE__ */ $constructor("ZodPromise", (inst, def) => {
23046
23137
  $ZodPromise.init(inst, def);
23047
23138
  ZodType.init(inst, def);
23048
- inst._zod.processJSONSchema = (ctx, json2, params) => promiseProcessor(inst, ctx, json2, params);
23139
+ inst._zod.processJSONSchema = (ctx, json3, params) => promiseProcessor(inst, ctx, json3, params);
23049
23140
  inst.unwrap = () => inst._zod.def.innerType;
23050
23141
  });
23051
23142
  function promise(innerType) {
@@ -23057,7 +23148,7 @@ function promise(innerType) {
23057
23148
  var ZodFunction = /* @__PURE__ */ $constructor("ZodFunction", (inst, def) => {
23058
23149
  $ZodFunction.init(inst, def);
23059
23150
  ZodType.init(inst, def);
23060
- inst._zod.processJSONSchema = (ctx, json2, params) => functionProcessor(inst, ctx, json2, params);
23151
+ inst._zod.processJSONSchema = (ctx, json3, params) => functionProcessor(inst, ctx, json3, params);
23061
23152
  });
23062
23153
  function _function(params) {
23063
23154
  return new ZodFunction({
@@ -23069,7 +23160,7 @@ function _function(params) {
23069
23160
  var ZodCustom = /* @__PURE__ */ $constructor("ZodCustom", (inst, def) => {
23070
23161
  $ZodCustom.init(inst, def);
23071
23162
  ZodType.init(inst, def);
23072
- inst._zod.processJSONSchema = (ctx, json2, params) => customProcessor(inst, ctx, json2, params);
23163
+ inst._zod.processJSONSchema = (ctx, json3, params) => customProcessor(inst, ctx, json3, params);
23073
23164
  });
23074
23165
  function check(fn) {
23075
23166
  const ch = new $ZodCheck({
@@ -24221,25 +24312,39 @@ var RULES = [
24221
24312
  replace: "[REDACTED_TOKEN]"
24222
24313
  }
24223
24314
  ];
24224
- function currentUserPattern() {
24225
- let name;
24315
+ var COMMON_NAMES = /* @__PURE__ */ new Set([
24316
+ // System, CI and container accounts
24317
+ ...["root", "admin", "administrator", "user", "guest", "test", "tester", "dev", "developer", "build", "builder"],
24318
+ ...["runner", "deploy", "app", "node", "git", "www", "web", "server", "ubuntu", "debian", "centos", "fedora"],
24319
+ ...["alpine", "vagrant", "docker", "jenkins", "codespace", "vscode", "coder", "gitpod", "default", "owner"],
24320
+ ...["local", "home", "work", "ops", "operator", "service", "bot", "agent", "demo", "sandbox", "main", "master"],
24321
+ // Given names that are also everyday words
24322
+ ...["will", "mark", "max", "bill", "rob", "pat", "sue", "may", "june", "april", "august", "art", "grant"],
24323
+ ...["hunter", "chase", "rose", "frank", "gene", "ray", "jack", "joy", "hope", "grace", "dawn", "summer", "guy"]
24324
+ ]);
24325
+ function currentUserName() {
24226
24326
  try {
24227
- name = process.env.REFLEX_REDACT_USER ?? userInfo().username;
24327
+ return process.env.REFLEX_REDACT_USER ?? userInfo().username;
24228
24328
  } catch {
24229
- name = void 0;
24329
+ return void 0;
24230
24330
  }
24231
- if (!name || name.length < 3) return void 0;
24232
- const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24233
- return new RegExp(`\\b${escaped}\\b`, "gi");
24234
24331
  }
24235
- var userPattern = currentUserPattern();
24236
- function redactionFingerprint() {
24237
- let name = "";
24238
- try {
24239
- name = process.env.REFLEX_REDACT_USER ?? userInfo().username;
24240
- } catch {
24241
- name = "";
24332
+ var escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24333
+ function userRules() {
24334
+ const rules2 = [];
24335
+ const name = currentUserName();
24336
+ const homeFolder = homedir().replace(/[\\/]+$/, "");
24337
+ if (homeFolder.length >= 2) {
24338
+ rules2.push({ name: "home", pattern: new RegExp(`(?<![\\w.-])${escapeRegExp(homeFolder)}(?![\\w.-])`, "g"), replace: "~" });
24339
+ }
24340
+ if (name && name.length >= 3 && !COMMON_NAMES.has(name.toLowerCase())) {
24341
+ rules2.push({ name: "username", pattern: new RegExp(`\\b${escapeRegExp(name)}\\b`, "gi"), replace: "<user>" });
24242
24342
  }
24343
+ return rules2;
24344
+ }
24345
+ var USER_RULES = userRules();
24346
+ function redactionFingerprint() {
24347
+ const name = currentUserName() ?? "";
24243
24348
  return createHash2("sha256").update(`${name}
24244
24349
  ${homedir()}`).digest("hex").slice(0, 16);
24245
24350
  }
@@ -24254,37 +24359,34 @@ function redactDeep(value) {
24254
24359
  function redactWithReport(input2) {
24255
24360
  let text = input2;
24256
24361
  let redactions = 0;
24257
- const rules = /* @__PURE__ */ new Set();
24258
- for (const rule of RULES) {
24362
+ const rules2 = /* @__PURE__ */ new Set();
24363
+ for (const rule of [...RULES, ...USER_RULES]) {
24259
24364
  text = text.replace(rule.pattern, (...args) => {
24260
24365
  redactions++;
24261
- rules.add(rule.name);
24366
+ rules2.add(rule.name);
24262
24367
  if (typeof rule.replace === "string") return rule.replace;
24263
24368
  const offsetIndex = args.findIndex((a) => typeof a === "number");
24264
24369
  const groups = args.slice(0, offsetIndex).map((a) => typeof a === "string" ? a : "");
24265
24370
  return rule.replace(...groups);
24266
24371
  });
24267
24372
  }
24268
- if (userPattern) {
24269
- text = text.replace(userPattern, () => {
24270
- redactions++;
24271
- rules.add("username");
24272
- return "<user>";
24273
- });
24274
- }
24275
- return { text, redactions, rules: [...rules] };
24373
+ return { text, redactions, rules: [...rules2] };
24276
24374
  }
24277
24375
  function redact(input2) {
24278
24376
  return redactWithReport(input2).text;
24279
24377
  }
24280
- var PATH_RULES = /* @__PURE__ */ new Set(["macos-home", "linux-home", "windows-home", "encoded-home", "email"]);
24378
+ var PATH_RULES = /* @__PURE__ */ new Set(["macos-home", "linux-home", "windows-home", "encoded-home", "email", "home", "username"]);
24281
24379
  function redactPath(input2) {
24282
24380
  let text = input2;
24283
- for (const rule of RULES) {
24381
+ for (const rule of [...RULES, ...USER_RULES]) {
24284
24382
  if (!PATH_RULES.has(rule.name) || typeof rule.replace !== "string") continue;
24285
24383
  text = text.replace(rule.pattern, rule.replace);
24286
24384
  }
24287
- return userPattern ? text.replace(userPattern, "<user>") : text;
24385
+ return text;
24386
+ }
24387
+ var REDACT_MARGIN = 1024;
24388
+ function redactTruncated(input2, max) {
24389
+ return redact(input2.slice(0, max + REDACT_MARGIN)).slice(0, max);
24288
24390
  }
24289
24391
  function excerpt(input2, maxLength = 160) {
24290
24392
  const flat = redact(input2).replace(/\s+/g, " ").trim();
@@ -24385,6 +24487,47 @@ async function replaceOwnedFile(path, content, mode = 420) {
24385
24487
  }
24386
24488
  }
24387
24489
 
24490
+ // ../../packages/safety/src/spawn.ts
24491
+ import { statSync } from "node:fs";
24492
+ import { posix, win32 } from "node:path";
24493
+ var isFile = (path) => {
24494
+ try {
24495
+ return statSync(path).isFile();
24496
+ } catch {
24497
+ return false;
24498
+ }
24499
+ };
24500
+ function findOnPath(name, host = {}) {
24501
+ const env = host.env ?? process.env;
24502
+ const exists2 = host.isFile ?? isFile;
24503
+ if ((host.platform ?? process.platform) !== "win32") {
24504
+ for (const dir of (env.PATH ?? "").split(posix.delimiter)) if (dir && exists2(posix.join(dir, name))) return posix.join(dir, name);
24505
+ return void 0;
24506
+ }
24507
+ const exts = (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").toLowerCase().split(";").filter(Boolean);
24508
+ const names = exts.some((e2) => name.toLowerCase().endsWith(e2)) ? [name] : exts.map((e2) => name + e2);
24509
+ for (const dir of (env.Path ?? env.PATH ?? "").split(win32.delimiter)) {
24510
+ if (!dir) continue;
24511
+ for (const n of names) if (exists2(win32.join(dir, n))) return win32.join(dir, n);
24512
+ }
24513
+ return void 0;
24514
+ }
24515
+ var UNSAFE_FOR_CMD = /["%\r\n\0]/;
24516
+ function agentLaunch(command, args, host = {}) {
24517
+ if ((host.platform ?? process.platform) !== "win32") return { command, args };
24518
+ const path = findOnPath(command, host);
24519
+ if (!path) return { command, args };
24520
+ if (!/\.(cmd|bat)$/i.test(path)) return { command: path, args };
24521
+ if ([path, ...args].some((a) => UNSAFE_FOR_CMD.test(a))) {
24522
+ throw new Error(
24523
+ `${win32.basename(path)} is a Windows batch launcher, which can't be given quotes, % or line breaks safely. Leave them out, or install ${command} as an .exe.`
24524
+ );
24525
+ }
24526
+ const line2 = [path, ...args].map((a) => `"${a.replace(/(\\+)$/, "$1$1")}"`).join(" ");
24527
+ const env = host.env ?? process.env;
24528
+ return { command: env.ComSpec ?? "cmd.exe", args: ["/d", "/s", "/v:off", "/c", `"${line2}"`], windowsVerbatimArguments: true };
24529
+ }
24530
+
24388
24531
  // ../../packages/adapters/src/jsonl.ts
24389
24532
  import { createReadStream } from "node:fs";
24390
24533
  import { createInterface as createInterface2 } from "node:readline";
@@ -24392,19 +24535,19 @@ var MAX_LINE_BYTES = 4 * 1024 * 1024;
24392
24535
  async function* readJsonl(path) {
24393
24536
  const stream = createReadStream(path, { encoding: "utf8" });
24394
24537
  const rl = createInterface2({ input: stream, crlfDelay: Infinity });
24395
- let line = 0;
24538
+ let line2 = 0;
24396
24539
  try {
24397
24540
  for await (const raw of rl) {
24398
- line++;
24541
+ line2++;
24399
24542
  if (!raw.trim()) continue;
24400
24543
  if (raw.length > MAX_LINE_BYTES) {
24401
- yield { line, error: "too-large" };
24544
+ yield { line: line2, error: "too-large" };
24402
24545
  continue;
24403
24546
  }
24404
24547
  try {
24405
- yield { line, value: JSON.parse(raw) };
24548
+ yield { line: line2, value: JSON.parse(raw) };
24406
24549
  } catch {
24407
- yield { line, error: "invalid-json" };
24550
+ yield { line: line2, error: "invalid-json" };
24408
24551
  }
24409
24552
  }
24410
24553
  } finally {
@@ -24422,10 +24565,10 @@ var MAX_REQUEST_CHARS = 2e3;
24422
24565
  var MAX_COMMAND_CHARS = 600;
24423
24566
  var MAX_ASSISTANT_CHARS = 400;
24424
24567
  var clean = {
24425
- request: (text) => redact(text.slice(0, MAX_REQUEST_CHARS)).trim(),
24426
- command: (text) => redact(text.slice(0, MAX_COMMAND_CHARS)).trim(),
24427
- assistant: (text) => redact(text.slice(0, MAX_ASSISTANT_CHARS)).trim(),
24428
- path: (text) => redact(text.slice(0, 400))
24568
+ request: (text) => redactTruncated(text, MAX_REQUEST_CHARS).trim(),
24569
+ command: (text) => redactTruncated(text, MAX_COMMAND_CHARS).trim(),
24570
+ assistant: (text) => redactTruncated(text, MAX_ASSISTANT_CHARS).trim(),
24571
+ path: (text) => redactTruncated(text, 400)
24429
24572
  };
24430
24573
  function isHarnessText(text) {
24431
24574
  const t = text.trimStart();
@@ -24647,13 +24790,13 @@ var ClaudeCodeAdapter = class {
24647
24790
  let skippedRecords = 0;
24648
24791
  const fallbackId = basename2(file2.path, ".jsonl");
24649
24792
  try {
24650
- for await (const line of readJsonl(file2.path)) {
24793
+ for await (const line2 of readJsonl(file2.path)) {
24651
24794
  totalRecords++;
24652
- if (line.error) {
24795
+ if (line2.error) {
24653
24796
  skippedRecords++;
24654
24797
  continue;
24655
24798
  }
24656
- const parsed = ClaudeRecord.safeParse(line.value);
24799
+ const parsed = ClaudeRecord.safeParse(line2.value);
24657
24800
  if (!parsed.success) {
24658
24801
  skippedRecords++;
24659
24802
  continue;
@@ -24835,27 +24978,27 @@ var CodexAdapter = class {
24835
24978
  const eventUserMessages = [];
24836
24979
  let model2;
24837
24980
  try {
24838
- for await (const line of readJsonl(file2.path)) {
24981
+ for await (const line2 of readJsonl(file2.path)) {
24839
24982
  totalRecords++;
24840
- if (line.error) {
24983
+ if (line2.error) {
24841
24984
  skippedRecords++;
24842
24985
  continue;
24843
24986
  }
24844
- const wrapped = RolloutLine.safeParse(line.value);
24987
+ const wrapped = RolloutLine.safeParse(line2.value);
24845
24988
  if (!wrapped.success) {
24846
24989
  skippedRecords++;
24847
24990
  continue;
24848
24991
  }
24849
24992
  const at = wrapped.data.timestamp;
24850
24993
  const kind = wrapped.data.type;
24851
- const body = wrapped.data.payload ?? line.value;
24994
+ const body = wrapped.data.payload ?? line2.value;
24852
24995
  b3.touch(at);
24853
24996
  if (kind === "session_meta") {
24854
- const meta3 = Item.safeParse({ type: "session_meta", ...body });
24855
- if (meta3.success) {
24856
- if (meta3.data.id) b3.nativeId = meta3.data.id.slice(0, 80);
24857
- if (meta3.data.cwd) b3.cwd = meta3.data.cwd;
24858
- b3.touch(meta3.data.timestamp);
24997
+ const meta4 = Item.safeParse({ type: "session_meta", ...body });
24998
+ if (meta4.success) {
24999
+ if (meta4.data.id) b3.nativeId = meta4.data.id.slice(0, 80);
25000
+ if (meta4.data.cwd) b3.cwd = meta4.data.cwd;
25001
+ b3.touch(meta4.data.timestamp);
24859
25002
  }
24860
25003
  continue;
24861
25004
  }
@@ -24951,7 +25094,7 @@ var CodexAdapter = class {
24951
25094
  };
24952
25095
 
24953
25096
  // ../../packages/adapters/src/cursor.ts
24954
- import { existsSync, statSync } from "node:fs";
25097
+ import { existsSync, statSync as statSync2 } from "node:fs";
24955
25098
  import { lstat as lstat3, readdir as readdir2 } from "node:fs/promises";
24956
25099
  import { homedir as homedir6 } from "node:os";
24957
25100
  import { basename as basename4, dirname as dirname2, join as join6 } from "node:path";
@@ -25042,7 +25185,7 @@ var MAX_AGENT_TRANSCRIPTS = 300;
25042
25185
  async function agentTranscripts(chatFile) {
25043
25186
  return listFiles(join6(dirname2(chatFile), "subagents"), ".jsonl", 0);
25044
25187
  }
25045
- async function isFile(path) {
25188
+ async function isFile2(path) {
25046
25189
  try {
25047
25190
  return (await lstat3(path)).isFile();
25048
25191
  } catch {
@@ -25070,7 +25213,7 @@ function decodeWorkspace(encoded, root = "/") {
25070
25213
  budget--;
25071
25214
  const candidate = join6(dir, tokens2.slice(i, j2).join("-"));
25072
25215
  try {
25073
- if (existsSync(candidate) && statSync(candidate).isDirectory()) {
25216
+ if (existsSync(candidate) && statSync2(candidate).isDirectory()) {
25074
25217
  const found = walk(candidate, j2);
25075
25218
  if (found) return found;
25076
25219
  }
@@ -25122,11 +25265,11 @@ var CursorAdapter = class {
25122
25265
  }
25123
25266
  async requestPermission(ask2, days) {
25124
25267
  if (!await ask2(`Read Cursor agent sessions from the last ${days} day${days === 1 ? "" : "s"} at ${displayPath(this.root)}?`)) return false;
25125
- if (this.stateDb && await isFile(this.stateDb)) {
25126
- const allowed = await ask2(
25268
+ if (this.stateDb && await isFile2(this.stateDb)) {
25269
+ const allowed2 = await ask2(
25127
25270
  `Also read which model each Cursor chat used, from Cursor's app database at ${displayPath(this.stateDb)}? Read-only; only model names are extracted, never messages.`
25128
25271
  );
25129
- if (allowed) this.models = new CursorModelIndex(this.stateDb);
25272
+ if (allowed2) this.models = new CursorModelIndex(this.stateDb);
25130
25273
  }
25131
25274
  return true;
25132
25275
  }
@@ -25205,13 +25348,13 @@ var CursorAdapter = class {
25205
25348
  }
25206
25349
  /** Streams a transcript's user and assistant content blocks; malformed lines and blocks are counted and skipped. */
25207
25350
  async readBlocks(path, b3, counts, onBlock) {
25208
- for await (const line of readJsonl(path)) {
25351
+ for await (const line2 of readJsonl(path)) {
25209
25352
  counts.total++;
25210
- if (line.error) {
25353
+ if (line2.error) {
25211
25354
  counts.skipped++;
25212
25355
  continue;
25213
25356
  }
25214
- const parsed = CursorRecord.safeParse(line.value);
25357
+ const parsed = CursorRecord.safeParse(line2.value);
25215
25358
  if (!parsed.success) {
25216
25359
  counts.skipped++;
25217
25360
  continue;
@@ -25801,7 +25944,7 @@ function bigrams(stems) {
25801
25944
  }
25802
25945
  var BIGRAM_BLEND = 0.3;
25803
25946
  function termSimilarities(termLists, weights) {
25804
- const stems = termLists.map((terms) => terms.map(stem));
25947
+ const stems = termLists.map((terms2) => terms2.map(stem));
25805
25948
  const words2 = buildTfIdf(stems, weights && new Map([...weights].map(([t, w2]) => [stem(t), w2]))).vectors;
25806
25949
  const pairs = buildTfIdf(stems.map(bigrams)).vectors;
25807
25950
  return (i, j2) => {
@@ -25829,9 +25972,9 @@ var CONCEPT_WORDS = {
25829
25972
  var CONCEPT_OF = /* @__PURE__ */ new Map();
25830
25973
  var DEVELOPER_WORDS = /* @__PURE__ */ new Set([...Object.values(CONCEPT_WORDS).flat(), ...Object.values(CANONICAL)]);
25831
25974
  for (const [concept, words2] of Object.entries(CONCEPT_WORDS)) for (const w2 of words2) CONCEPT_OF.set(w2, concept);
25832
- function concepts(terms) {
25975
+ function concepts(terms2) {
25833
25976
  const v2 = /* @__PURE__ */ new Map();
25834
- for (const t of terms) {
25977
+ for (const t of terms2) {
25835
25978
  const c2 = t.startsWith("@") ? "dependency" : CONCEPT_OF.get(t) ?? CONCEPT_OF.get(stem(t));
25836
25979
  if (c2) v2.set(c2, (v2.get(c2) ?? 0) + 1);
25837
25980
  }
@@ -25879,24 +26022,33 @@ var WEIGHTS = {
25879
26022
  repository: 0.05
25880
26023
  };
25881
26024
  function jaccard(a, b3) {
25882
- const A3 = new Set(a);
25883
- const B2 = new Set(b3);
26025
+ return setJaccard(new Set(a), new Set(b3));
26026
+ }
26027
+ function setJaccard(A3, B2) {
25884
26028
  if (!A3.size && !B2.size) return 0;
25885
26029
  let inter = 0;
25886
26030
  for (const x2 of A3) if (B2.has(x2)) inter++;
25887
26031
  return inter / (A3.size + B2.size - inter);
25888
26032
  }
26033
+ var lcsRows = new Int32Array(0);
25889
26034
  function lcsLength(a, b3) {
25890
26035
  if (!a.length || !b3.length) return 0;
25891
- let prev = new Array(b3.length + 1).fill(0);
26036
+ const width = b3.length + 1;
26037
+ if (lcsRows.length < 2 * width) lcsRows = new Int32Array(2 * width);
26038
+ const rows2 = lcsRows;
26039
+ let prev = 0;
26040
+ let cur = width;
26041
+ rows2.fill(0, prev, prev + width);
25892
26042
  for (let i = 1; i <= a.length; i++) {
25893
- const cur = new Array(b3.length + 1).fill(0);
26043
+ rows2[cur] = 0;
25894
26044
  for (let j2 = 1; j2 <= b3.length; j2++) {
25895
- cur[j2] = a[i - 1] === b3[j2 - 1] ? prev[j2 - 1] + 1 : Math.max(prev[j2], cur[j2 - 1]);
26045
+ rows2[cur + j2] = a[i - 1] === b3[j2 - 1] ? rows2[prev + j2 - 1] + 1 : Math.max(rows2[prev + j2], rows2[cur + j2 - 1]);
25896
26046
  }
26047
+ const done = prev;
25897
26048
  prev = cur;
26049
+ cur = done;
25898
26050
  }
25899
- return prev[b3.length];
26051
+ return rows2[prev + b3.length];
25900
26052
  }
25901
26053
  var COARSE = {
25902
26054
  "inspect-git": "git",
@@ -25920,16 +26072,21 @@ var COARSE = {
25920
26072
  function collapse(seq) {
25921
26073
  return seq.filter((s, i) => i === 0 || seq[i - 1] !== s);
25922
26074
  }
26075
+ var steps = (seq) => ({ seq, set: new Set(seq) });
26076
+ function actionShape(sequence) {
26077
+ const fine = sequence.filter((s) => s !== "summarize");
26078
+ return { fine: steps(fine), coarse: steps(collapse(fine.map((v2) => COARSE[v2] ?? v2))) };
26079
+ }
25923
26080
  function sequenceAgreement(x2, y3) {
25924
- if (!x2.length || !y3.length) return 0;
25925
- const lcs = 2 * lcsLength(x2, y3) / (x2.length + y3.length);
25926
- return 0.5 * lcs + 0.5 * jaccard(x2, y3);
26081
+ if (!x2.seq.length || !y3.seq.length) return 0;
26082
+ const lcs = 2 * lcsLength(x2.seq, y3.seq) / (x2.seq.length + y3.seq.length);
26083
+ return 0.5 * lcs + 0.5 * setJaccard(x2.set, y3.set);
26084
+ }
26085
+ function shapeSimilarity(a, b3) {
26086
+ return 0.5 * sequenceAgreement(a.fine, b3.fine) + 0.5 * sequenceAgreement(a.coarse, b3.coarse);
25927
26087
  }
25928
26088
  function actionSimilarity(a, b3) {
25929
- const x2 = a.filter((s) => s !== "summarize");
25930
- const y3 = b3.filter((s) => s !== "summarize");
25931
- const coarse = (s) => collapse(s.map((v2) => COARSE[v2] ?? v2));
25932
- return 0.5 * sequenceAgreement(x2, y3) + 0.5 * sequenceAgreement(coarse(x2), coarse(y3));
26089
+ return shapeSimilarity(actionShape(a), actionShape(b3));
25933
26090
  }
25934
26091
  function opKeys(t) {
25935
26092
  const keys = new Set(t.commands.map(opKey));
@@ -25941,12 +26098,15 @@ function opKeys(t) {
25941
26098
  keys.delete("");
25942
26099
  return keys;
25943
26100
  }
25944
- function similarity(a, b3, intentScore, keysA = opKeys(a), keysB = opKeys(b3)) {
26101
+ function traceFeatures(t) {
26102
+ return { actions: actionShape(t.actionSequence), keys: opKeys(t), files: new Set(t.fileCategories) };
26103
+ }
26104
+ function similarity(a, b3, intentScore, fa = traceFeatures(a), fb = traceFeatures(b3)) {
25945
26105
  const parts = {
25946
26106
  intent: intentScore,
25947
- actions: actionSimilarity(a.actionSequence, b3.actionSequence),
25948
- commands: jaccard(keysA, keysB),
25949
- files: jaccard(a.fileCategories, b3.fileCategories),
26107
+ actions: shapeSimilarity(fa.actions, fb.actions),
26108
+ commands: setJaccard(fa.keys, fb.keys),
26109
+ files: setJaccard(fa.files, fb.files),
25950
26110
  repository: a.projectHash && a.projectHash === b3.projectHash ? 1 : 0
25951
26111
  };
25952
26112
  const total = WEIGHTS.intent * parts.intent + WEIGHTS.actions * parts.actions + WEIGHTS.commands * parts.commands + WEIGHTS.files * parts.files + WEIGHTS.repository * parts.repository;
@@ -26040,8 +26200,11 @@ function render(polarity, ws) {
26040
26200
  return polarity === "avoid" ? `Don't ${phrase}.` : `${phrase[0].toUpperCase()}${phrase.slice(1)}.`;
26041
26201
  }
26042
26202
  function recurringCorrections(perInstance) {
26203
+ return recurringCorrectionsBySession(perInstance).map(({ instances: _3, ...c2 }) => c2);
26204
+ }
26205
+ function recurringCorrectionsBySession(perInstance) {
26043
26206
  const items = perInstance.flatMap((cs, inst) => cs.map((c2) => ({ ...c2, inst, keys: matchKeys(c2.words) })));
26044
- const rules = /* @__PURE__ */ new Map();
26207
+ const rules2 = /* @__PURE__ */ new Map();
26045
26208
  for (let i = 0; i < items.length; i++) {
26046
26209
  for (let j2 = i + 1; j2 < items.length; j2++) {
26047
26210
  const a = items[i];
@@ -26051,16 +26214,16 @@ function recurringCorrections(perInstance) {
26051
26214
  const shared = a.words.filter((_3, k3) => other.has(a.keys[k3]));
26052
26215
  if (!wellFormed(a.polarity, shared)) continue;
26053
26216
  const id = `${a.polarity}:${shared.join(" ")}`;
26054
- const rule = rules.get(id) ?? { polarity: a.polarity, words: shared, sessions: /* @__PURE__ */ new Set() };
26217
+ const rule = rules2.get(id) ?? { polarity: a.polarity, words: shared, sessions: /* @__PURE__ */ new Set() };
26055
26218
  rule.sessions.add(a.inst).add(b3.inst);
26056
- rules.set(id, rule);
26219
+ rules2.set(id, rule);
26057
26220
  }
26058
26221
  }
26059
- const all = [...rules.values()];
26222
+ const all = [...rules2.values()];
26060
26223
  const covered = (r2) => all.some(
26061
26224
  (s) => s !== r2 && s.polarity === r2.polarity && s.words.length < r2.words.length && s.words.every((w2) => r2.words.includes(w2)) && [...r2.sessions].every((x2) => s.sessions.has(x2))
26062
26225
  );
26063
- return all.filter((r2) => !covered(r2)).map((r2) => ({ polarity: r2.polarity, text: render(r2.polarity, r2.words), sessions: r2.sessions.size })).sort((a, b3) => b3.sessions - a.sessions || a.text.localeCompare(b3.text));
26226
+ return all.filter((r2) => !covered(r2)).map((r2) => ({ polarity: r2.polarity, text: render(r2.polarity, r2.words), sessions: r2.sessions.size, instances: [...r2.sessions].sort((a, b3) => a - b3) })).sort((a, b3) => b3.sessions - a.sessions || a.text.localeCompare(b3.text));
26064
26227
  }
26065
26228
 
26066
26229
  // ../../packages/analysis/src/context.ts
@@ -26068,12 +26231,12 @@ function withFloor(vectors, floor) {
26068
26231
  return Object.assign(vectors, { floor });
26069
26232
  }
26070
26233
  var CONTEXT_CHARS = 2e3;
26071
- function isNoiseLine(line) {
26072
- return /^\s*at\s/.test(line) || /\d{4}-\d\d-\d\dT\d\d:\d\d/.test(line) || /^\s*[✓✗✔✘×√]\s/.test(line) || /^\s*\[[\w-]+\]/.test(line) || // Mostly digits and symbols. Letters of any script count, so non-English text is never noise.
26073
- line.length > 30 && (line.match(new RegExp("\\p{L}{2,}", "gu")) ?? []).join("").length / line.length < 0.4;
26234
+ function isNoiseLine(line2) {
26235
+ return /^\s*at\s/.test(line2) || /\d{4}-\d\d-\d\dT\d\d:\d\d/.test(line2) || /^\s*[✓✗✔✘×√]\s/.test(line2) || /^\s*\[[\w-]+\]/.test(line2) || // Mostly digits and symbols. Letters of any script count, so non-English text is never noise.
26236
+ line2.length > 30 && (line2.match(new RegExp("\\p{L}{2,}", "gu")) ?? []).join("").length / line2.length < 0.4;
26074
26237
  }
26075
26238
  function requestWords(text) {
26076
- const kept = text.replace(/```[\s\S]*?(```|$)/g, " ").split("\n").filter((line) => !isNoiseLine(line)).join("\n").replace(/\bat [\w.<>$]+ \([^)]*:\d+:\d+\)/g, " ").trim();
26239
+ const kept = text.replace(/```[\s\S]*?(```|$)/g, " ").split("\n").filter((line2) => !isNoiseLine(line2)).join("\n").replace(/\bat [\w.<>$]+ \([^)]*:\d+:\d+\)/g, " ").trim();
26077
26240
  return kept || text;
26078
26241
  }
26079
26242
  function contextDocument(t, request) {
@@ -26122,8 +26285,8 @@ function usedSkill(trace, name) {
26122
26285
  return (trace.skillsUsed ?? []).some((s) => s === name || s.endsWith(`:${name}`));
26123
26286
  }
26124
26287
  function buildTrace(session) {
26125
- const steps = [];
26126
- const commands = [];
26288
+ const steps2 = [];
26289
+ const commands2 = [];
26127
26290
  const tools = /* @__PURE__ */ new Set();
26128
26291
  const fileCategories = /* @__PURE__ */ new Set();
26129
26292
  const eventHashes = [];
@@ -26140,8 +26303,8 @@ function buildTrace(session) {
26140
26303
  tools.add("shell");
26141
26304
  for (const s of skillsIn(ev.command)) skills.add(s);
26142
26305
  for (const fp of classifyCommand(ev.command)) {
26143
- commands.push(ev.isError ? { ...fp, failed: true } : fp);
26144
- steps.push({ action: fp.action, isError: ev.isError, command: fp });
26306
+ commands2.push(ev.isError ? { ...fp, failed: true } : fp);
26307
+ steps2.push({ action: fp.action, isError: ev.isError, command: fp });
26145
26308
  show2(fp.normalized);
26146
26309
  }
26147
26310
  eventHashes.push(shortHash(`shell|${ev.at ?? ""}|${ev.command}`));
@@ -26152,7 +26315,7 @@ function buildTrace(session) {
26152
26315
  if (ev.op === "read") for (const s of skillsIn(ev.path)) skills.add(s);
26153
26316
  const category = fileCategory(ev.path);
26154
26317
  fileCategories.add(category);
26155
- steps.push({ action: fileAction(ev.op, category), isError: ev.isError });
26318
+ steps2.push({ action: fileAction(ev.op, category), isError: ev.isError });
26156
26319
  show2(`${ev.op === "read" ? "read" : "edit"} ${FILE_LABEL[category]}`);
26157
26320
  eventHashes.push(shortHash(`file|${ev.at ?? ""}|${ev.op}|${ev.path}`));
26158
26321
  break;
@@ -26162,7 +26325,7 @@ function buildTrace(session) {
26162
26325
  if (ev.skill) skills.add(ev.skill);
26163
26326
  const action = TOOL_ACTIONS[ev.tool];
26164
26327
  if (action) {
26165
- steps.push({ action, isError: ev.isError });
26328
+ steps2.push({ action, isError: ev.isError });
26166
26329
  show2(action === "search-code" ? "search code" : "look up docs");
26167
26330
  }
26168
26331
  break;
@@ -26174,14 +26337,14 @@ function buildTrace(session) {
26174
26337
  break;
26175
26338
  }
26176
26339
  }
26177
- for (const fp of commands) {
26340
+ for (const fp of commands2) {
26178
26341
  if (fp.action === "inspect-ci") fileCategories.add("ci-config");
26179
26342
  if (fp.action === "inspect-dependencies" && /<file>/.test(fp.normalized)) fileCategories.add("dependency-manifest");
26180
26343
  }
26181
26344
  const lastAssistant = [...session.events].reverse().find((e2) => e2.kind !== "error");
26182
26345
  const summarized = lastAssistant?.kind === "assistant";
26183
26346
  const actionSequence = [];
26184
- for (const s of steps) {
26347
+ for (const s of steps2) {
26185
26348
  if (actionSequence[actionSequence.length - 1] !== s.action) actionSequence.push(s.action);
26186
26349
  }
26187
26350
  if (summarized) actionSequence.push("summarize");
@@ -26200,11 +26363,11 @@ function buildTrace(session) {
26200
26363
  projectHash: session.project?.pathHash,
26201
26364
  intents,
26202
26365
  tools: [...tools].sort(),
26203
- commands,
26366
+ commands: commands2,
26204
26367
  fileCategories: [...fileCategories].sort(),
26205
26368
  actionSequence: actionSequence.slice(0, MAX_SEQUENCE),
26206
26369
  displaySteps,
26207
- outcome: outcomeOf(steps, summarized),
26370
+ outcome: outcomeOf(steps2, summarized),
26208
26371
  excerpt: excerpt(session.requests[0]?.text ?? "", 180),
26209
26372
  fingerprint,
26210
26373
  eventHashes,
@@ -26237,14 +26400,14 @@ function summarizeAgents(session) {
26237
26400
  toolCalls: session.events.filter((e2) => (e2.kind === "shell" || e2.kind === "file" || e2.kind === "tool") && e2.byAgent).length
26238
26401
  };
26239
26402
  }
26240
- function outcomeOf(steps, summarized) {
26403
+ function outcomeOf(steps2, summarized) {
26241
26404
  let lastModify = -1;
26242
- steps.forEach((s, i) => {
26405
+ steps2.forEach((s, i) => {
26243
26406
  if (MODIFY_ACTIONS.has(s.action)) lastModify = i;
26244
26407
  });
26245
- const verified = steps.some((s, i) => i > lastModify && VERIFY_ACTIONS.has(s.action) && !s.isError);
26246
- const failedAt = steps.findIndex((s) => s.isError);
26247
- const recoveredFromFailure = failedAt >= 0 && steps.slice(failedAt + 1).some((s) => VERIFY_ACTIONS.has(s.action) && !s.isError);
26408
+ const verified = steps2.some((s, i) => i > lastModify && VERIFY_ACTIONS.has(s.action) && !s.isError);
26409
+ const failedAt = steps2.findIndex((s) => s.isError);
26410
+ const recoveredFromFailure = failedAt >= 0 && steps2.slice(failedAt + 1).some((s) => VERIFY_ACTIONS.has(s.action) && !s.isError);
26248
26411
  return { verified, recoveredFromFailure, modified: lastModify >= 0, summarized };
26249
26412
  }
26250
26413
  function isGenericTrace(trace) {
@@ -26362,6 +26525,30 @@ function fillerWeights(traces) {
26362
26525
  var CLUSTER_THRESHOLD = 0.45;
26363
26526
  var MIN_INTENT_COHESION = 0.2;
26364
26527
  var MIN_INTENT_LINK = 0.35;
26528
+ var PairMatrix = class _PairMatrix {
26529
+ constructor(size2) {
26530
+ this.size = size2;
26531
+ this.values = new Float64Array(size2 * (size2 - 1) / 2);
26532
+ }
26533
+ size;
26534
+ values;
26535
+ index(i, j2) {
26536
+ const a = i < j2 ? i : j2;
26537
+ const b3 = i < j2 ? j2 : i;
26538
+ return a * (2 * this.size - a - 1) / 2 + b3 - a - 1;
26539
+ }
26540
+ get(i, j2) {
26541
+ return i === j2 ? 1 : this.values[this.index(i, j2)];
26542
+ }
26543
+ set(i, j2, value) {
26544
+ this.values[this.index(i, j2)] = value;
26545
+ }
26546
+ copy() {
26547
+ const m2 = new _PairMatrix(this.size);
26548
+ m2.values.set(this.values);
26549
+ return m2;
26550
+ }
26551
+ };
26365
26552
  var EMBEDDING_FLOOR = 0.05;
26366
26553
  function rescaleEmbedding(cos, floor = EMBEDDING_FLOOR) {
26367
26554
  return Math.min(1, Math.max(0, (cos - floor) / (1 - floor)));
@@ -26382,21 +26569,15 @@ function intentSimilarities(traces, vectors) {
26382
26569
  }
26383
26570
  function similarityMatrices(traces, vectors) {
26384
26571
  const intentOf = intentSimilarities(traces, vectors);
26385
- const keys = traces.map(opKeys);
26572
+ const features = traces.map(traceFeatures);
26386
26573
  const n = traces.length;
26387
- const make = () => Array.from({ length: n }, () => new Array(n).fill(1));
26388
- const m2 = { total: make(), intent: make(), actions: make() };
26574
+ const m2 = { total: new PairMatrix(n), intent: new PairMatrix(n), actions: new PairMatrix(n) };
26389
26575
  for (let i = 0; i < n; i++) {
26390
26576
  for (let j2 = i + 1; j2 < n; j2++) {
26391
- const s = similarity(traces[i], traces[j2], intentOf(i, j2), keys[i], keys[j2]);
26392
- for (const [name, v2] of [
26393
- ["total", s.total],
26394
- ["intent", s.intent],
26395
- ["actions", s.actions]
26396
- ]) {
26397
- m2[name][i][j2] = v2;
26398
- m2[name][j2][i] = v2;
26399
- }
26577
+ const s = similarity(traces[i], traces[j2], intentOf(i, j2), features[i], features[j2]);
26578
+ m2.total.set(i, j2, s.total);
26579
+ m2.intent.set(i, j2, s.intent);
26580
+ m2.actions.set(i, j2, s.actions);
26400
26581
  }
26401
26582
  }
26402
26583
  return m2;
@@ -26406,7 +26587,7 @@ function meanPairwise(matrix, members2) {
26406
26587
  let pairs = 0;
26407
26588
  for (let x2 = 0; x2 < members2.length; x2++)
26408
26589
  for (let y3 = x2 + 1; y3 < members2.length; y3++) {
26409
- total += matrix[members2[x2]][members2[y3]];
26590
+ total += matrix.get(members2[x2], members2[y3]);
26410
26591
  pairs++;
26411
26592
  }
26412
26593
  return pairs ? total / pairs : 1;
@@ -26415,37 +26596,56 @@ function clusterTraces(traces, threshold = CLUSTER_THRESHOLD, vectors, minIntent
26415
26596
  const sim = similarityMatrices(traces, vectors);
26416
26597
  const n = traces.length;
26417
26598
  const members2 = traces.map((_3, i) => [i]);
26418
- const link = sim.total.map((row) => [...row]);
26419
- const intentLink = sim.intent.map((row) => [...row]);
26599
+ const link = sim.total.copy();
26600
+ const intentLink = sim.intent.copy();
26601
+ const bestJ = new Int32Array(n).fill(-1);
26602
+ const bestLink = new Float64Array(n).fill(-1);
26603
+ const findBest = (i) => {
26604
+ bestJ[i] = -1;
26605
+ bestLink[i] = -1;
26606
+ for (let j2 = i + 1; j2 < n; j2++) {
26607
+ if (!members2[j2] || intentLink.get(i, j2) < minIntent) continue;
26608
+ const v2 = link.get(i, j2);
26609
+ if (v2 > bestLink[i]) {
26610
+ bestLink[i] = v2;
26611
+ bestJ[i] = j2;
26612
+ }
26613
+ }
26614
+ };
26615
+ for (let i = 0; i < n; i++) findBest(i);
26420
26616
  for (; ; ) {
26421
26617
  let best = -1;
26422
26618
  let bi = -1;
26423
- let bj = -1;
26424
26619
  for (let i = 0; i < n; i++) {
26425
- if (!members2[i]) continue;
26426
- for (let j2 = i + 1; j2 < n; j2++) {
26427
- if (!members2[j2] || intentLink[i][j2] < minIntent) continue;
26428
- if (link[i][j2] > best) {
26429
- best = link[i][j2];
26430
- bi = i;
26431
- bj = j2;
26432
- }
26620
+ if (members2[i] && bestJ[i] >= 0 && bestLink[i] > best) {
26621
+ best = bestLink[i];
26622
+ bi = i;
26433
26623
  }
26434
26624
  }
26435
26625
  if (bi < 0 || best < threshold) break;
26626
+ const bj = bestJ[bi];
26436
26627
  const a = members2[bi];
26437
26628
  const b3 = members2[bj];
26438
26629
  for (let k3 = 0; k3 < n; k3++) {
26439
26630
  if (!members2[k3] || k3 === bi || k3 === bj) continue;
26440
- const v2 = (a.length * link[bi][k3] + b3.length * link[bj][k3]) / (a.length + b3.length);
26441
- link[bi][k3] = v2;
26442
- link[k3][bi] = v2;
26443
- const w2 = (a.length * intentLink[bi][k3] + b3.length * intentLink[bj][k3]) / (a.length + b3.length);
26444
- intentLink[bi][k3] = w2;
26445
- intentLink[k3][bi] = w2;
26631
+ link.set(bi, k3, (a.length * link.get(bi, k3) + b3.length * link.get(bj, k3)) / (a.length + b3.length));
26632
+ intentLink.set(bi, k3, (a.length * intentLink.get(bi, k3) + b3.length * intentLink.get(bj, k3)) / (a.length + b3.length));
26446
26633
  }
26447
26634
  members2[bi] = [...a, ...b3].sort((x2, y3) => x2 - y3);
26448
26635
  members2[bj] = null;
26636
+ bestJ[bj] = -1;
26637
+ findBest(bi);
26638
+ for (let k3 = 0; k3 < bj; k3++) {
26639
+ if (!members2[k3] || k3 === bi) continue;
26640
+ if (bestJ[k3] === bi || bestJ[k3] === bj) findBest(k3);
26641
+ else if (k3 < bi && intentLink.get(k3, bi) >= minIntent) {
26642
+ const v2 = link.get(k3, bi);
26643
+ if (v2 > bestLink[k3] || v2 === bestLink[k3] && bi < bestJ[k3]) {
26644
+ bestLink[k3] = v2;
26645
+ bestJ[k3] = bi;
26646
+ }
26647
+ }
26648
+ }
26449
26649
  }
26450
26650
  return members2.filter((m2) => m2 !== null).map((m2) => ({
26451
26651
  members: m2,
@@ -26698,15 +26898,15 @@ function stepOrder(inst) {
26698
26898
  return at;
26699
26899
  }
26700
26900
  var LAST_OCCURRENCE = /* @__PURE__ */ new Set(["run-tests", "run-build", "run-lint", "inspect-diff"]);
26701
- function completionCriteria(steps) {
26901
+ function completionCriteria(steps2) {
26702
26902
  const out2 = [];
26703
- if (steps.has("inspect-ci")) out2.push("The CI-equivalent command succeeds locally where it can be reproduced.");
26704
- if (steps.has("run-tests")) out2.push("Relevant tests pass.");
26705
- if (steps.has("run-build")) out2.push("Build or typecheck succeeds.");
26706
- if (steps.has("run-lint")) out2.push("Linter passes.");
26707
- if (steps.has("inspect-diff") || steps.has("inspect-git")) out2.push("Repository state and the final diff have been reviewed; the diff contains only intended changes.");
26708
- if (steps.has("submit-review")) out2.push("The review is posted with concrete findings, or explicitly states that none were found.");
26709
- if (steps.has("summarize")) out2.push("A summary states the root cause (or findings), what changed, and how it was verified.");
26903
+ if (steps2.has("inspect-ci")) out2.push("The CI-equivalent command succeeds locally where it can be reproduced.");
26904
+ if (steps2.has("run-tests")) out2.push("Relevant tests pass.");
26905
+ if (steps2.has("run-build")) out2.push("Build or typecheck succeeds.");
26906
+ if (steps2.has("run-lint")) out2.push("Linter passes.");
26907
+ if (steps2.has("inspect-diff") || steps2.has("inspect-git")) out2.push("Repository state and the final diff have been reviewed; the diff contains only intended changes.");
26908
+ if (steps2.has("submit-review")) out2.push("The review is posted with concrete findings, or explicitly states that none were found.");
26909
+ if (steps2.has("summarize")) out2.push("A summary states the root cause (or findings), what changed, and how it was verified.");
26710
26910
  return out2;
26711
26911
  }
26712
26912
  function frequentTerms(instances, limit = 6) {
@@ -26770,15 +26970,15 @@ function analyze(traces, opts = {}) {
26770
26970
  if (cluster.members.length < MIN_INSTANCES) continue;
26771
26971
  if (cluster.intentCohesion < MIN_INTENT_COHESION || cluster.actionCohesion < MIN_ACTION_COHESION) continue;
26772
26972
  const group = cluster.members.map((i) => candidates[i]);
26773
- const steps = consensusSteps(group);
26774
- const stepKinds = new Set(steps.map((s) => s.kind));
26973
+ const steps2 = consensusSteps(group);
26974
+ const stepKinds = new Set(steps2.map((s) => s.kind));
26775
26975
  if (stepKinds.size - (stepKinds.has("summarize") ? 1 : 0) < 3) continue;
26776
- const terms = distinctiveTerms(group, context);
26976
+ const terms2 = distinctiveTerms(group, context);
26777
26977
  const frequent = frequentTerms(group);
26778
26978
  const fileCats = new Set(group.flatMap((g2) => g2.primary.fileCategories));
26779
26979
  const family = FAMILIES.filter((f) => f.requires(stepKinds, fileCats)).map((f) => ({ f, score: f.terms.filter((t) => frequent.includes(t)).length })).filter((x2) => x2.score > 0).sort((a, b3) => b3.score - a.score)[0]?.f;
26780
- const fallbackTerms = terms.slice(0, 3);
26781
- const baseSlug = family?.slug ?? toSlug(fallbackTerms.join(" ") || steps.map((s) => s.kind).slice(0, 2).join(" "));
26980
+ const fallbackTerms = terms2.slice(0, 3);
26981
+ const baseSlug = family?.slug ?? toSlug(fallbackTerms.join(" ") || steps2.map((s) => s.kind).slice(0, 2).join(" "));
26782
26982
  const inside = /* @__PURE__ */ new Map();
26783
26983
  for (const g2 of group) for (const s of skillsOf(g2)) inside.set(s, (inside.get(s) ?? 0) + 1);
26784
26984
  const rest = Math.max(1, instances.length - group.length);
@@ -26814,7 +27014,7 @@ function analyze(traces, opts = {}) {
26814
27014
  const dates = group.map((g2) => g2.primary.startedAt).filter((d3) => !!d3).sort();
26815
27015
  const verifiedRate = group.filter((g2) => g2.primary.outcome.verified).length / group.length;
26816
27016
  const durations = group.map((g2) => g2.primary.startedAt && g2.primary.endedAt ? (Date.parse(g2.primary.endedAt) - Date.parse(g2.primary.startedAt)) / 6e4 : NaN).filter((m2) => Number.isFinite(m2) && m2 > 0);
26817
- const consensus = steps.reduce((acc, s) => acc + s.support, 0) / steps.length;
27017
+ const consensus = steps2.reduce((acc, s) => acc + s.support, 0) / steps2.length;
26818
27018
  const confidence = 0.3 * Math.min(1, cluster.cohesion / 0.75) + 0.2 * Math.min(1, group.length / 6) + 0.15 * Math.min(1, repos.length / 3) + 0.2 * consensus + 0.15 * verifiedRate;
26819
27019
  const notes = [];
26820
27020
  if (repos.length === 1) notes.push("All evidence comes from a single repository; the skill may be repository-specific.");
@@ -26825,8 +27025,8 @@ function analyze(traces, opts = {}) {
26825
27025
  suggestions.push({
26826
27026
  slug,
26827
27027
  title: family?.title ?? `Repeated workflow: ${fallbackTerms.join(", ") || slug}`,
26828
- description: family?.description ?? `Repeated workflow involving ${steps.map((s) => s.label).slice(0, 3).join(", ")}.`,
26829
- whenToUse: family?.whenToUse ?? `Use for requests similar to: ${terms.slice(0, 5).join(", ")}.`,
27028
+ description: family?.description ?? `Repeated workflow involving ${steps2.map((s) => s.label).slice(0, 3).join(", ")}.`,
27029
+ whenToUse: family?.whenToUse ?? `Use for requests similar to: ${terms2.slice(0, 5).join(", ")}.`,
26830
27030
  confidence: Math.round(confidence * 100) / 100,
26831
27031
  cohesion: Math.round(cluster.cohesion * 100) / 100,
26832
27032
  instances: group.length,
@@ -26835,9 +27035,9 @@ function analyze(traces, opts = {}) {
26835
27035
  sources,
26836
27036
  firstSeen: dates[0],
26837
27037
  lastSeen: dates[dates.length - 1],
26838
- steps,
27038
+ steps: steps2,
26839
27039
  completion: completionCriteria(stepKinds),
26840
- topTerms: terms,
27040
+ topTerms: terms2,
26841
27041
  evidence: group.map((g2) => evidenceFor(g2, slug)).sort((a, b3) => (a.date ?? "").localeCompare(b3.date ?? "")),
26842
27042
  notes,
26843
27043
  verifiedRate: Math.round(verifiedRate * 100) / 100,
@@ -26974,8 +27174,8 @@ var requestDocument = (request) => contextDocument({ excerpt: "", fileCategories
26974
27174
  var DEFAULT_ROUTER_SETTINGS = { autopilot: false, explore: 0, protect: [] };
26975
27175
  function chooseRoute(guess, table2, opts) {
26976
27176
  const fallback = opts.sources[0] ?? "claude-code";
26977
- const allowed = (a) => opts.sources.includes(a.source);
26978
- const arms = (guess.kind ? table2.find((k3) => k3.kind.key === guess.kind.key)?.arms ?? [] : []).filter(allowed);
27177
+ const allowed2 = (a) => opts.sources.includes(a.source);
27178
+ const arms = (guess.kind ? table2.find((k3) => k3.kind.key === guess.kind.key)?.arms ?? [] : []).filter(allowed2);
26979
27179
  const p3 = pickArm(arms);
26980
27180
  const base = { guess, randomized: false, pick: p3.arm, arms };
26981
27181
  const explore = Math.min(MAX_EXPLORE, Math.max(0, opts.settings.explore));
@@ -27156,13 +27356,13 @@ function reviewSkill(skill, content, traces) {
27156
27356
  protected: fixed
27157
27357
  };
27158
27358
  if (n < MIN_REVIEW_SESSIONS) return { ...base, commands: [], missing: [], rarelyTaken: [], constraints: [] };
27159
- const steps = consensusSteps(instances).filter((s) => !GENERIC.has(s.kind) && MENTIONS[s.kind]);
27160
- const commands = steps.filter((s) => mentions(text, s.kind)).map((s) => ({ ...s, examples: s.examples.filter((e2) => !text.includes(e2.toLowerCase()) && !(s.kind.startsWith("inspect-") && WRITES.test(e2))) })).filter((s) => s.examples.length);
27161
- const missing = steps.filter((s) => !mentions(text, s.kind) && !(fixed.length && s.kind === "summarize"));
27359
+ const steps2 = consensusSteps(instances).filter((s) => !GENERIC.has(s.kind) && MENTIONS[s.kind]);
27360
+ const commands2 = steps2.filter((s) => mentions(text, s.kind)).map((s) => ({ ...s, examples: s.examples.filter((e2) => !text.includes(e2.toLowerCase()) && !(s.kind.startsWith("inspect-") && WRITES.test(e2))) })).filter((s) => s.examples.length);
27361
+ const missing = steps2.filter((s) => !mentions(text, s.kind) && !(fixed.length && s.kind === "summarize"));
27162
27362
  const share = (kind) => runs.filter((t) => kind === "apply-fix" ? t.actionSequence.some((a) => a.startsWith("modify-")) : t.actionSequence.includes(kind)).length / n;
27163
27363
  const rarelyTaken = Object.keys(MENTIONS).filter((k3) => !GENERIC.has(k3) && !k3.startsWith("modify-") && k3 !== "summarize" && mentions(text, k3) && share(k3) < STALE_BELOW).map((k3) => ({ kind: k3, label: STEP_TEXT[k3].label, share: share(k3) })).sort((a, b3) => a.share - b3.share).slice(0, MAX_RARELY);
27164
27364
  const constraints = recurringCorrections(runs.map((t) => t.corrections ?? [])).filter(isSafeConstraint).filter((c2) => c2.text.toLowerCase().replace(/[^a-z\s-]/g, "").split(/\s+/).some((w2) => w2.length > 2 && !VAGUE.has(w2) && !/^(don't|dont|never|always|avoid|use|prefer|run|keep)$/.test(w2))).filter((c2) => !(fixed.length && OUTPUT_WORDS.test(c2.text))).filter((c2) => !c2.text.toLowerCase().split(/\s+/).every((w2) => w2.length < 3 || text.includes(w2))).slice(0, MAX_CONSTRAINTS2);
27165
- return { ...base, commands, model: modelAdvice(runs), missing, rarelyTaken, constraints };
27365
+ return { ...base, commands: commands2, model: modelAdvice(runs), missing, rarelyTaken, constraints };
27166
27366
  }
27167
27367
  function outputShape(text) {
27168
27368
  const trimmed = text.trim();
@@ -27178,21 +27378,21 @@ function outputShape(text) {
27178
27378
  let fence = false;
27179
27379
  let prev = "";
27180
27380
  for (const raw of trimmed.split("\n")) {
27181
- const line = raw.trimEnd();
27182
- if (/^\s*```/.test(line)) {
27183
- shape.push(fence ? "code:end" : `code:${line.trim().slice(3).trim() || "text"}`);
27381
+ const line2 = raw.trimEnd();
27382
+ if (/^\s*```/.test(line2)) {
27383
+ shape.push(fence ? "code:end" : `code:${line2.trim().slice(3).trim() || "text"}`);
27184
27384
  fence = !fence;
27185
27385
  prev = "";
27186
27386
  continue;
27187
27387
  }
27188
27388
  if (fence) continue;
27189
27389
  let kind = "";
27190
- const h2 = /^(#{1,6})\s+(.+)$/.exec(line);
27390
+ const h2 = /^(#{1,6})\s+(.+)$/.exec(line2);
27191
27391
  if (h2) kind = `h${h2[1].length}:${h2[2].split(":")[0].replace(/[\d.,/-]+/g, "#").trim().toLowerCase()}`;
27192
- else if (/^\s*\|.*\|\s*$/.test(line)) kind = /^\s*\|[\s:|-]+\|\s*$/.test(line) ? "" : prev.startsWith("table") ? "table:row" : `table:${line.split("|").filter((c2) => c2.trim()).length}`;
27193
- else if (/^\s*[-*+]\s+/.test(line)) kind = "list";
27194
- else if (/^\s*\d+[.)]\s+/.test(line)) kind = "numbered";
27195
- else if (/^\s*\*\*[^*]+\*\*:?/.test(line)) kind = `label:${/\*\*([^*]+)\*\*/.exec(line)[1].toLowerCase()}`;
27392
+ else if (/^\s*\|.*\|\s*$/.test(line2)) kind = /^\s*\|[\s:|-]+\|\s*$/.test(line2) ? "" : prev.startsWith("table") ? "table:row" : `table:${line2.split("|").filter((c2) => c2.trim()).length}`;
27393
+ else if (/^\s*[-*+]\s+/.test(line2)) kind = "list";
27394
+ else if (/^\s*\d+[.)]\s+/.test(line2)) kind = "numbered";
27395
+ else if (/^\s*\*\*[^*]+\*\*:?/.test(line2)) kind = `label:${/\*\*([^*]+)\*\*/.exec(line2)[1].toLowerCase()}`;
27196
27396
  if (!kind || kind === prev && (kind === "list" || kind === "numbered" || kind === "table:row")) {
27197
27397
  if (kind) prev = kind;
27198
27398
  continue;
@@ -27203,6 +27403,136 @@ function outputShape(text) {
27203
27403
  return shape;
27204
27404
  }
27205
27405
 
27406
+ // ../../packages/analysis/src/handbook.ts
27407
+ var MAX_SOURCES = 5;
27408
+ var MIN_COMMAND_SESSIONS = 2;
27409
+ var WHEN_SHARE = 2 / 3;
27410
+ var WHEN_LIFT = 2;
27411
+ var SITUATIONS = [
27412
+ { category: "dependency-manifest", when: "when changing dependencies", words: ["dependency", "package", "install", "lockfile", "upgrade"] },
27413
+ { category: "migration", when: "when changing the database schema", words: ["migration", "schema", "database", "db", "sql"] },
27414
+ { category: "ci-config", when: "when working on CI", words: ["ci", "pipeline", "workflow", "github", "action"] },
27415
+ { category: "test", when: "when writing or changing tests", words: ["test", "spec"] },
27416
+ { category: "config", when: "when changing configuration", words: ["config", "configuration", "setting"] },
27417
+ { category: "docs", when: "when editing docs", words: ["doc", "readme", "documentation"] }
27418
+ ];
27419
+ var VERIFY = [
27420
+ { action: "run-tests", label: "Run tests with", words: ["test", "spec", "unit", "e2e"] },
27421
+ { action: "run-build", label: "Build or typecheck with", words: ["build", "compile", "typecheck", "type", "tsc"] },
27422
+ { action: "run-lint", label: "Lint with", words: ["lint", "format", "style", "prettier", "eslint"] }
27423
+ ];
27424
+ var projectOf = (i) => i.primary.projectHash;
27425
+ var time4 = (t) => t.startedAt ? Date.parse(t.startedAt) || 0 : 0;
27426
+ function sourcesOf(group) {
27427
+ const newest = [...group].sort((a, b3) => time4(b3.primary) - time4(a.primary));
27428
+ return {
27429
+ last: newest[0]?.primary.startedAt,
27430
+ sources: newest.slice(0, MAX_SOURCES).map((i) => ({ date: i.primary.startedAt, tool: i.primary.source, request: i.primary.excerpt }))
27431
+ };
27432
+ }
27433
+ function scopeOf(group) {
27434
+ const hashes = new Set(group.map(projectOf));
27435
+ if (hashes.size !== 1) return void 0;
27436
+ const hash2 = [...hashes][0];
27437
+ return hash2 ? { name: group[0].primary.projectName, hash: hash2 } : void 0;
27438
+ }
27439
+ function situation(group, others) {
27440
+ const count2 = (xs, cat) => xs.filter((i) => i.primary.fileCategories.includes(cat)).length;
27441
+ let best;
27442
+ for (const s of SITUATIONS) {
27443
+ const inside = count2(group, s.category) / group.length;
27444
+ if (inside < WHEN_SHARE) continue;
27445
+ const lift = inside / ((count2(others, s.category) + 0.5) / (others.length + 1));
27446
+ if (lift >= WHEN_LIFT && (!best || lift > best.lift)) best = { when: s.when, lift };
27447
+ }
27448
+ return best?.when;
27449
+ }
27450
+ function rules(instances, forgotten) {
27451
+ const out2 = [];
27452
+ for (const r2 of recurringCorrectionsBySession(instances.map((i) => i.primary.corrections ?? []))) {
27453
+ if (forgotten.has(r2.text) || !isSafeConstraint(r2)) continue;
27454
+ const group = r2.instances.map((k3) => instances[k3]);
27455
+ const project = scopeOf(group);
27456
+ const members2 = new Set(group);
27457
+ const others = instances.filter((i) => !members2.has(i) && (!project || projectOf(i) === project.hash));
27458
+ const when = situation(group, others);
27459
+ out2.push({ id: practiceId("rule", project?.hash, r2.text), kind: "rule", project, text: r2.text, when, sessions: r2.sessions, ...sourcesOf(group) });
27460
+ }
27461
+ return out2;
27462
+ }
27463
+ function commands(instances) {
27464
+ const byProject2 = /* @__PURE__ */ new Map();
27465
+ for (const i of instances) {
27466
+ const h2 = projectOf(i);
27467
+ if (h2) byProject2.set(h2, [...byProject2.get(h2) ?? [], i]);
27468
+ }
27469
+ const out2 = [];
27470
+ for (const [hash2, group] of byProject2) {
27471
+ for (const v2 of VERIFY) {
27472
+ const worked = /* @__PURE__ */ new Map();
27473
+ const failed = /* @__PURE__ */ new Map();
27474
+ for (const i of group) {
27475
+ const runs = i.primary.commands.filter((c2) => c2.action === v2.action);
27476
+ for (const cmd2 of new Set(runs.map((c2) => c2.normalized).filter(isSafeExample))) {
27477
+ const same = runs.filter((c2) => c2.normalized === cmd2);
27478
+ if (same.some((c2) => !c2.failed)) worked.set(cmd2, [...worked.get(cmd2) ?? [], i]);
27479
+ else failed.set(cmd2, (failed.get(cmd2) ?? 0) + 1);
27480
+ }
27481
+ }
27482
+ const top = [...worked].sort((a, b3) => b3[1].length - a[1].length || a[0].localeCompare(b3[0]))[0];
27483
+ if (!top || top[1].length < MIN_COMMAND_SESSIONS) continue;
27484
+ const [cmd, sessions2] = top;
27485
+ const notThis = [...failed].filter(([other, n]) => other !== cmd && n >= MIN_COMMAND_SESSIONS && !worked.has(other)).sort((a, b3) => b3[1] - a[1])[0];
27486
+ const text = `${v2.label} \`${cmd}\`.${notThis ? ` Not \`${notThis[0]}\`: it failed in ${notThis[1]} sessions.` : ""}`;
27487
+ out2.push({
27488
+ id: practiceId("command", hash2, `${v2.action}:${cmd}`),
27489
+ kind: "command",
27490
+ project: { name: sessions2[0].primary.projectName, hash: hash2 },
27491
+ text,
27492
+ sessions: sessions2.length,
27493
+ ...sourcesOf(sessions2)
27494
+ });
27495
+ }
27496
+ }
27497
+ return out2;
27498
+ }
27499
+ function practiceId(kind, project, key3) {
27500
+ return shortHash(`${kind}|${project ?? "*"}|${key3}`, 8);
27501
+ }
27502
+ function buildHandbook(traces, opts = {}) {
27503
+ const { instances } = deduplicate(traces);
27504
+ return [...commands(instances), ...rules(instances, opts.forgotten ?? /* @__PURE__ */ new Set())].sort(
27505
+ (a, b3) => b3.sessions - a.sessions || a.kind.localeCompare(b3.kind) || a.text.localeCompare(b3.text)
27506
+ );
27507
+ }
27508
+ function practicesFor(practices, projectHash) {
27509
+ return practices.filter((p3) => !p3.project || p3.project.hash === projectHash).sort((a, b3) => Number(!a.project) - Number(!b3.project));
27510
+ }
27511
+ var QUESTION_FILLER = new Set(
27512
+ "a an the to it is are be do does did how what when where which who why we i you our my your here there this that in on of for with and or should can could would will".split(" ")
27513
+ );
27514
+ function terms(text) {
27515
+ return new Set(
27516
+ text.toLowerCase().split(/[^a-z0-9.-]+/).map((w2) => w2.replace(/^[.-]+|[.-]+$/g, "")).filter((w2) => w2.length > 1 && !QUESTION_FILLER.has(w2)).map(stem)
27517
+ );
27518
+ }
27519
+ function practiceTerms(p3) {
27520
+ const extra = [];
27521
+ for (const s of SITUATIONS) if (p3.when === s.when) extra.push(...s.words);
27522
+ for (const v2 of VERIFY) if (p3.text.startsWith(v2.label)) extra.push(...v2.words, "command", "run");
27523
+ return terms(`${p3.text} ${p3.when ?? ""} ${extra.join(" ")}`);
27524
+ }
27525
+ function askHandbook(practices, question, projectHash, limit = 3) {
27526
+ const q2 = terms(question);
27527
+ if (!q2.size) return [];
27528
+ return practices.map((p3) => {
27529
+ const t = practiceTerms(p3);
27530
+ const hits = [...q2].filter((w2) => t.has(w2)).length;
27531
+ const local = p3.project ? p3.project.hash === projectHash ? 1.5 : 0.5 : 1;
27532
+ return { practice: p3, score: hits / q2.size * local };
27533
+ }).filter((a) => a.score > 0).sort((a, b3) => b3.score - a.score || b3.practice.sessions - a.practice.sessions).slice(0, limit);
27534
+ }
27535
+
27206
27536
  // src/commands/scan.ts
27207
27537
  import { totalmem as totalmem2 } from "node:os";
27208
27538
 
@@ -27304,8 +27634,8 @@ function parseFrontmatter(content) {
27304
27634
  const end = content.indexOf("\n---", 3);
27305
27635
  if (end < 0) return void 0;
27306
27636
  const out2 = {};
27307
- for (const line of content.slice(4, end).split("\n")) {
27308
- const m2 = /^([a-z][a-z0-9-]*):\s*(.*)$/i.exec(line);
27637
+ for (const line2 of content.slice(4, end).split("\n")) {
27638
+ const m2 = /^([a-z][a-z0-9-]*):\s*(.*)$/i.exec(line2);
27309
27639
  if (!m2) continue;
27310
27640
  let v2 = m2[2].trim();
27311
27641
  if (v2.startsWith('"')) {
@@ -27331,15 +27661,15 @@ function checkSkill(content, expectedName) {
27331
27661
  const description = fm?.description ?? "";
27332
27662
  if (!description) errors.push("frontmatter `description` is missing");
27333
27663
  if (description.length > 1024) errors.push("description is longer than 1024 characters");
27334
- for (const section of REQUIRED_SECTIONS) if (!content.includes(`
27335
- ${section}
27336
- `)) errors.push(`missing section "${section}"`);
27337
- const steps = (content.split("## Workflow")[1]?.split("\n## ")[0] ?? "").split("\n").filter((l2) => /^\d+\. /.test(l2)).length;
27338
- if (steps < 3) errors.push(`workflow has ${steps} steps; at least 3 expected`);
27664
+ for (const section2 of REQUIRED_SECTIONS) if (!content.includes(`
27665
+ ${section2}
27666
+ `)) errors.push(`missing section "${section2}"`);
27667
+ const steps2 = (content.split("## Workflow")[1]?.split("\n## ")[0] ?? "").split("\n").filter((l2) => /^\d+\. /.test(l2)).length;
27668
+ if (steps2 < 3) errors.push(`workflow has ${steps2} steps; at least 3 expected`);
27339
27669
  if (findLeaks(content).length) errors.push("contains sensitive-looking content (secret, email, or home path)");
27340
27670
  if (/(^|[\s`'"(])(\/Users\/|\/home\/|[A-Z]:\\Users\\)/m.test(content)) errors.push("contains a local absolute path");
27341
27671
  if (!/generator: reflex/.test(content)) warnings.push("no Reflex provenance metadata (hand-written or edited skill)");
27342
- return { ok: errors.length === 0, errors, warnings, name, steps, lines };
27672
+ return { ok: errors.length === 0, errors, warnings, name, steps: steps2, lines };
27343
27673
  }
27344
27674
 
27345
27675
  // ../../packages/skills/src/diff.ts
@@ -27579,8 +27909,9 @@ function runClaudeInSandbox(sandbox, skillName2, timeoutMs = 6 * 60 * 1e3) {
27579
27909
  "--allowedTools",
27580
27910
  ...ALLOWED_TOOLS
27581
27911
  ];
27912
+ const launch = agentLaunch("claude", args);
27582
27913
  return new Promise((resolve5) => {
27583
- const child = spawn("claude", args, { cwd: sandbox.dir, stdio: ["ignore", "pipe", "ignore"] });
27914
+ const child = spawn(launch.command, launch.args, { cwd: sandbox.dir, stdio: ["ignore", "pipe", "ignore"], windowsVerbatimArguments: launch.windowsVerbatimArguments });
27584
27915
  let buffer = "";
27585
27916
  let timedOut = false;
27586
27917
  const run2 = { exitCode: null, skillUsed: false, commands: [], editedFiles: [], testsPass: false, timedOut: false };
@@ -27593,19 +27924,19 @@ function runClaudeInSandbox(sandbox, skillName2, timeoutMs = 6 * 60 * 1e3) {
27593
27924
  const base = bases.find((b3) => p3.startsWith(b3));
27594
27925
  return base ? p3.slice(base.length) : displayPath(p3);
27595
27926
  };
27596
- const handle = (line) => {
27927
+ const handle = (line2) => {
27597
27928
  let msg;
27598
27929
  try {
27599
- msg = JSON.parse(line);
27930
+ msg = JSON.parse(line2);
27600
27931
  } catch {
27601
27932
  return;
27602
27933
  }
27603
- if (msg.type === "result" && typeof msg.result === "string") run2.finalMessage = redact(msg.result.slice(0, 2e3));
27934
+ if (msg.type === "result" && typeof msg.result === "string") run2.finalMessage = redactTruncated(msg.result, 2e3);
27604
27935
  if (msg.type !== "assistant" || !Array.isArray(msg.message?.content)) return;
27605
27936
  for (const block of msg.message.content) {
27606
27937
  if (block.type !== "tool_use") continue;
27607
27938
  if (block.name === "Skill" && String(block.input?.skill ?? "").replace(/^.*:/, "") === skillName2) run2.skillUsed = true;
27608
- if (block.name === "Bash" && typeof block.input?.command === "string") run2.commands.push(redact(block.input.command.slice(0, 200)));
27939
+ if (block.name === "Bash" && typeof block.input?.command === "string") run2.commands.push(redactTruncated(block.input.command, 200));
27609
27940
  if ((block.name === "Edit" || block.name === "Write") && typeof block.input?.file_path === "string")
27610
27941
  run2.editedFiles.push(sandboxRelative(block.input.file_path));
27611
27942
  }
@@ -27687,15 +28018,16 @@ function cleanMemoryText(text) {
27687
28018
  if (!t || redactions > 0 || findLeaks(t).length) return void 0;
27688
28019
  return t;
27689
28020
  }
27690
- function renderMemoryBlock(rules) {
28021
+ function renderMemoryBlock(rules2) {
27691
28022
  const lines = [
27692
28023
  MEMORY_START,
27693
28024
  "## Remembered by Reflex",
27694
28025
  "",
27695
28026
  "Corrections the developer gave coding agents in more than one past session. Follow them unless the current task says otherwise.",
27696
28027
  "Managed by `reflex memory`: edits inside this block are replaced on the next scan.",
28028
+ 'To see how work is done in the current repository (commands that work, rules the developer gave), run `reflex handbook --json`, or `reflex handbook ask "<question>" --json`. Both are read-only.',
27697
28029
  "",
27698
- ...rules.map((r2) => `- ${r2.text}${r2.sessions ? ` (${r2.sessions} sessions)` : ""}`),
28030
+ ...rules2.map((r2) => `- ${r2.text}${r2.sessions ? ` (${r2.sessions} sessions)` : ""}`),
27699
28031
  MEMORY_END
27700
28032
  ];
27701
28033
  return lines.join("\n");
@@ -27774,19 +28106,19 @@ function learnedSection(review, opts = {}) {
27774
28106
  for (const c2 of constraints) lines.push(`- ${c2.text} (${c2.sessions} sessions)`);
27775
28107
  }
27776
28108
  lines.push(LEARNED_END);
27777
- const section = redact(lines.join("\n"));
27778
- if (findLeaks(section).length) throw new Error("The proposed section still contains sensitive-looking content; refusing to propose it.");
27779
- return section;
28109
+ const section2 = redact(lines.join("\n"));
28110
+ if (findLeaks(section2).length) throw new Error("The proposed section still contains sensitive-looking content; refusing to propose it.");
28111
+ return section2;
27780
28112
  }
27781
- function applyLearned(content, section) {
28113
+ function applyLearned(content, section2) {
27782
28114
  const starts = content.split(LEARNED_START).length - 1;
27783
28115
  const ends = content.split(LEARNED_END).length - 1;
27784
28116
  if (starts > 1 || ends > 1 || starts !== ends || starts && content.indexOf(LEARNED_END) < content.indexOf(LEARNED_START))
27785
28117
  throw new Error(`The skill's "Learned from your sessions" markers are incomplete or repeated. Fix or remove ${LEARNED_START} and ${LEARNED_END}, then run reflex improve again.`);
27786
28118
  const start = content.indexOf(LEARNED_START);
27787
28119
  const end = start >= 0 ? content.indexOf(LEARNED_END, start) : -1;
27788
- if (start >= 0 && end >= 0) return content.slice(0, start) + section + content.slice(end + LEARNED_END.length);
27789
- return content.replace(/\n*$/, "\n\n") + section + "\n";
28120
+ if (start >= 0 && end >= 0) return content.slice(0, start) + section2 + content.slice(end + LEARNED_END.length);
28121
+ return content.replace(/\n*$/, "\n\n") + section2 + "\n";
27790
28122
  }
27791
28123
  function withoutLearned(content) {
27792
28124
  const start = content.indexOf(LEARNED_START);
@@ -27809,6 +28141,7 @@ async function applyToOwnSkill(path, readHash, next, backupDir, name, now = /* @
27809
28141
  if (sha256(current) !== readHash) throw new Error("The skill changed since Reflex read it; run `reflex improve` again.");
27810
28142
  const stat4 = await lstat6(path);
27811
28143
  if (!stat4.isFile()) throw new Error("Not a regular file.");
28144
+ if ((stat4.mode & 146) === 0) throw new Error("You can't write to this skill file, so Reflex won't change it.");
27812
28145
  await access(path, constants3.W_OK).catch(() => {
27813
28146
  throw new Error("You can't write to this skill file, so Reflex won't change it.");
27814
28147
  });
@@ -27876,19 +28209,20 @@ function runClaudeBench(dir, task, model2, tools, timeoutMs) {
27876
28209
  "--allowedTools",
27877
28210
  ...tools
27878
28211
  ];
28212
+ const launch = agentLaunch("claude", args);
27879
28213
  const started = Date.now();
27880
28214
  return new Promise((resolve5) => {
27881
- const child = spawn2("claude", args, { cwd: dir, stdio: ["ignore", "pipe", "ignore"] });
28215
+ const child = spawn2(launch.command, launch.args, { cwd: dir, stdio: ["ignore", "pipe", "ignore"], windowsVerbatimArguments: launch.windowsVerbatimArguments });
27882
28216
  const run2 = { exitCode: null, timedOut: false, durationMs: 0 };
27883
28217
  let buffer = "";
27884
28218
  const timer = setTimeout(() => {
27885
28219
  run2.timedOut = true;
27886
28220
  child.kill("SIGTERM");
27887
28221
  }, timeoutMs);
27888
- const handle = (line) => {
28222
+ const handle = (line2) => {
27889
28223
  let msg;
27890
28224
  try {
27891
- msg = JSON.parse(line);
28225
+ msg = JSON.parse(line2);
27892
28226
  } catch {
27893
28227
  return;
27894
28228
  }
@@ -28067,6 +28401,7 @@ function parseJson(raw, shape, what) {
28067
28401
  if (!result.success) throw new Error(`Reflex database has a malformed ${what}. Run \`reflex scan\` again.`);
28068
28402
  return result.data;
28069
28403
  }
28404
+ var BUSY_TIMEOUT_MS = 1e4;
28070
28405
  var Store = class {
28071
28406
  db;
28072
28407
  constructor(file2 = paths.db()) {
@@ -28075,6 +28410,8 @@ var Store = class {
28075
28410
  mkdirSync(dir, { recursive: true, mode: 448 });
28076
28411
  this.db = new DatabaseSync2(file2);
28077
28412
  chmodSync(file2, 384);
28413
+ this.db.exec(`PRAGMA busy_timeout = ${BUSY_TIMEOUT_MS}`);
28414
+ this.db.exec("PRAGMA journal_mode = WAL");
28078
28415
  const version2 = Number(this.db.prepare("PRAGMA user_version").get().user_version);
28079
28416
  if (version2 < 4) this.db.exec("DROP TABLE IF EXISTS sessions");
28080
28417
  this.db.exec(SCHEMA);
@@ -28089,7 +28426,7 @@ var Store = class {
28089
28426
  }
28090
28427
  /** Record a scan and make the given cached traces its working set (what suggest, stats and the TUI see). */
28091
28428
  saveScan(scan2, traceRows) {
28092
- this.db.exec("BEGIN");
28429
+ this.db.exec("BEGIN IMMEDIATE");
28093
28430
  try {
28094
28431
  const res = this.db.prepare(
28095
28432
  "INSERT INTO scans (started_at, days, mode, sources_json, files, sessions, partial, unreadable, skipped_records) VALUES (?,?,?,?,?,?,?,?,?)"
@@ -28129,7 +28466,7 @@ var Store = class {
28129
28466
  }
28130
28467
  /** Replace what is cached for one file (its identity and its traces) atomically. */
28131
28468
  saveFile(file2, traces) {
28132
- this.db.exec("BEGIN");
28469
+ this.db.exec("BEGIN IMMEDIATE");
28133
28470
  try {
28134
28471
  this.db.prepare("DELETE FROM traces WHERE path = ?").run(file2.path);
28135
28472
  this.db.prepare(
@@ -28160,7 +28497,7 @@ var Store = class {
28160
28497
  }
28161
28498
  /** Rewrite a kept trace in place (re-redaction after the rules or the user's identity changed). */
28162
28499
  updateKeptTraces(path, traces, keys) {
28163
- this.db.exec("BEGIN");
28500
+ this.db.exec("BEGIN IMMEDIATE");
28164
28501
  try {
28165
28502
  const update = this.db.prepare("UPDATE traces SET trace_json = ? WHERE row_id = ?");
28166
28503
  for (const t of traces) update.run(JSON.stringify(t.trace), t.row);
@@ -28205,7 +28542,7 @@ var Store = class {
28205
28542
  /** Store the current suggestions, keeping any earlier approve/reject decision for the same slug. */
28206
28543
  saveSuggestions(scanId, suggestions) {
28207
28544
  const now = (/* @__PURE__ */ new Date()).toISOString();
28208
- this.db.exec("BEGIN");
28545
+ this.db.exec("BEGIN IMMEDIATE");
28209
28546
  try {
28210
28547
  this.db.prepare("UPDATE suggestions SET rank = NULL").run();
28211
28548
  const upsert = this.db.prepare(
@@ -28301,7 +28638,7 @@ var Store = class {
28301
28638
  }
28302
28639
  saveEmbeddings(model2, entries) {
28303
28640
  const put = this.db.prepare("INSERT OR REPLACE INTO embeddings (key, model, vector) VALUES (?,?,COALESCE(?, zeroblob(0)))");
28304
- this.db.exec("BEGIN");
28641
+ this.db.exec("BEGIN IMMEDIATE");
28305
28642
  try {
28306
28643
  for (const [key3, v2] of entries) put.run(key3, model2, new Uint8Array(v2.buffer, v2.byteOffset, v2.byteLength));
28307
28644
  this.db.exec("COMMIT");
@@ -28315,11 +28652,11 @@ var Store = class {
28315
28652
  this.db.prepare("DELETE FROM embeddings WHERE key NOT IN (SELECT value FROM json_each(?))").run(JSON.stringify(keep));
28316
28653
  }
28317
28654
  /** Replace the mined memory with the latest result. User decisions (forgotten, added) are kept. */
28318
- syncMinedMemory(rules) {
28655
+ syncMinedMemory(rules2) {
28319
28656
  const now = (/* @__PURE__ */ new Date()).toISOString();
28320
- this.db.exec("BEGIN");
28657
+ this.db.exec("BEGIN IMMEDIATE");
28321
28658
  try {
28322
- const keep = new Set(rules.map((r2) => r2.text));
28659
+ const keep = new Set(rules2.map((r2) => r2.text));
28323
28660
  for (const row of this.db.prepare("SELECT text FROM memory_entries WHERE origin = 'mined' AND status = 'active'").all()) {
28324
28661
  if (!keep.has(row.text)) this.db.prepare("DELETE FROM memory_entries WHERE text = ?").run(row.text);
28325
28662
  }
@@ -28327,7 +28664,7 @@ var Store = class {
28327
28664
  `INSERT INTO memory_entries (text, origin, status, sessions, updated_at) VALUES (?, 'mined', 'active', ?, ?)
28328
28665
  ON CONFLICT(text) DO UPDATE SET sessions = excluded.sessions, updated_at = excluded.updated_at`
28329
28666
  );
28330
- for (const r2 of rules) upsert.run(r2.text, r2.sessions, now);
28667
+ for (const r2 of rules2) upsert.run(r2.text, r2.sessions, now);
28331
28668
  this.db.exec("COMMIT");
28332
28669
  } catch (err) {
28333
28670
  this.db.exec("ROLLBACK");
@@ -28684,8 +29021,8 @@ var COMFORTABLE = { memoryGB: 8, cores: 4 };
28684
29021
  function machineIsSmall(totalBytes = totalmem(), cores = availableParallelism()) {
28685
29022
  return totalBytes / 1e9 < COMFORTABLE.memoryGB - 0.5 || cores < COMFORTABLE.cores;
28686
29023
  }
28687
- function embeddingSeconds(model2, sessions2, threads = embeddingThreads()) {
28688
- const speedup = 1 + (threads - 1) * 0.83;
29024
+ function embeddingSeconds(model2, sessions2, threads2 = embeddingThreads()) {
29025
+ const speedup = 1 + (threads2 - 1) * 0.83;
28689
29026
  return sessions2 * model2.secondsPerSession / speedup;
28690
29027
  }
28691
29028
 
@@ -28705,8 +29042,8 @@ async function tokenizerFor(dir, model2) {
28705
29042
  return (text) => tokenizer2.encode(text, model2.maxTokens);
28706
29043
  }
28707
29044
  const { Tokenizer } = await import("./tokenizers-CLBWC4RJ.js");
28708
- const [json2, config2] = await Promise.all([readVerified(dir, "tokenizer.json", model2), readVerified(dir, "tokenizer_config.json", model2)]);
28709
- const tokenizer = new Tokenizer(JSON.parse(json2.toString("utf8")), JSON.parse(config2.toString("utf8")));
29045
+ const [json3, config2] = await Promise.all([readVerified(dir, "tokenizer.json", model2), readVerified(dir, "tokenizer_config.json", model2)]);
29046
+ const tokenizer = new Tokenizer(JSON.parse(json3.toString("utf8")), JSON.parse(config2.toString("utf8")));
28710
29047
  return (text) => {
28711
29048
  const ids = tokenizer.encode(text).ids;
28712
29049
  return ids.length > model2.maxTokens ? [...ids.slice(0, model2.maxTokens - 1), ids[ids.length - 1]] : ids;
@@ -30939,7 +31276,8 @@ async function validate2(name, opts) {
30939
31276
  out(c.dim(` Or let Reflex run it: reflex validate ${name} --run`));
30940
31277
  return;
30941
31278
  }
30942
- if (spawnSync3("claude", ["--version"], { stdio: "ignore" }).status !== 0) {
31279
+ const claude = agentLaunch("claude", ["--version"]);
31280
+ if (spawnSync3(claude.command, claude.args, { stdio: "ignore", windowsVerbatimArguments: claude.windowsVerbatimArguments }).status !== 0) {
30943
31281
  fail("The `claude` CLI was not found on PATH.");
30944
31282
  return;
30945
31283
  }
@@ -30960,7 +31298,7 @@ async function validate2(name, opts) {
30960
31298
  if (run2.finalMessage) {
30961
31299
  out();
30962
31300
  out(c.dim(" Final message:"));
30963
- for (const line of run2.finalMessage.split("\n").slice(0, 14)) out(c.dim(` ${line}`));
31301
+ for (const line2 of run2.finalMessage.split("\n").slice(0, 14)) out(c.dim(` ${line2}`));
30964
31302
  }
30965
31303
  out();
30966
31304
  if (run2.skillUsed && run2.testsPass) ok(`${name} worked on a new task.`);
@@ -30971,9 +31309,9 @@ async function validate2(name, opts) {
30971
31309
  var sourceSummary = (s) => Object.entries(s.sources).map(([k3, n]) => `${SOURCE_LABELS[k3] ?? k3} ${n}`).join(", ");
30972
31310
  function costLine(s) {
30973
31311
  const cost = s.cost;
30974
- const line = describeCost(cost);
30975
- if (cost.runsWithTokens) return line;
30976
- return s.sources.cursor ? `${line} ${c.dim("(Cursor doesn't record tokens)")}` : line;
31312
+ const line2 = describeCost(cost);
31313
+ if (cost.runsWithTokens) return line2;
31314
+ return s.sources.cursor ? `${line2} ${c.dim("(Cursor doesn't record tokens)")}` : line2;
30977
31315
  }
30978
31316
  function renderSuggestion(entry) {
30979
31317
  const s = entry.data;
@@ -31228,7 +31566,8 @@ async function doctor() {
31228
31566
  out();
31229
31567
  out("Agent CLIs (for fresh-task validation)");
31230
31568
  for (const bin of ["claude", "codex"]) {
31231
- const found = spawnSync4(bin, ["--version"], { stdio: "ignore" }).status === 0;
31569
+ const launch = agentLaunch(bin, ["--version"]);
31570
+ const found = spawnSync4(launch.command, launch.args, { stdio: "ignore", windowsVerbatimArguments: launch.windowsVerbatimArguments }).status === 0;
31232
31571
  out(` ${found ? c.green("\u2714") : c.dim("\xB7")} ${bin}`);
31233
31572
  }
31234
31573
  out();
@@ -31327,7 +31666,7 @@ async function reset(opts) {
31327
31666
  out(c.dim("Skills you installed into Claude Code, Codex or Cursor are not touched; Reflex's agent-memory block is removed. The embedding model is kept (`reflex model remove`)."));
31328
31667
  if (!await confirm("Delete Reflex data?", opts)) return;
31329
31668
  for (const w2 of await removeMemory()) if (w2.changed) ok(`Removed Reflex's memory block from ${displayPath(w2.path)}`);
31330
- for (const child of ["reflex.db", "reflex.db-journal", "skills", "validation"]) {
31669
+ for (const child of ["reflex.db", "reflex.db-journal", "reflex.db-wal", "reflex.db-shm", "skills", "validation"]) {
31331
31670
  await rm3(join19(home, child), { recursive: true, force: true });
31332
31671
  }
31333
31672
  ok("Reset.");
@@ -31366,9 +31705,9 @@ async function memoryStatus() {
31366
31705
  return;
31367
31706
  }
31368
31707
  entries.forEach((e2, i) => {
31369
- const meta3 = e2.origin === "added" ? "added by you" : plural(e2.sessions, "session");
31370
- const line = ` ${String(i + 1).padStart(2)}. ${e2.text} ${c.dim(`(${meta3})`)}`;
31371
- out(e2.status === "forgotten" ? c.dim(`${line} forgotten`) : line);
31708
+ const meta4 = e2.origin === "added" ? "added by you" : plural(e2.sessions, "session");
31709
+ const line2 = ` ${String(i + 1).padStart(2)}. ${e2.text} ${c.dim(`(${meta4})`)}`;
31710
+ out(e2.status === "forgotten" ? c.dim(`${line2} forgotten`) : line2);
31372
31711
  });
31373
31712
  out();
31374
31713
  out(c.dim('reflex memory forget <n> \xB7 remember <n> \xB7 add "<text>" \xB7 on \xB7 off'));
@@ -31461,12 +31800,12 @@ async function storedSessions() {
31461
31800
  }
31462
31801
  }
31463
31802
  async function machineCheck(model2) {
31464
- const threads = embeddingThreads();
31803
+ const threads2 = embeddingThreads();
31465
31804
  const memGB = totalmem3() / 1e9;
31466
31805
  const sessions2 = await storedSessions();
31467
- const estimate = sessions2 ? `about ${duration3(embeddingSeconds(model2, sessions2, threads))} for your ${sessions2} stored sessions` : `about ${duration3(embeddingSeconds(model2, 100, threads))} per 100 sessions`;
31806
+ const estimate = sessions2 ? `about ${duration3(embeddingSeconds(model2, sessions2, threads2))} for your ${sessions2} stored sessions` : `about ${duration3(embeddingSeconds(model2, 100, threads2))} per 100 sessions`;
31468
31807
  rows([
31469
- ["This machine", `${memGB.toFixed(0)} GB memory, ${availableParallelism2()} cores (${threads} used for embedding)`],
31808
+ ["This machine", `${memGB.toFixed(0)} GB memory, ${availableParallelism2()} cores (${threads2} used for embedding)`],
31470
31809
  ["First scan", `${estimate}; later scans only embed new sessions (older CPUs can take up to 3x longer)`]
31471
31810
  ]);
31472
31811
  out();
@@ -31527,6 +31866,7 @@ async function modelFetch(opts) {
31527
31866
  const total = modelBytes(model2);
31528
31867
  let done = 0;
31529
31868
  let last = 0;
31869
+ const closeNetwork = allowHosts(MODEL_HOSTS);
31530
31870
  try {
31531
31871
  await fetchModel(
31532
31872
  paths.models(),
@@ -31545,6 +31885,8 @@ async function modelFetch(opts) {
31545
31885
  } catch (err) {
31546
31886
  spin.stop("Download failed");
31547
31887
  throw err;
31888
+ } finally {
31889
+ closeNetwork();
31548
31890
  }
31549
31891
  await setActiveModel(paths.models(), model2);
31550
31892
  spin.stop("Downloaded and verified");
@@ -31724,14 +32066,14 @@ async function improve(name, opts) {
31724
32066
  const behavior = opts.behavior === true;
31725
32067
  out();
31726
32068
  renderReview(review, behavior);
31727
- const section = learnedSection(review, { behavior });
31728
- if (!section) {
32069
+ const section2 = learnedSection(review, { behavior });
32070
+ if (!section2) {
31729
32071
  ok(
31730
32072
  behavior || !review.missing.length && !review.constraints.length ? `Nothing to add: ${name} already covers what these sessions did.` : `Nothing to add that keeps ${name} doing exactly what it does. --behavior proposes the steps and corrections above.`
31731
32073
  );
31732
32074
  return;
31733
32075
  }
31734
- const next = applyLearned(content, section);
32076
+ const next = applyLearned(content, section2);
31735
32077
  const proposalDir = assertInside(paths.home(), join20(paths.home(), "proposals", name));
31736
32078
  await ensureDir(paths.home(), 448);
31737
32079
  await ensureDir(join20(paths.home(), "proposals"), 448);
@@ -31790,6 +32132,127 @@ async function improve(name, opts) {
31790
32132
  }
31791
32133
  }
31792
32134
 
32135
+ // src/commands/handbook.ts
32136
+ import { dirname as dirname8 } from "node:path";
32137
+ var TOOL = { "claude-code": "Claude Code", codex: "Codex", cursor: "Cursor" };
32138
+ function load() {
32139
+ const store = new Store();
32140
+ try {
32141
+ if (!store.latestScan()) throw new Error("No scan yet. Run `reflex scan --days 30` first.");
32142
+ const forgotten = new Set(store.memoryEntries().filter((e2) => e2.status === "forgotten").map((e2) => e2.text));
32143
+ return buildHandbook(store.traces(), { forgotten });
32144
+ } finally {
32145
+ store.close();
32146
+ }
32147
+ }
32148
+ function scope(practices, opts) {
32149
+ const known = new Map(practices.filter((p3) => p3.project).map((p3) => [p3.project.hash, p3.project]));
32150
+ if (opts.project) {
32151
+ const hit = [...known.values()].find((p3) => p3.name === opts.project || p3.hash === opts.project);
32152
+ if (!hit) throw new Error(`No practices for a repository named "${opts.project}". \`reflex handbook --all\` lists them.`);
32153
+ return hit;
32154
+ }
32155
+ for (let dir = process.cwd(); ; dir = dirname8(dir)) {
32156
+ const hit = known.get(shortHash(dir));
32157
+ if (hit) return hit;
32158
+ if (dirname8(dir) === dir) return {};
32159
+ }
32160
+ }
32161
+ function meta3(p3) {
32162
+ return `${plural(p3.sessions, "session")}${p3.last ? ` \xB7 last ${shortDate(p3.last)}` : ""} \xB7 ${p3.id}`;
32163
+ }
32164
+ function line(p3) {
32165
+ return ` ${p3.text}${p3.when ? c.cyan(` (${p3.when})`) : ""} ${c.dim(meta3(p3))}`;
32166
+ }
32167
+ function section(name, items) {
32168
+ if (!items.length) return;
32169
+ out(c.bold(` ${name}`));
32170
+ for (const p3 of items) out(line(p3));
32171
+ out();
32172
+ }
32173
+ var json2 = (value) => out(JSON.stringify(value, null, 2));
32174
+ async function handbook(opts) {
32175
+ const all = load();
32176
+ if (opts.all) {
32177
+ if (opts.json) return json2({ project: null, practices: all });
32178
+ title(`Handbook \xB7 every repository \xB7 ${plural(all.length, "practice")}`);
32179
+ const groups = /* @__PURE__ */ new Map();
32180
+ for (const p3 of all) groups.set(p3.project?.name ?? "Across repositories", [...groups.get(p3.project?.name ?? "Across repositories") ?? [], p3]);
32181
+ for (const [name, items] of groups) section(name, items);
32182
+ return;
32183
+ }
32184
+ const where = scope(all, opts);
32185
+ const practices = practicesFor(all, where.hash);
32186
+ if (opts.json) return json2({ project: where.hash ? where : null, practices });
32187
+ title(`Handbook \xB7 ${where.name ?? "no repository matched this folder"}`);
32188
+ if (!practices.length) {
32189
+ out("Nothing learned yet. Practices come from commands that worked and corrections you repeated, in at least 2 independent sessions.");
32190
+ return;
32191
+ }
32192
+ const own2 = practices.filter((p3) => p3.project);
32193
+ section("Commands that work here", own2.filter((p3) => p3.kind === "command"));
32194
+ section("Rules you gave agents here", own2.filter((p3) => p3.kind === "rule"));
32195
+ section("Rules across your repositories", practices.filter((p3) => !p3.project));
32196
+ out(c.dim(`reflex handbook show <id> \xB7 ask "<question>" \xB7 export \xB7 --json${where.hash ? "" : " \xB7 --project <name> \xB7 --all"}`));
32197
+ }
32198
+ async function handbookShow(id, opts) {
32199
+ const p3 = load().find((x2) => x2.id === id);
32200
+ if (!p3) throw new Error(`No practice ${id}. \`reflex handbook\` lists them with their ids.`);
32201
+ if (opts.json) return json2(p3);
32202
+ title(p3.text);
32203
+ if (p3.when) out(` Applies ${p3.when}.`);
32204
+ out(` ${p3.project?.name ? `In ${p3.project.name}` : "Across your repositories"} \xB7 ${plural(p3.sessions, "independent session")}`);
32205
+ out();
32206
+ out(c.bold(` Sessions behind it${p3.sessions > p3.sources.length ? ` (newest ${p3.sources.length})` : ""}`));
32207
+ for (const s of p3.sources) out(` ${shortDate(s.date)} ${(TOOL[s.tool] ?? s.tool).padEnd(11)} ${c.dim(s.request || "(no request text)")}`);
32208
+ }
32209
+ async function handbookAsk(words2, opts) {
32210
+ const question = words2.join(" ").trim();
32211
+ if (!question) throw new Error('Ask a question: reflex handbook ask "how do we run tests here?"');
32212
+ const all = load();
32213
+ const where = scope(all, opts);
32214
+ const answers = askHandbook(practicesFor(all, where.hash), question, where.hash);
32215
+ if (opts.json) return json2({ question, project: where.hash ? where : null, answers: answers.map((a) => ({ score: Number(a.score.toFixed(3)), ...a.practice })) });
32216
+ out();
32217
+ if (!answers.length) {
32218
+ out(`Nothing in the handbook${where.name ? ` for ${where.name}` : ""} answers that. Reflex only knows what past sessions showed.`);
32219
+ return;
32220
+ }
32221
+ for (const { practice: p3 } of answers) {
32222
+ out(`${c.green("\u203A")} ${p3.text}${p3.when ? c.cyan(` (${p3.when})`) : ""}`);
32223
+ out(c.dim(` ${p3.project?.name ? `in ${p3.project.name}` : "across your repositories"} \xB7 ${meta3(p3)} \xB7 reflex handbook show ${p3.id}`));
32224
+ }
32225
+ }
32226
+ async function handbookExport(opts) {
32227
+ const all = load();
32228
+ const where = opts.all ? {} : scope(all, opts);
32229
+ const practices = opts.all ? all : practicesFor(all, where.hash);
32230
+ const name = opts.all ? "all repositories" : where.name ?? "this folder";
32231
+ const entry = (p3) => `- ${p3.text}${p3.when ? ` *(${p3.when})*` : ""} \xB7 ${plural(p3.sessions, "session")}${p3.last ? `, last ${shortDate(p3.last)}` : ""}`;
32232
+ const lines = [
32233
+ `# Handbook: ${name}`,
32234
+ "",
32235
+ `Learned by Reflex from past coding-agent sessions, ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}. Each item held in at least 2 independent sessions; the count says how many.`,
32236
+ ""
32237
+ ];
32238
+ const groups = [
32239
+ ["Commands that work", practices.filter((p3) => p3.kind === "command")],
32240
+ ["Rules", practices.filter((p3) => p3.kind === "rule" && p3.project)],
32241
+ ["Rules across repositories", practices.filter((p3) => p3.kind === "rule" && !p3.project)]
32242
+ ];
32243
+ for (const [heading, items] of groups) {
32244
+ if (!items.length) continue;
32245
+ lines.push(`## ${heading}`, "");
32246
+ if (opts.all && heading !== "Rules across repositories") {
32247
+ const byRepo = /* @__PURE__ */ new Map();
32248
+ for (const p3 of items) byRepo.set(p3.project?.name ?? "unnamed", [...byRepo.get(p3.project?.name ?? "unnamed") ?? [], p3]);
32249
+ for (const [repo, ps] of byRepo) lines.push(`### ${repo}`, "", ...ps.map(entry), "");
32250
+ } else lines.push(...items.map(entry), "");
32251
+ }
32252
+ if (!practices.length) lines.push("Nothing learned yet.", "");
32253
+ out(lines.join("\n").trimEnd());
32254
+ }
32255
+
31793
32256
  // src/commands/route.ts
31794
32257
  import { spawnSync as spawnSync5 } from "node:child_process";
31795
32258
  import { randomInt, randomUUID as randomUUID2 } from "node:crypto";
@@ -31903,7 +32366,8 @@ async function runRouted(words2, opts) {
31903
32366
  if (!run2) return;
31904
32367
  const model2 = run2.model ? ["--model", run2.model] : [];
31905
32368
  const args = run2.source === "claude-code" ? [...model2, "--session-id", run2.nativeId, request] : [...model2, request];
31906
- const res = spawnSync5(CLI[run2.source], args, { stdio: "inherit" });
32369
+ const launch = agentLaunch(CLI[run2.source], args);
32370
+ const res = spawnSync5(launch.command, launch.args, { stdio: "inherit", windowsVerbatimArguments: launch.windowsVerbatimArguments });
31907
32371
  if (res.error) throw new Error(`Could not start ${CLI[run2.source]}: ${res.error.message}`);
31908
32372
  process.exitCode = res.status ?? 0;
31909
32373
  if (opts.ask !== false && interactive()) await askOutcome(runId);
@@ -32207,8 +32671,8 @@ function hcat(blocks, gap) {
32207
32671
  for (let i = 0; i < h2; i++) {
32208
32672
  let l2 = [];
32209
32673
  blocks.forEach((b3, j2) => {
32210
- const line = b3.lines[i];
32211
- l2 = l2.concat(line ? fit(line, b3.w) : [S2(" ".repeat(b3.w))]);
32674
+ const line2 = b3.lines[i];
32675
+ l2 = l2.concat(line2 ? fit(line2, b3.w) : [S2(" ".repeat(b3.w))]);
32212
32676
  if (j2 < blocks.length - 1) l2.push(S2(" ".repeat(gap)));
32213
32677
  });
32214
32678
  out2.push(l2);
@@ -32381,18 +32845,18 @@ function hbars(title2, items, w2, o2 = {}) {
32381
32845
  function mdLines(src, w2) {
32382
32846
  const out2 = [];
32383
32847
  let fm = 0;
32384
- src.forEach((line) => {
32848
+ src.forEach((line2) => {
32385
32849
  let c2 = "fg";
32386
32850
  let b3 = null;
32387
- if (line === "---") {
32851
+ if (line2 === "---") {
32388
32852
  fm++;
32389
32853
  c2 = "dim";
32390
32854
  } else if (fm === 1) c2 = "dim";
32391
- else if (line.startsWith("#")) {
32855
+ else if (line2.startsWith("#")) {
32392
32856
  c2 = "hi";
32393
32857
  b3 = BOLD;
32394
32858
  }
32395
- wrap(line, w2).forEach((t) => out2.push([S2(t, c2, b3)]));
32859
+ wrap(line2, w2).forEach((t) => out2.push([S2(t, c2, b3)]));
32396
32860
  });
32397
32861
  return out2;
32398
32862
  }
@@ -34145,7 +34609,12 @@ function runTui(opts) {
34145
34609
  const resume = async (c2) => {
34146
34610
  let error62;
34147
34611
  await term.suspend(() => {
34148
- error62 = spawnSync6(c2.cmd, c2.args, { stdio: "inherit", cwd: c2.cwd }).error;
34612
+ try {
34613
+ const launch = agentLaunch(c2.cmd, c2.args);
34614
+ error62 = spawnSync6(launch.command, launch.args, { stdio: "inherit", cwd: c2.cwd, windowsVerbatimArguments: launch.windowsVerbatimArguments }).error;
34615
+ } catch (e2) {
34616
+ error62 = e2 instanceof Error ? e2 : new Error(String(e2));
34617
+ }
34149
34618
  });
34150
34619
  term.invalidate();
34151
34620
  await reload();
@@ -34268,7 +34737,7 @@ async function readReflexCopy(name) {
34268
34737
  if (await isSymlink(paths.skills()) || await isSymlink(dir)) return void 0;
34269
34738
  return readCapped(join22(dir, "SKILL.md"));
34270
34739
  }
34271
- async function isFile2(path) {
34740
+ async function isFile3(path) {
34272
34741
  try {
34273
34742
  return (await lstat9(path)).isFile();
34274
34743
  } catch {
@@ -34292,7 +34761,7 @@ async function skillItems(store, scan2, targets, now) {
34292
34761
  const names = new Set(generated.map((k3) => k3.name));
34293
34762
  const installs = store.installations();
34294
34763
  const installed = async (name) => {
34295
- for (const r2 of installs) if (r2.skill === name && await isFile2(r2.path)) return true;
34764
+ for (const r2 of installs) if (r2.skill === name && await isFile3(r2.path)) return true;
34296
34765
  return false;
34297
34766
  };
34298
34767
  const path = (name) => claude ? toCells(`${displayPath(claude.skillsDir)}/${name}/SKILL.md`) : "";
@@ -34516,20 +34985,20 @@ function buildRouter(priced, rebuiltAt, windowDays2, autopilot = false) {
34516
34985
  }
34517
34986
 
34518
34987
  // ../../packages/tui/src/live/search.ts
34519
- import { closeSync, constants as constants5, existsSync as existsSync7, lstatSync as lstatSync2, openSync, readSync, readdirSync, statSync as statSync2 } from "node:fs";
34520
- import { basename as basename8, delimiter as delimiter3, join as join23 } from "node:path";
34988
+ import { closeSync, constants as constants5, existsSync as existsSync7, lstatSync as lstatSync2, openSync, readSync, readdirSync, statSync as statSync3 } from "node:fs";
34989
+ import { basename as basename8, join as join23 } from "node:path";
34521
34990
  var SESSION_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$/;
34522
34991
  var MAX_CWD_SCAN_BYTES = 256 * 1024;
34523
34992
  function buildSearch(priced) {
34524
34993
  const sessions2 = /* @__PURE__ */ new Map();
34525
34994
  const bySession = /* @__PURE__ */ new Map();
34526
- const meta3 = /* @__PURE__ */ new Map();
34995
+ const meta4 = /* @__PURE__ */ new Map();
34527
34996
  const all = [];
34528
34997
  for (const { t, at, tool, cost } of priced) {
34529
34998
  const nativeId = t.sessionId.slice(t.source.length + 1);
34530
34999
  const key3 = sessions2.has(nativeId.slice(0, 8)) ? nativeId : nativeId.slice(0, 8);
34531
35000
  sessions2.set(key3, { source: t.source, nativeId });
34532
- meta3.set(key3, { usd: cost?.usd, turnCount: t.requests });
35001
+ meta4.set(key3, { usd: cost?.usd, turnCount: t.requests });
34533
35002
  const base = { date: at ? dayLabel(new Date(at)) : "\u2014", tool, project: toCells(t.projectName ?? "\u2014"), session: toCells(key3), at };
34534
35003
  const texts = [["you", t.excerpt], ...t.displaySteps.map((s) => ["ai", s])];
34535
35004
  const entries = [];
@@ -34548,7 +35017,7 @@ function buildSearch(priced) {
34548
35017
  return all.filter((e2) => (tool === "all" || e2.tool === tool) && (!needle || e2.lower.includes(needle)));
34549
35018
  },
34550
35019
  session(id) {
34551
- return { turns: bySession.get(id) ?? [], ...meta3.get(id) };
35020
+ return { turns: bySession.get(id) ?? [], ...meta4.get(id) };
34552
35021
  }
34553
35022
  };
34554
35023
  return { index, sessions: sessions2 };
@@ -34576,10 +35045,10 @@ function claudeCwd(nativeId) {
34576
35045
  } finally {
34577
35046
  closeSync(fd);
34578
35047
  }
34579
- for (const line of buf.subarray(0, n).toString("utf8").split("\n")) {
35048
+ for (const line2 of buf.subarray(0, n).toString("utf8").split("\n")) {
34580
35049
  try {
34581
- const cwd = JSON.parse(line).cwd;
34582
- if (typeof cwd === "string" && statSync2(cwd).isDirectory()) return cwd;
35050
+ const cwd = JSON.parse(line2).cwd;
35051
+ if (typeof cwd === "string" && statSync3(cwd).isDirectory()) return cwd;
34583
35052
  } catch {
34584
35053
  continue;
34585
35054
  }
@@ -34599,7 +35068,6 @@ function cursorWorkspace(nativeId) {
34599
35068
  const dir = dirs.find((d3) => existsSync7(join23(root, d3, "agent-transcripts", nativeId)));
34600
35069
  return dir ? decodeWorkspace(dir) : void 0;
34601
35070
  }
34602
- var onPath3 = (cmd) => (process.env.PATH ?? "").split(delimiter3).some((d3) => d3 && existsSync7(join23(d3, cmd)));
34603
35071
  function resumeCommand(ref) {
34604
35072
  if (!ref || !SESSION_ID.test(ref.nativeId)) return { ok: false, message: "this session cannot be resumed", tone: "dim" };
34605
35073
  const id = ref.nativeId;
@@ -34612,7 +35080,7 @@ function resumeCommand(ref) {
34612
35080
  const dir = cursorWorkspace(id);
34613
35081
  if (!dir) return { ok: false, message: "this Cursor chat has no workspace folder on this machine", tone: "dim" };
34614
35082
  const done = `opened ${toCells(basename8(dir))} in Cursor \xB7 the chat is in its agent history`;
34615
- if (onPath3("cursor")) return { cmd: "cursor", args: [dir], done };
35083
+ if (findOnPath("cursor")) return { cmd: "cursor", args: [dir], done };
34616
35084
  if (process.platform === "darwin") return { cmd: "open", args: ["-a", "Cursor", dir], done };
34617
35085
  return { ok: false, message: `open ${toCells(dir)} in Cursor; the chat is in its agent history`, tone: "dim" };
34618
35086
  }
@@ -34906,8 +35374,7 @@ async function tui() {
34906
35374
 
34907
35375
  // src/main.ts
34908
35376
  quietSqliteWarning();
34909
- var fetchingModel = process.argv[2] === "model" && process.argv[3] === "fetch";
34910
- if (!fetchingModel) installNetworkGuard();
35377
+ installNetworkGuard();
34911
35378
  process.stdout.on("error", (err) => {
34912
35379
  if (err.code === "EPIPE") process.exit(0);
34913
35380
  throw err;
@@ -34925,7 +35392,7 @@ function run(fn) {
34925
35392
  };
34926
35393
  }
34927
35394
  var program2 = new Command();
34928
- program2.name("reflex").description("Find workflows you keep re-teaching Claude Code, Codex and Cursor, and turn proven repeats into reusable skills. Everything runs locally.").version("0.5.0").allowExcessArguments().action(
35395
+ program2.name("reflex").description("Find workflows you keep re-teaching Claude Code, Codex and Cursor, and turn proven repeats into reusable skills. Everything runs locally.").version("0.5.1").allowExcessArguments().action(
34929
35396
  run(async () => {
34930
35397
  if (program2.args.length) program2.error(`error: unknown command '${program2.args[0]}'. See \`reflex --help\`.`);
34931
35398
  if (process.stdin.isTTY && process.stdout.isTTY) await tui();
@@ -34940,6 +35407,10 @@ program2.command("scan").description("read recent coding-agent history (asks fir
34940
35407
  );
34941
35408
  program2.command("sessions").description("list sessions from the last scan (redacted)").action(run(sessions));
34942
35409
  program2.command("agents").description("sessions that launched agents (Cursor), what kinds, and how much work the agents did").action(run(agents));
35410
+ var handbookCmd = program2.command("handbook").description("how work is done in this repository, learned from past sessions (read-only, safe for agents)").option("--project <name>", "a repository by name instead of the current folder").option("--all", "every repository").option("--json", "machine-readable output").action(run(async (o2) => handbook(o2)));
35411
+ handbookCmd.command("show <id>").description("one practice and the sessions behind it").option("--json", "machine-readable output").action(run(async (id, _o, cmd) => handbookShow(id, cmd.optsWithGlobals())));
35412
+ handbookCmd.command("ask <question...>").description("practices that answer a question, with their sources").option("--project <name>", "a repository by name instead of the current folder").option("--json", "machine-readable output").action(run(async (q2, _o, cmd) => handbookAsk(q2, cmd.optsWithGlobals())));
35413
+ handbookCmd.command("export").description("a Markdown handbook for a teammate or new hire (no request text)").option("--project <name>", "a repository by name instead of the current folder").option("--all", "every repository").action(run(async (_o, cmd) => handbookExport(cmd.optsWithGlobals())));
34943
35414
  program2.command("suggest").description("detect repeated workflows and review them").option("--all", "include rejected suggestions").option("--no-interactive", "print suggestions without the review prompt").action(run(suggest));
34944
35415
  program2.command("show <suggestion>").description("show a suggestion in detail (number or name)").action(run(show));
34945
35416
  program2.command("evidence <suggestion>").description("show the sessions behind a suggestion").action(run(evidence));