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/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/reflex.js +943 -472
- package/package.json +2 -1
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((
|
|
594
|
-
const commandList =
|
|
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((
|
|
746
|
-
const chunks =
|
|
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
|
|
3577
|
-
|
|
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
|
-
|
|
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(
|
|
4290
|
-
process.stdout.write(
|
|
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
|
|
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 = (
|
|
6477
|
-
const escapedDelim = escapeRegex(
|
|
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
|
|
7052
|
-
this.content.push(
|
|
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
|
|
17341
|
-
this._map.set(schema,
|
|
17342
|
-
if (
|
|
17343
|
-
this._idmap.set(
|
|
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
|
|
17354
|
-
if (
|
|
17355
|
-
this._idmap.delete(
|
|
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,
|
|
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(
|
|
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
|
|
20130
|
-
if (
|
|
20131
|
-
assignProps(result.schema,
|
|
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(
|
|
20320
|
-
const 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
|
|
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
|
|
20344
|
-
assignProps(
|
|
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
|
|
20427
|
-
const 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(
|
|
20523
|
+
existing.push(json3);
|
|
20433
20524
|
else
|
|
20434
|
-
carriers.set(allOf, [
|
|
20525
|
+
carriers.set(allOf, [json3]);
|
|
20435
20526
|
}
|
|
20436
20527
|
}
|
|
20437
20528
|
for (const allOf of ctx.intersections) {
|
|
20438
|
-
for (const
|
|
20439
|
-
foldIntersection(
|
|
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
|
|
20675
|
-
|
|
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
|
-
|
|
20769
|
+
json3.minLength = minimum;
|
|
20679
20770
|
if (typeof maximum === "number")
|
|
20680
|
-
|
|
20771
|
+
json3.maxLength = maximum;
|
|
20681
20772
|
if (format) {
|
|
20682
|
-
|
|
20683
|
-
if (
|
|
20684
|
-
delete
|
|
20773
|
+
json3.format = formatMap[format] ?? format;
|
|
20774
|
+
if (json3.format === "")
|
|
20775
|
+
delete json3.format;
|
|
20685
20776
|
if (format === "time" || laxFormat) {
|
|
20686
|
-
delete
|
|
20777
|
+
delete json3.format;
|
|
20687
20778
|
}
|
|
20688
20779
|
}
|
|
20689
20780
|
if (contentEncoding)
|
|
20690
|
-
|
|
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
|
-
|
|
20785
|
+
json3.pattern = patternList[0].source;
|
|
20695
20786
|
else if (patternList.length > 1) {
|
|
20696
|
-
|
|
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
|
|
20797
|
+
const json3 = _json;
|
|
20707
20798
|
const { minimum, maximum, multipleOf, exclusiveMaximum, exclusiveMinimum, isInt: isInt2 } = aggregateChecks(schema);
|
|
20708
|
-
|
|
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
|
-
|
|
20715
|
-
|
|
20805
|
+
json3.minimum = exclusiveMinimum;
|
|
20806
|
+
json3.exclusiveMinimum = true;
|
|
20716
20807
|
} else {
|
|
20717
|
-
|
|
20808
|
+
json3.exclusiveMinimum = exclusiveMinimum;
|
|
20718
20809
|
}
|
|
20719
20810
|
} else if (typeof minimum === "number") {
|
|
20720
|
-
|
|
20811
|
+
json3.minimum = minimum;
|
|
20721
20812
|
}
|
|
20722
20813
|
if (exMax) {
|
|
20723
20814
|
if (legacy) {
|
|
20724
|
-
|
|
20725
|
-
|
|
20815
|
+
json3.maximum = exclusiveMaximum;
|
|
20816
|
+
json3.exclusiveMaximum = true;
|
|
20726
20817
|
} else {
|
|
20727
|
-
|
|
20818
|
+
json3.exclusiveMaximum = exclusiveMaximum;
|
|
20728
20819
|
}
|
|
20729
20820
|
} else if (typeof maximum === "number") {
|
|
20730
|
-
|
|
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,
|
|
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
|
-
|
|
20833
|
+
json3.multipleOf = first;
|
|
20743
20834
|
if (rest.length)
|
|
20744
|
-
|
|
20835
|
+
json3.allOf = [...json3.allOf ?? [], ...rest.map((m2) => ({ multipleOf: m2 }))];
|
|
20745
20836
|
}
|
|
20746
20837
|
};
|
|
20747
|
-
var booleanProcessor = (_schema, _ctx,
|
|
20748
|
-
|
|
20838
|
+
var booleanProcessor = (_schema, _ctx, json3, _params) => {
|
|
20839
|
+
json3.type = "boolean";
|
|
20749
20840
|
};
|
|
20750
|
-
var bigintProcessor = (schema, ctx,
|
|
20751
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20754
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20847
|
+
var nullProcessor = (_schema, ctx, json3, _params) => {
|
|
20757
20848
|
if (ctx.target === "openapi-3.0") {
|
|
20758
|
-
|
|
20759
|
-
|
|
20760
|
-
|
|
20849
|
+
json3.type = "string";
|
|
20850
|
+
json3.nullable = true;
|
|
20851
|
+
json3.enum = [null];
|
|
20761
20852
|
} else {
|
|
20762
|
-
|
|
20853
|
+
json3.type = "null";
|
|
20763
20854
|
}
|
|
20764
20855
|
};
|
|
20765
|
-
var undefinedProcessor = (schema, ctx,
|
|
20766
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20769
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20772
|
-
|
|
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,
|
|
20779
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
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
|
-
|
|
20876
|
+
json3.not = {};
|
|
20786
20877
|
return;
|
|
20787
20878
|
}
|
|
20788
20879
|
if (values.every((v2) => typeof v2 === "number"))
|
|
20789
|
-
|
|
20880
|
+
json3.type = "number";
|
|
20790
20881
|
if (values.every((v2) => typeof v2 === "string"))
|
|
20791
|
-
|
|
20792
|
-
|
|
20882
|
+
json3.type = "string";
|
|
20883
|
+
json3.enum = values;
|
|
20793
20884
|
};
|
|
20794
|
-
var literalProcessor = (schema, ctx,
|
|
20885
|
+
var literalProcessor = (schema, ctx, json3, params) => {
|
|
20795
20886
|
const def = schema._zod.def;
|
|
20796
20887
|
if (def.values.length === 0) {
|
|
20797
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
20907
|
+
json3.type = val === null ? "null" : typeof val;
|
|
20817
20908
|
if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") {
|
|
20818
|
-
|
|
20909
|
+
json3.enum = [val];
|
|
20819
20910
|
} else {
|
|
20820
|
-
|
|
20911
|
+
json3.const = val;
|
|
20821
20912
|
}
|
|
20822
20913
|
} else {
|
|
20823
20914
|
if (vals.every((v2) => typeof v2 === "number"))
|
|
20824
|
-
|
|
20915
|
+
json3.type = "number";
|
|
20825
20916
|
if (vals.every((v2) => typeof v2 === "string"))
|
|
20826
|
-
|
|
20917
|
+
json3.type = "string";
|
|
20827
20918
|
if (vals.every((v2) => typeof v2 === "boolean"))
|
|
20828
|
-
|
|
20919
|
+
json3.type = "boolean";
|
|
20829
20920
|
if (vals.every((v2) => v2 === null))
|
|
20830
|
-
|
|
20831
|
-
|
|
20921
|
+
json3.type = "null";
|
|
20922
|
+
json3.enum = vals;
|
|
20832
20923
|
}
|
|
20833
20924
|
};
|
|
20834
|
-
var nanProcessor = (schema, ctx,
|
|
20835
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20838
|
-
const _json =
|
|
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,
|
|
20846
|
-
const _json =
|
|
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,
|
|
20865
|
-
|
|
20955
|
+
var successProcessor = (_schema, _ctx, json3, _params) => {
|
|
20956
|
+
json3.type = "boolean";
|
|
20866
20957
|
};
|
|
20867
|
-
var customProcessor = (schema, ctx,
|
|
20868
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20871
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20874
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20877
|
-
handleUnrepresentable(schema, ctx,
|
|
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,
|
|
20880
|
-
handleUnrepresentable(schema, ctx,
|
|
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
|
|
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
|
-
|
|
20978
|
+
json3.minItems = minimum;
|
|
20888
20979
|
if (typeof maximum === "number")
|
|
20889
|
-
|
|
20890
|
-
|
|
20891
|
-
|
|
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
|
|
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,
|
|
21002
|
+
if (symbolKeys.length && handleUnrepresentable(schema, ctx, json3, params, "Symbol keys cannot be represented in JSON Schema")) {
|
|
20912
21003
|
return;
|
|
20913
21004
|
}
|
|
20914
|
-
|
|
20915
|
-
|
|
21005
|
+
json3.type = "object";
|
|
21006
|
+
json3.properties = {};
|
|
20916
21007
|
for (const key3 in shape) {
|
|
20917
|
-
assignProp(
|
|
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
|
-
|
|
21021
|
+
json3.required = requiredKeys;
|
|
20931
21022
|
}
|
|
20932
21023
|
if (def.catchall?._zod.def.type === "never") {
|
|
20933
|
-
|
|
21024
|
+
json3.additionalProperties = false;
|
|
20934
21025
|
} else if (!def.catchall) {
|
|
20935
21026
|
if (ctx.io === "output")
|
|
20936
|
-
|
|
21027
|
+
json3.additionalProperties = false;
|
|
20937
21028
|
} else if (def.catchall) {
|
|
20938
|
-
|
|
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,
|
|
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
|
-
|
|
21043
|
+
json3.oneOf = options;
|
|
20953
21044
|
} else {
|
|
20954
|
-
|
|
21045
|
+
json3.anyOf = options;
|
|
20955
21046
|
}
|
|
20956
21047
|
};
|
|
20957
|
-
var intersectionProcessor = (schema, ctx,
|
|
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
|
-
|
|
21063
|
+
json3.allOf = allOf;
|
|
20973
21064
|
ctx.intersections.push(allOf);
|
|
20974
21065
|
};
|
|
20975
21066
|
var tupleProcessor = (schema, ctx, _json, params) => {
|
|
20976
|
-
const
|
|
21067
|
+
const json3 = _json;
|
|
20977
21068
|
const def = schema._zod.def;
|
|
20978
|
-
|
|
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
|
-
|
|
21091
|
+
json3.prefixItems = prefixItems;
|
|
21001
21092
|
if (isClosed) {
|
|
21002
|
-
|
|
21093
|
+
json3.items = false;
|
|
21003
21094
|
} else if (rest) {
|
|
21004
|
-
|
|
21095
|
+
json3.items = rest;
|
|
21005
21096
|
}
|
|
21006
21097
|
if (minItems > 0)
|
|
21007
|
-
|
|
21098
|
+
json3.minItems = minItems;
|
|
21008
21099
|
if (isClosed)
|
|
21009
|
-
|
|
21100
|
+
json3.maxItems = maxItems;
|
|
21010
21101
|
} else if (ctx.target === "openapi-3.0") {
|
|
21011
|
-
|
|
21102
|
+
json3.items = {
|
|
21012
21103
|
anyOf: prefixItems
|
|
21013
21104
|
};
|
|
21014
21105
|
if (rest) {
|
|
21015
|
-
|
|
21106
|
+
json3.items.anyOf.push(rest);
|
|
21016
21107
|
}
|
|
21017
21108
|
if (minItems > 0)
|
|
21018
|
-
|
|
21109
|
+
json3.minItems = minItems;
|
|
21019
21110
|
if (isClosed)
|
|
21020
|
-
|
|
21111
|
+
json3.maxItems = maxItems;
|
|
21021
21112
|
} else {
|
|
21022
|
-
|
|
21113
|
+
json3.items = prefixItems;
|
|
21023
21114
|
if (isClosed) {
|
|
21024
|
-
|
|
21115
|
+
json3.additionalItems = false;
|
|
21025
21116
|
} else if (rest) {
|
|
21026
|
-
|
|
21117
|
+
json3.additionalItems = rest;
|
|
21027
21118
|
}
|
|
21028
21119
|
if (minItems > 0)
|
|
21029
|
-
|
|
21120
|
+
json3.minItems = minItems;
|
|
21030
21121
|
if (isClosed)
|
|
21031
|
-
|
|
21122
|
+
json3.maxItems = maxItems;
|
|
21032
21123
|
}
|
|
21033
21124
|
const { minimum, maximum } = aggregateChecks(schema);
|
|
21034
21125
|
if (typeof minimum === "number")
|
|
21035
|
-
|
|
21126
|
+
json3.minItems = minimum;
|
|
21036
21127
|
if (typeof maximum === "number")
|
|
21037
|
-
|
|
21128
|
+
json3.maxItems = maximum;
|
|
21038
21129
|
};
|
|
21039
|
-
function stringifyKeyNames(bySchema,
|
|
21040
|
-
if (
|
|
21041
|
-
if (visited.has(
|
|
21042
|
-
return
|
|
21043
|
-
visited.add(
|
|
21044
|
-
const def = bySchema.get(
|
|
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
|
|
21137
|
+
return json3;
|
|
21047
21138
|
const inlined = stringifyKeyNames(bySchema, def, visited);
|
|
21048
|
-
return inlined === def ?
|
|
21139
|
+
return inlined === def ? json3 : inlined;
|
|
21049
21140
|
}
|
|
21050
21141
|
for (const keyword of ["anyOf", "oneOf"]) {
|
|
21051
|
-
const branches =
|
|
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
|
-
|
|
21147
|
+
json3 = { ...json3, [keyword]: mapped };
|
|
21057
21148
|
}
|
|
21058
|
-
const types = Array.isArray(
|
|
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 =
|
|
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
|
|
21063
|
-
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } =
|
|
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
|
|
21194
|
+
const json3 = _json;
|
|
21104
21195
|
const def = schema._zod.def;
|
|
21105
|
-
|
|
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
|
-
|
|
21204
|
+
json3.patternProperties = {};
|
|
21114
21205
|
for (const pattern of patterns) {
|
|
21115
|
-
assignProp(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
21232
|
+
json3.required = validKeyValues.map(String);
|
|
21142
21233
|
}
|
|
21143
21234
|
}
|
|
21144
21235
|
};
|
|
21145
|
-
var nullableProcessor = (schema, ctx,
|
|
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
|
-
|
|
21242
|
+
json3.nullable = true;
|
|
21152
21243
|
} else {
|
|
21153
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
21272
|
+
const value = serializeDefaultValue(def.defaultValue, schema, ctx, json3, params);
|
|
21182
21273
|
if (value !== UNREPRESENTABLE_DEFAULT)
|
|
21183
|
-
|
|
21274
|
+
json3.default = value;
|
|
21184
21275
|
};
|
|
21185
|
-
var prefaultProcessor = (schema, ctx,
|
|
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,
|
|
21283
|
+
const value = serializeDefaultValue(def.defaultValue, schema, ctx, json3, params);
|
|
21193
21284
|
if (value !== UNREPRESENTABLE_DEFAULT)
|
|
21194
|
-
|
|
21285
|
+
json3._prefault = value;
|
|
21195
21286
|
};
|
|
21196
|
-
var catchProcessor = (schema, ctx,
|
|
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,
|
|
21296
|
+
handleUnrepresentable(schema, ctx, json3, params, "Dynamic catch values are not supported in JSON Schema");
|
|
21206
21297
|
return;
|
|
21207
21298
|
}
|
|
21208
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
21711
|
-
reg.add(this,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
24225
|
-
|
|
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
|
-
|
|
24327
|
+
return process.env.REFLEX_REDACT_USER ?? userInfo().username;
|
|
24228
24328
|
} catch {
|
|
24229
|
-
|
|
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
|
|
24236
|
-
function
|
|
24237
|
-
|
|
24238
|
-
|
|
24239
|
-
|
|
24240
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
24538
|
+
let line2 = 0;
|
|
24396
24539
|
try {
|
|
24397
24540
|
for await (const raw of rl) {
|
|
24398
|
-
|
|
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) =>
|
|
24426
|
-
command: (text) =>
|
|
24427
|
-
assistant: (text) =>
|
|
24428
|
-
path: (text) =>
|
|
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
|
|
24793
|
+
for await (const line2 of readJsonl(file2.path)) {
|
|
24651
24794
|
totalRecords++;
|
|
24652
|
-
if (
|
|
24795
|
+
if (line2.error) {
|
|
24653
24796
|
skippedRecords++;
|
|
24654
24797
|
continue;
|
|
24655
24798
|
}
|
|
24656
|
-
const parsed = ClaudeRecord.safeParse(
|
|
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
|
|
24981
|
+
for await (const line2 of readJsonl(file2.path)) {
|
|
24839
24982
|
totalRecords++;
|
|
24840
|
-
if (
|
|
24983
|
+
if (line2.error) {
|
|
24841
24984
|
skippedRecords++;
|
|
24842
24985
|
continue;
|
|
24843
24986
|
}
|
|
24844
|
-
const wrapped = RolloutLine.safeParse(
|
|
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 ??
|
|
24994
|
+
const body = wrapped.data.payload ?? line2.value;
|
|
24852
24995
|
b3.touch(at);
|
|
24853
24996
|
if (kind === "session_meta") {
|
|
24854
|
-
const
|
|
24855
|
-
if (
|
|
24856
|
-
if (
|
|
24857
|
-
if (
|
|
24858
|
-
b3.touch(
|
|
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
|
|
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) &&
|
|
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
|
|
25126
|
-
const
|
|
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 (
|
|
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
|
|
25351
|
+
for await (const line2 of readJsonl(path)) {
|
|
25209
25352
|
counts.total++;
|
|
25210
|
-
if (
|
|
25353
|
+
if (line2.error) {
|
|
25211
25354
|
counts.skipped++;
|
|
25212
25355
|
continue;
|
|
25213
25356
|
}
|
|
25214
|
-
const parsed = CursorRecord.safeParse(
|
|
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((
|
|
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(
|
|
25975
|
+
function concepts(terms2) {
|
|
25833
25976
|
const v2 = /* @__PURE__ */ new Map();
|
|
25834
|
-
for (const t of
|
|
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
|
-
|
|
25883
|
-
|
|
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
|
-
|
|
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
|
-
|
|
26043
|
+
rows2[cur] = 0;
|
|
25894
26044
|
for (let j2 = 1; j2 <= b3.length; j2++) {
|
|
25895
|
-
cur
|
|
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
|
|
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 *
|
|
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
|
-
|
|
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
|
|
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:
|
|
25948
|
-
commands:
|
|
25949
|
-
files:
|
|
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
|
|
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 =
|
|
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
|
-
|
|
26219
|
+
rules2.set(id, rule);
|
|
26057
26220
|
}
|
|
26058
26221
|
}
|
|
26059
|
-
const all = [...
|
|
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(
|
|
26072
|
-
return /^\s*at\s/.test(
|
|
26073
|
-
|
|
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((
|
|
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
|
|
26126
|
-
const
|
|
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
|
-
|
|
26144
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
26403
|
+
function outcomeOf(steps2, summarized) {
|
|
26241
26404
|
let lastModify = -1;
|
|
26242
|
-
|
|
26405
|
+
steps2.forEach((s, i) => {
|
|
26243
26406
|
if (MODIFY_ACTIONS.has(s.action)) lastModify = i;
|
|
26244
26407
|
});
|
|
26245
|
-
const verified =
|
|
26246
|
-
const failedAt =
|
|
26247
|
-
const recoveredFromFailure = failedAt >= 0 &&
|
|
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
|
|
26572
|
+
const features = traces.map(traceFeatures);
|
|
26386
26573
|
const n = traces.length;
|
|
26387
|
-
const
|
|
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),
|
|
26392
|
-
|
|
26393
|
-
|
|
26394
|
-
|
|
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
|
|
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.
|
|
26419
|
-
const intentLink = sim.intent.
|
|
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 (
|
|
26426
|
-
|
|
26427
|
-
|
|
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
|
-
|
|
26441
|
-
|
|
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(
|
|
26901
|
+
function completionCriteria(steps2) {
|
|
26702
26902
|
const out2 = [];
|
|
26703
|
-
if (
|
|
26704
|
-
if (
|
|
26705
|
-
if (
|
|
26706
|
-
if (
|
|
26707
|
-
if (
|
|
26708
|
-
if (
|
|
26709
|
-
if (
|
|
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
|
|
26774
|
-
const stepKinds = new Set(
|
|
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
|
|
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 =
|
|
26781
|
-
const baseSlug = family?.slug ?? toSlug(fallbackTerms.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 =
|
|
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 ${
|
|
26829
|
-
whenToUse: family?.whenToUse ?? `Use for requests similar to: ${
|
|
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:
|
|
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
|
|
26978
|
-
const arms = (guess.kind ? table2.find((k3) => k3.kind.key === guess.kind.key)?.arms ?? [] : []).filter(
|
|
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
|
|
27160
|
-
const
|
|
27161
|
-
const missing =
|
|
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
|
|
27182
|
-
if (/^\s*```/.test(
|
|
27183
|
-
shape.push(fence ? "code:end" : `code:${
|
|
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(
|
|
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(
|
|
27193
|
-
else if (/^\s*[-*+]\s+/.test(
|
|
27194
|
-
else if (/^\s*\d+[.)]\s+/.test(
|
|
27195
|
-
else if (/^\s*\*\*[^*]+\*\*:?/.test(
|
|
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
|
|
27308
|
-
const m2 = /^([a-z][a-z0-9-]*):\s*(.*)$/i.exec(
|
|
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
|
|
27335
|
-
${
|
|
27336
|
-
`)) errors.push(`missing section "${
|
|
27337
|
-
const
|
|
27338
|
-
if (
|
|
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(
|
|
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 = (
|
|
27927
|
+
const handle = (line2) => {
|
|
27597
27928
|
let msg;
|
|
27598
27929
|
try {
|
|
27599
|
-
msg = JSON.parse(
|
|
27930
|
+
msg = JSON.parse(line2);
|
|
27600
27931
|
} catch {
|
|
27601
27932
|
return;
|
|
27602
27933
|
}
|
|
27603
|
-
if (msg.type === "result" && typeof msg.result === "string") run2.finalMessage =
|
|
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(
|
|
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(
|
|
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
|
-
...
|
|
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
|
|
27778
|
-
if (findLeaks(
|
|
27779
|
-
return
|
|
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,
|
|
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) +
|
|
27789
|
-
return content.replace(/\n*$/, "\n\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(
|
|
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 = (
|
|
28222
|
+
const handle = (line2) => {
|
|
27889
28223
|
let msg;
|
|
27890
28224
|
try {
|
|
27891
|
-
msg = JSON.parse(
|
|
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(
|
|
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(
|
|
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
|
|
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,
|
|
28688
|
-
const speedup = 1 + (
|
|
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 [
|
|
28709
|
-
const tokenizer = new Tokenizer(JSON.parse(
|
|
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
|
-
|
|
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
|
|
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
|
|
30975
|
-
if (cost.runsWithTokens) return
|
|
30976
|
-
return s.sources.cursor ? `${
|
|
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
|
|
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
|
|
31370
|
-
const
|
|
31371
|
-
out(e2.status === "forgotten" ? c.dim(`${
|
|
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
|
|
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,
|
|
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 (${
|
|
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
|
|
31728
|
-
if (!
|
|
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,
|
|
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
|
|
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
|
|
32211
|
-
l2 = l2.concat(
|
|
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((
|
|
32848
|
+
src.forEach((line2) => {
|
|
32385
32849
|
let c2 = "fg";
|
|
32386
32850
|
let b3 = null;
|
|
32387
|
-
if (
|
|
32851
|
+
if (line2 === "---") {
|
|
32388
32852
|
fm++;
|
|
32389
32853
|
c2 = "dim";
|
|
32390
32854
|
} else if (fm === 1) c2 = "dim";
|
|
32391
|
-
else if (
|
|
32855
|
+
else if (line2.startsWith("#")) {
|
|
32392
32856
|
c2 = "hi";
|
|
32393
32857
|
b3 = BOLD;
|
|
32394
32858
|
}
|
|
32395
|
-
wrap(
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
34520
|
-
import { basename as basename8,
|
|
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
|
|
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
|
-
|
|
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) ?? [], ...
|
|
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
|
|
35048
|
+
for (const line2 of buf.subarray(0, n).toString("utf8").split("\n")) {
|
|
34580
35049
|
try {
|
|
34581
|
-
const cwd = JSON.parse(
|
|
34582
|
-
if (typeof cwd === "string" &&
|
|
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 (
|
|
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
|
-
|
|
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.
|
|
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));
|