runcastle 1.5.5 → 1.5.6

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/index.js CHANGED
@@ -205,7 +205,8 @@ var init_review_gates = __esm(() => {
205
205
  z2.object({
206
206
  status: z2.literal("ran"),
207
207
  commit: z2.string(),
208
- commands: z2.array(GateCommandResult)
208
+ commands: z2.array(GateCommandResult),
209
+ reusedFrom: z2.object({ kind: z2.enum(["round", "review"]), id: z2.string() }).optional()
209
210
  })
210
211
  ]);
211
212
  });
@@ -4349,12 +4350,14 @@ async function commitsSince(repoPath, sha, branch) {
4349
4350
  return;
4350
4351
  }
4351
4352
  }
4352
- async function diffPaths(repoPath, from, to) {
4353
+ async function diffPaths(repoPath, from, to, opts = {}) {
4353
4354
  try {
4354
4355
  const out = (await git(repoPath).raw(["diff", "--name-only", from, to])).trim();
4355
4356
  return out ? out.split(`
4356
4357
  `).map((s) => s.trim()).filter(Boolean) : [];
4357
- } catch {
4358
+ } catch (err) {
4359
+ if (opts.throwOnError)
4360
+ throw err;
4358
4361
  return [];
4359
4362
  }
4360
4363
  }
@@ -9641,1012 +9644,339 @@ var init_kill_registry = __esm(() => {
9641
9644
  REGISTRY_KEY2 = Symbol.for("runcastle.kill.registry");
9642
9645
  });
9643
9646
 
9644
- // src/services/settings.ts
9645
- import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
9646
- import { dirname as dirname8 } from "path";
9647
- import * as z5 from "zod";
9648
- import { eq as eq11 } from "drizzle-orm";
9649
- function hostDefaults(logicalCpus) {
9650
- return { ...DEFAULTS, burnConcurrency: resolveDefaultBurnConcurrency(logicalCpus) };
9651
- }
9652
- function readRawConfig(configFile) {
9653
- if (!existsSync15(configFile))
9654
- return {};
9655
- try {
9656
- const parsed = JSON.parse(readFileSync11(configFile, "utf8"));
9657
- if (typeof parsed !== "object" || parsed === null)
9658
- return {};
9659
- return foldLegacyModelConfig(migrateCollapsedModelSteps(parsed));
9660
- } catch {
9661
- return {};
9647
+ // ../../node_modules/.bun/@ai-hero+sandcastle@0.12.0/node_modules/@ai-hero/sandcastle/dist/chunk-NGBM7T3E.js
9648
+ import { createRequire as createRequire4 } from "module";
9649
+ var require$1, __create, __defProp2, __getOwnPropDesc, __getOwnPropNames, __getProtoOf, __hasOwnProp, __require2, __commonJS = (cb, mod) => function __require22() {
9650
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9651
+ }, __export2 = (target, all) => {
9652
+ for (var name in all)
9653
+ __defProp2(target, name, { get: all[name], enumerable: true });
9654
+ }, __copyProps = (to, from, except, desc5) => {
9655
+ if (from && typeof from === "object" || typeof from === "function") {
9656
+ for (let key of __getOwnPropNames(from))
9657
+ if (!__hasOwnProp.call(to, key) && key !== except)
9658
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc5 = __getOwnPropDesc(from, key)) || desc5.enumerable });
9662
9659
  }
9663
- }
9664
- function rawStepModels(fileRaw) {
9665
- const raw = fileRaw.stepModels;
9666
- return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
9667
- }
9668
- function stepModelFields(fileRaw) {
9669
- const set = rawStepModels(fileRaw);
9670
- return MODEL_STEPS.map((step) => {
9671
- const base = { key: `stepModels.${step}`, restartRequired: false, scope: "global" };
9672
- const v = set[step];
9673
- if (typeof v === "string" && v !== "") {
9674
- return { ...base, value: v, source: "file", editable: true };
9660
+ return to;
9661
+ }, __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")), __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)), MAX_TAIL_CHARS, BoundedTail = class {
9662
+ items = [];
9663
+ totalChars = 0;
9664
+ maxChars;
9665
+ separator;
9666
+ constructor(maxChars = MAX_TAIL_CHARS, separator = "") {
9667
+ this.maxChars = maxChars;
9668
+ this.separator = separator;
9669
+ }
9670
+ push(item) {
9671
+ const bounded = item.length > this.maxChars ? item.slice(item.length - this.maxChars) : item;
9672
+ this.totalChars += bounded.length + (this.items.length > 0 ? this.separator.length : 0);
9673
+ this.items.push(bounded);
9674
+ while (this.totalChars > this.maxChars && this.items.length > 1) {
9675
+ const dropped = this.items.shift();
9676
+ this.totalChars -= dropped.length + this.separator.length;
9675
9677
  }
9676
- return { ...base, value: DEFAULTS.stepModels[step] ?? null, source: "default", editable: true };
9678
+ }
9679
+ toString() {
9680
+ return this.items.join(this.separator);
9681
+ }
9682
+ }, elidePayloadTokens = (command) => command.replace(/'[A-Za-z0-9+\/=]{120,}'/g, "'\u2026'"), formatExecFailureMessage = (command, result, maxTailChars = MAX_TAIL_CHARS) => {
9683
+ const output = [result.stdout, result.stderr].map((stream) => (stream ?? "").trimEnd()).filter((stream) => stream.length > 0).join(`
9684
+ `);
9685
+ const tail = output.length > maxTailChars ? output.slice(output.length - maxTailChars) : output;
9686
+ const headline = `Command failed (exit ${result.exitCode}): ${elidePayloadTokens(command)}`;
9687
+ return tail ? `${headline}
9688
+ ${tail}` : headline;
9689
+ };
9690
+ var init_chunk_NGBM7T3E = __esm(() => {
9691
+ require$1 = createRequire4(import.meta.url);
9692
+ __create = Object.create;
9693
+ __defProp2 = Object.defineProperty;
9694
+ __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9695
+ __getOwnPropNames = Object.getOwnPropertyNames;
9696
+ __getProtoOf = Object.getPrototypeOf;
9697
+ __hasOwnProp = Object.prototype.hasOwnProperty;
9698
+ __require2 = /* @__PURE__ */ ((x) => typeof require$1 !== "undefined" ? require$1 : typeof Proxy !== "undefined" ? new Proxy(x, {
9699
+ get: (a, b) => (typeof require$1 !== "undefined" ? require$1 : a)[b]
9700
+ }) : x)(function(x) {
9701
+ if (typeof require$1 !== "undefined")
9702
+ return require$1.apply(this, arguments);
9703
+ throw Error('Dynamic require of "' + x + '" is not supported');
9677
9704
  });
9678
- }
9679
- function projectOverrides(ctx, projectId) {
9680
- const row = ctx.db.select({
9681
- model: projects.model,
9682
- sandbox: projects.sandbox,
9683
- sandboxImage: projects.sandboxImage,
9684
- sessionBranch: projects.sessionBranch,
9685
- devCommand: projects.devCommand,
9686
- setupCommand: projects.setupCommand,
9687
- verifyCommands: projects.verifyCommands,
9688
- knownFailures: projects.knownFailures,
9689
- dbResetCommand: projects.dbResetCommand,
9690
- driveSetupCommand: projects.driveSetupCommand,
9691
- driveStopCommand: projects.driveStopCommand,
9692
- driveInstructions: projects.driveInstructions,
9693
- scenarioRunner: projects.scenarioRunner,
9694
- docsCommitPrefix: projects.docsCommitPrefix
9695
- }).from(projects).where(eq11(projects.id, projectId)).get();
9696
- return {
9697
- model: row?.model ?? null,
9698
- sandbox: row?.sandbox ?? null,
9699
- sandboxImage: row?.sandboxImage ?? null,
9700
- sessionBranch: row?.sessionBranch ?? null,
9701
- devCommand: row?.devCommand ?? null,
9702
- setupCommand: row?.setupCommand ?? null,
9703
- verifyCommands: row?.verifyCommands ?? null,
9704
- knownFailures: row?.knownFailures ?? null,
9705
- dbResetCommand: row?.dbResetCommand ?? null,
9706
- driveSetupCommand: row?.driveSetupCommand ?? null,
9707
- driveStopCommand: row?.driveStopCommand ?? null,
9708
- driveInstructions: row?.driveInstructions ?? null,
9709
- scenarioRunner: row?.scenarioRunner ?? null,
9710
- docsCommitPrefix: row?.docsCommitPrefix ?? null
9711
- };
9712
- }
9713
- function resolveField(desc5, layers) {
9714
- const scoped = layers.overrides !== null;
9715
- const scope = scoped && desc5.projectColumn ? "project" : "global";
9716
- const base = { key: desc5.key, restartRequired: desc5.restartRequired, scope };
9717
- if (desc5.envVar) {
9718
- const raw = layers.env[desc5.envVar];
9719
- if (raw !== undefined && raw !== "") {
9720
- return { ...base, value: desc5.parseEnv(raw), source: "env", editable: false };
9705
+ MAX_TAIL_CHARS = 64 * 1024;
9706
+ });
9707
+
9708
+ // ../../node_modules/.bun/@ai-hero+sandcastle@0.12.0/node_modules/@ai-hero/sandcastle/dist/chunk-VOG34SRF.js
9709
+ import { createRequire as createRequire5 } from "module";
9710
+ import * as clack from "@clack/prompts";
9711
+ import { join as join$1, basename as basename3, dirname as dirname8, resolve as resolve10, posix as posix2, normalize, isAbsolute as isAbsolute2 } from "path";
9712
+ import { styleText, promisify } from "util";
9713
+ import { existsSync as existsSync15, statSync as statSync5 } from "fs";
9714
+ import { tmpdir as tmpdir2, homedir as homedir3 } from "os";
9715
+ import { mkdtemp, writeFile, mkdir, readFile as readFile2, rm, readdir, stat } from "fs/promises";
9716
+ import { exec, execFile } from "child_process";
9717
+ import { randomBytes as randomBytes2 } from "crypto";
9718
+ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
9719
+ switch (arguments.length) {
9720
+ case 1:
9721
+ return a;
9722
+ case 2:
9723
+ return ab(a);
9724
+ case 3:
9725
+ return bc(ab(a));
9726
+ case 4:
9727
+ return cd(bc(ab(a)));
9728
+ case 5:
9729
+ return de(cd(bc(ab(a))));
9730
+ case 6:
9731
+ return ef(de(cd(bc(ab(a)))));
9732
+ case 7:
9733
+ return fg(ef(de(cd(bc(ab(a))))));
9734
+ case 8:
9735
+ return gh(fg(ef(de(cd(bc(ab(a)))))));
9736
+ case 9:
9737
+ return hi(gh(fg(ef(de(cd(bc(ab(a))))))));
9738
+ default: {
9739
+ let ret = arguments[0];
9740
+ for (let i = 1;i < arguments.length; i++) {
9741
+ ret = arguments[i](ret);
9742
+ }
9743
+ return ret;
9721
9744
  }
9722
9745
  }
9723
- if (layers.overrides && desc5.projectColumn) {
9724
- const ov = layers.overrides[desc5.projectColumn];
9725
- if (ov !== null && ov !== "") {
9726
- return { ...base, value: ov, source: "project", editable: true };
9727
- }
9746
+ }
9747
+ function mul64(out, aHi, aLo, bHi, bLo) {
9748
+ let c1 = (aLo >>> 16) * (bLo & 65535) >>> 0;
9749
+ let c0 = (aLo & 65535) * (bLo >>> 16) >>> 0;
9750
+ let lo = (aLo & 65535) * (bLo & 65535) >>> 0;
9751
+ let hi = (aLo >>> 16) * (bLo >>> 16) + ((c0 >>> 16) + (c1 >>> 16)) >>> 0;
9752
+ c0 = c0 << 16 >>> 0;
9753
+ lo = lo + c0 >>> 0;
9754
+ if (lo >>> 0 < c0 >>> 0) {
9755
+ hi = hi + 1 >>> 0;
9728
9756
  }
9729
- if (desc5.configKey && Object.prototype.hasOwnProperty.call(layers.fileRaw, desc5.configKey)) {
9730
- return { ...base, value: layers.fileRaw[desc5.configKey], source: "file", editable: true };
9757
+ c1 = c1 << 16 >>> 0;
9758
+ lo = lo + c1 >>> 0;
9759
+ if (lo >>> 0 < c1 >>> 0) {
9760
+ hi = hi + 1 >>> 0;
9731
9761
  }
9732
- const value = desc5.configKey ? layers.defaults[desc5.configKey] ?? null : desc5.defaultValue ?? null;
9733
- return { ...base, value, source: "default", editable: true };
9762
+ hi = hi + Math.imul(aLo, bHi) >>> 0;
9763
+ hi = hi + Math.imul(aHi, bLo) >>> 0;
9764
+ out[0] = hi;
9765
+ out[1] = lo;
9734
9766
  }
9735
- function getSettings(ctx, projectId, io = {}) {
9736
- const env = io.env ?? process.env;
9737
- const fileRaw = readRawConfig(io.configFile ?? configPath());
9738
- const overrides = projectId !== undefined ? projectOverrides(ctx, projectId) : null;
9739
- const defaults = hostDefaults(io.logicalCpus ?? hostLogicalCpus());
9740
- const visible = DESCRIPTORS.filter((d) => projectId !== undefined || d.configKey !== undefined);
9741
- const fields = visible.map((d) => resolveField(d, { env, fileRaw, overrides, defaults }));
9742
- return {
9743
- projectId,
9744
- fields: [...fields, ...stepModelFields(fileRaw)],
9745
- discovery: discoverySnapshot(ctx)
9746
- };
9767
+ function add64(out, aHi, aLo, bHi, bLo) {
9768
+ let hi = aHi + bHi >>> 0;
9769
+ const lo = aLo + bLo >>> 0;
9770
+ if (lo >>> 0 < aLo >>> 0) {
9771
+ hi = hi + 1 | 0;
9772
+ }
9773
+ out[0] = hi;
9774
+ out[1] = lo;
9747
9775
  }
9748
- function updateSettings(ctx, input, io = {}) {
9749
- const env = io.env ?? process.env;
9750
- const configFile = io.configFile ?? configPath();
9751
- if (input.key.startsWith("stepModels.")) {
9752
- return updateStepModel(ctx, input, configFile, io);
9776
+ function yieldWrapGet(self) {
9777
+ if (typeof self === "object" && self !== null && YieldWrapTypeId in self) {
9778
+ return self[YieldWrapTypeId]();
9753
9779
  }
9754
- const desc5 = DESCRIPTORS.find((d) => d.key === input.key);
9755
- if (!desc5)
9756
- throw new InvalidInputError(`unknown setting: ${input.key}`);
9757
- if (desc5.envVar) {
9758
- const raw = env[desc5.envVar];
9759
- if (raw !== undefined && raw !== "") {
9760
- throw new InvalidInputError(`${desc5.key} is set by environment variable ${desc5.envVar}; unset it to edit`);
9761
- }
9780
+ throw new Error(getBugErrorMessage("yieldWrapGet"));
9781
+ }
9782
+ function equals() {
9783
+ if (arguments.length === 1) {
9784
+ return (self) => compareBoth(self, arguments[0]);
9762
9785
  }
9763
- const toProject = input.projectId !== undefined && desc5.projectColumn !== undefined;
9764
- if (input.value === null) {
9765
- if (!toProject)
9766
- return clearGlobal(ctx, desc5, input, configFile, io);
9767
- const project = requireProjectById(ctx, input.projectId);
9768
- ctx.db.update(projects).set({ [desc5.projectColumn]: null }).where(eq11(projects.id, project.id)).run();
9769
- recordHuman(ctx, project.id, desc5.key, null);
9770
- emitProject(ctx, project.id, {
9771
- type: "settings.updated",
9772
- message: `${desc5.key} override cleared`,
9773
- data: { key: desc5.key, scope: "project", value: null }
9774
- });
9775
- return field(getSettings(ctx, input.projectId, io), desc5.key);
9786
+ return compareBoth(arguments[0], arguments[1]);
9787
+ }
9788
+ function compareBoth(self, that) {
9789
+ if (self === that) {
9790
+ return true;
9776
9791
  }
9777
- const parsed = desc5.valueSchema.safeParse(input.value);
9778
- if (!parsed.success) {
9779
- throw new InvalidInputError(`invalid value for ${desc5.key}: ${parsed.error.issues[0]?.message}`);
9792
+ const selfType = typeof self;
9793
+ if (selfType !== typeof that) {
9794
+ return false;
9780
9795
  }
9781
- const value = parsed.data;
9782
- if (toProject) {
9783
- const project = requireProjectById(ctx, input.projectId);
9784
- ctx.db.update(projects).set({ [desc5.projectColumn]: String(value) }).where(eq11(projects.id, project.id)).run();
9785
- recordHuman(ctx, project.id, desc5.key, String(value));
9786
- emitProject(ctx, project.id, {
9787
- type: "settings.updated",
9788
- message: `${desc5.key} override set to ${String(value)}`,
9789
- data: { key: desc5.key, scope: "project", value }
9790
- });
9791
- return field(getSettings(ctx, input.projectId, io), desc5.key);
9796
+ if (selfType === "object" || selfType === "function") {
9797
+ if (self !== null && that !== null) {
9798
+ if (isEqual(self) && isEqual(that)) {
9799
+ if (hash(self) === hash(that) && self[symbol2](that)) {
9800
+ return true;
9801
+ } else {
9802
+ return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
9803
+ }
9804
+ } else if (self instanceof Date && that instanceof Date) {
9805
+ const t1 = self.getTime();
9806
+ const t2 = that.getTime();
9807
+ return t1 === t2 || Number.isNaN(t1) && Number.isNaN(t2);
9808
+ } else if (self instanceof URL && that instanceof URL) {
9809
+ return self.href === that.href;
9810
+ }
9811
+ }
9812
+ if (structuralRegionState.enabled) {
9813
+ if (Array.isArray(self) && Array.isArray(that)) {
9814
+ return self.length === that.length && self.every((v, i) => compareBoth(v, that[i]));
9815
+ }
9816
+ if (Object.getPrototypeOf(self) === Object.prototype && Object.getPrototypeOf(that) === Object.prototype) {
9817
+ const keysSelf = Object.keys(self);
9818
+ const keysThat = Object.keys(that);
9819
+ if (keysSelf.length === keysThat.length) {
9820
+ for (const key of keysSelf) {
9821
+ if (!((key in that) && compareBoth(self[key], that[key]))) {
9822
+ return structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
9823
+ }
9824
+ }
9825
+ return true;
9826
+ }
9827
+ }
9828
+ return structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
9829
+ }
9792
9830
  }
9793
- if (!desc5.configKey) {
9794
- throw new InvalidInputError(`${desc5.key} is a per-project setting; provide a projectId`);
9831
+ return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
9832
+ }
9833
+ function formatDate(date2) {
9834
+ try {
9835
+ return date2.toISOString();
9836
+ } catch {
9837
+ return "Invalid Date";
9795
9838
  }
9796
- writeGlobal(configFile, desc5.configKey, value);
9797
- ctx.config[desc5.configKey] = value;
9798
- emitProject(ctx, GLOBAL_EVENT_KEY, {
9799
- type: "settings.updated",
9800
- message: `${desc5.key} set to ${describeValue(value)}`,
9801
- data: { key: desc5.key, scope: "global", value }
9802
- });
9803
- return field(getSettings(ctx, input.projectId, io), desc5.key);
9804
9839
  }
9805
- function clearGlobal(ctx, desc5, input, configFile, io) {
9806
- if (!desc5.configKey || !GLOBAL_CLEARABLE_KEYS.has(desc5.key)) {
9807
- throw new InvalidInputError(`${desc5.key} cannot be cleared`);
9840
+ function safeToString(input) {
9841
+ try {
9842
+ const s = input.toString();
9843
+ return typeof s === "string" ? s : String(s);
9844
+ } catch {
9845
+ return "[toString threw]";
9808
9846
  }
9809
- removeGlobal(configFile, desc5.configKey);
9810
- delete ctx.config[desc5.configKey];
9811
- emitProject(ctx, GLOBAL_EVENT_KEY, {
9812
- type: "settings.updated",
9813
- message: `${desc5.key} cleared`,
9814
- data: { key: desc5.key, scope: "global", value: null }
9815
- });
9816
- return field(getSettings(ctx, input.projectId, io), desc5.key);
9817
9847
  }
9818
- function describeValue(value) {
9819
- return typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
9848
+ function formatPropertyKey(name) {
9849
+ return isString(name) ? JSON.stringify(name) : String(name);
9820
9850
  }
9821
- function writeGlobal(configFile, configKey, value) {
9822
- const raw = readRawConfig(configFile);
9823
- raw[configKey] = value;
9824
- saveRawConfig(configFile, raw);
9851
+ function formatUnknown(input, options) {
9852
+ const seen = /* @__PURE__ */ new WeakSet;
9853
+ const wrap = (v, body) => {
9854
+ const ctor = v?.constructor;
9855
+ return ctor && ctor !== Object.prototype.constructor && ctor.name ? `${ctor.name}(${body})` : body;
9856
+ };
9857
+ const ownKeys = (o) => {
9858
+ try {
9859
+ return Reflect.ownKeys(o);
9860
+ } catch {
9861
+ return ["[ownKeys threw]"];
9862
+ }
9863
+ };
9864
+ function go2(v, d = 0) {
9865
+ if (Array.isArray(v)) {
9866
+ if (seen.has(v))
9867
+ return CIRCULAR;
9868
+ seen.add(v);
9869
+ return `[${v.map((x) => go2(x, d)).join(",")}]`;
9870
+ }
9871
+ if (isDate(v))
9872
+ return formatDate(v);
9873
+ if (hasProperty(v, "toString") && isFunction2(v["toString"]) && v["toString"] !== Object.prototype.toString && v["toString"] !== Array.prototype.toString) {
9874
+ const s = safeToString(v);
9875
+ if (v instanceof Error && v.cause) {
9876
+ return `${s} (cause: ${go2(v.cause, d)})`;
9877
+ }
9878
+ return s;
9879
+ }
9880
+ if (isString(v))
9881
+ return JSON.stringify(v);
9882
+ if (isNumber(v) || v == null || isBoolean(v) || isSymbol(v))
9883
+ return String(v);
9884
+ if (isBigInt(v))
9885
+ return String(v) + "n";
9886
+ if (v instanceof Set || v instanceof Map) {
9887
+ if (seen.has(v))
9888
+ return CIRCULAR;
9889
+ seen.add(v);
9890
+ return `${v.constructor.name}(${go2(Array.from(v), d)})`;
9891
+ }
9892
+ if (isObject(v)) {
9893
+ if (seen.has(v))
9894
+ return CIRCULAR;
9895
+ seen.add(v);
9896
+ const keys5 = ownKeys(v);
9897
+ {
9898
+ const body2 = `{${keys5.map((k) => `${formatPropertyKey(k)}:${go2(v[k], d)}`).join(",")}}`;
9899
+ return wrap(v, body2);
9900
+ }
9901
+ }
9902
+ return String(v);
9903
+ }
9904
+ return go2(input, 0);
9825
9905
  }
9826
- function removeGlobal(configFile, configKey) {
9827
- const raw = readRawConfig(configFile);
9828
- delete raw[configKey];
9829
- saveRawConfig(configFile, raw);
9906
+ function copy2(src, srcPos, dest, destPos, len) {
9907
+ for (let i = srcPos;i < Math.min(src.length, srcPos + len); i++) {
9908
+ dest[destPos + i - srcPos] = src[i];
9909
+ }
9910
+ return dest;
9830
9911
  }
9831
- function saveRawConfig(configFile, raw) {
9832
- mkdirSync8(dirname8(configFile), { recursive: true });
9833
- writeFileSync7(configFile, `${JSON.stringify(raw, null, 2)}
9834
- `);
9912
+ function popcount(x) {
9913
+ x -= x >> 1 & 1431655765;
9914
+ x = (x & 858993459) + (x >> 2 & 858993459);
9915
+ x = x + (x >> 4) & 252645135;
9916
+ x += x >> 8;
9917
+ x += x >> 16;
9918
+ return x & 127;
9835
9919
  }
9836
- function updateStepModel(ctx, input, configFile, io) {
9837
- const step = input.key.slice("stepModels.".length);
9838
- if (!STEP_SET.has(step))
9839
- throw new InvalidInputError(`unknown model step: ${step}`);
9840
- const modelStep = step;
9841
- let value = null;
9842
- if (input.value !== null) {
9843
- const parsed = z5.string().min(1).safeParse(input.value);
9844
- if (!parsed.success) {
9845
- throw new InvalidInputError(`invalid value for ${input.key}: ${parsed.error.issues[0]?.message}`);
9846
- }
9847
- value = parsed.data;
9920
+ function hashFragment(shift2, h) {
9921
+ return h >>> shift2 & MASK;
9922
+ }
9923
+ function toBitmap(x) {
9924
+ return 1 << x;
9925
+ }
9926
+ function fromBitmap(bitmap, bit) {
9927
+ return popcount(bitmap & bit - 1);
9928
+ }
9929
+ function arrayUpdate(mutate5, at, v, arr) {
9930
+ let out = arr;
9931
+ if (!mutate5) {
9932
+ const len = arr.length;
9933
+ out = new Array(len);
9934
+ for (let i = 0;i < len; ++i)
9935
+ out[i] = arr[i];
9848
9936
  }
9849
- writeStepModel(configFile, modelStep, value);
9850
- const stepModels = ctx.config.stepModels ?? {};
9851
- if (value === null)
9852
- delete stepModels[modelStep];
9853
- else
9854
- stepModels[modelStep] = value;
9855
- ctx.config.stepModels = stepModels;
9856
- emitProject(ctx, GLOBAL_EVENT_KEY, {
9857
- type: "settings.updated",
9858
- message: value === null ? `${input.key} override cleared` : `${input.key} set to ${value}`,
9859
- data: { key: input.key, scope: "global", value }
9860
- });
9861
- return field(getSettings(ctx, input.projectId, io), input.key);
9937
+ out[at] = v;
9938
+ return out;
9862
9939
  }
9863
- function writeStepModel(configFile, step, value) {
9864
- const raw = readRawConfig(configFile);
9865
- const stepModels = { ...rawStepModels(raw) };
9866
- if (value === null)
9867
- delete stepModels[step];
9868
- else
9869
- stepModels[step] = value;
9870
- raw.stepModels = stepModels;
9871
- saveRawConfig(configFile, raw);
9940
+ function arraySpliceOut(mutate5, at, arr) {
9941
+ const newLen = arr.length - 1;
9942
+ let i = 0;
9943
+ let g = 0;
9944
+ let out = arr;
9945
+ if (mutate5) {
9946
+ i = g = at;
9947
+ } else {
9948
+ out = new Array(newLen);
9949
+ while (i < at)
9950
+ out[g++] = arr[i++];
9951
+ }
9952
+ ++i;
9953
+ while (i <= newLen)
9954
+ out[g++] = arr[i++];
9955
+ if (mutate5) {
9956
+ out.length = newLen;
9957
+ }
9958
+ return out;
9872
9959
  }
9873
- function warnLegacyGlobalImage(ctx) {
9874
- const legacy = legacyGlobalImage(ctx.config.sandboxImage, allProjects(ctx).map((p) => p.id));
9875
- if (legacy === null)
9876
- return null;
9877
- const message = legacyGlobalImageReason(legacy);
9878
- console.warn(`runcastle: ${message}`);
9879
- emitProject(ctx, GLOBAL_EVENT_KEY, {
9880
- type: "settings.legacyImage",
9881
- message,
9882
- data: { key: "sandboxImage", scope: "global", value: legacy }
9883
- });
9884
- return legacy;
9960
+ function arraySpliceIn(mutate5, at, v, arr) {
9961
+ const len = arr.length;
9962
+ if (mutate5) {
9963
+ let i2 = len;
9964
+ while (i2 >= at)
9965
+ arr[i2--] = arr[i2];
9966
+ arr[at] = v;
9967
+ return arr;
9968
+ }
9969
+ let i = 0, g = 0;
9970
+ const out = new Array(len + 1);
9971
+ while (i < at)
9972
+ out[g++] = arr[i++];
9973
+ out[at] = v;
9974
+ while (i < len)
9975
+ out[++g] = arr[i++];
9976
+ return out;
9885
9977
  }
9886
- function field(view, key) {
9887
- const f = view.fields.find((x) => x.key === key);
9888
- if (!f)
9889
- throw new InvalidInputError(`setting ${key} not visible in this scope`);
9890
- return f;
9891
- }
9892
- var GLOBAL_EVENT_KEY = "global", idEnv = (raw) => raw, DESCRIPTORS, DEFAULTS, GLOBAL_CLEARABLE_KEYS, STEP_SET;
9893
- var init_settings = __esm(() => {
9894
- init_src();
9895
- init_config_load();
9896
- init_paths();
9897
- init_model_discovery();
9898
- init_schema();
9899
- init_errors();
9900
- init_events();
9901
- init_findings();
9902
- init_repo();
9903
- init_sandbox_image();
9904
- DESCRIPTORS = [
9905
- {
9906
- key: "serverPort",
9907
- configKey: "serverPort",
9908
- envVar: "RUNCASTLE_SERVER_PORT",
9909
- restartRequired: true,
9910
- valueSchema: z5.number().int().positive(),
9911
- parseEnv: (raw) => Number(raw)
9912
- },
9913
- {
9914
- key: "model",
9915
- configKey: "model",
9916
- envVar: "RUNCASTLE_MODEL",
9917
- projectColumn: "model",
9918
- restartRequired: false,
9919
- valueSchema: z5.string().min(1),
9920
- parseEnv: idEnv
9921
- },
9922
- {
9923
- key: "models",
9924
- configKey: "models",
9925
- restartRequired: false,
9926
- valueSchema: z5.array(ModelEntry),
9927
- parseEnv: idEnv
9928
- },
9929
- {
9930
- key: "sandbox",
9931
- configKey: "sandbox",
9932
- envVar: "RUNCASTLE_SANDBOX",
9933
- projectColumn: "sandbox",
9934
- restartRequired: false,
9935
- valueSchema: z5.enum(["docker", "podman", "noSandbox"]),
9936
- parseEnv: idEnv
9937
- },
9938
- {
9939
- key: "sandboxImage",
9940
- configKey: "sandboxImage",
9941
- envVar: "RUNCASTLE_SANDBOX_IMAGE",
9942
- projectColumn: "sandboxImage",
9943
- restartRequired: false,
9944
- valueSchema: z5.string().min(1),
9945
- parseEnv: idEnv
9946
- },
9947
- {
9948
- key: "sessionMcp",
9949
- configKey: "sessionMcp",
9950
- envVar: "RUNCASTLE_SESSION_MCP",
9951
- restartRequired: false,
9952
- valueSchema: z5.enum(["inherit", "runcastleOnly"]),
9953
- parseEnv: idEnv
9954
- },
9955
- {
9956
- key: "burnConcurrency",
9957
- configKey: "burnConcurrency",
9958
- envVar: "RUNCASTLE_BURN_CONCURRENCY",
9959
- restartRequired: false,
9960
- valueSchema: z5.number().int().min(1).max(8),
9961
- parseEnv: (raw) => Number(raw)
9962
- },
9963
- {
9964
- key: "burnMaxIterations",
9965
- configKey: "burnMaxIterations",
9966
- envVar: "RUNCASTLE_BURN_MAX_ITERATIONS",
9967
- restartRequired: false,
9968
- valueSchema: z5.number().int().min(1).max(10),
9969
- parseEnv: (raw) => Number(raw)
9970
- },
9971
- {
9972
- key: "burnAttempts",
9973
- configKey: "burnAttempts",
9974
- envVar: "RUNCASTLE_BURN_ATTEMPTS",
9975
- restartRequired: false,
9976
- valueSchema: z5.number().int().min(1).max(5),
9977
- parseEnv: (raw) => Number(raw)
9978
- },
9979
- {
9980
- key: "burnConflictAttempts",
9981
- configKey: "burnConflictAttempts",
9982
- envVar: "RUNCASTLE_BURN_CONFLICT_ATTEMPTS",
9983
- restartRequired: false,
9984
- valueSchema: z5.number().int().min(0).max(3),
9985
- parseEnv: (raw) => Number(raw)
9986
- },
9987
- {
9988
- key: "burnCpus",
9989
- configKey: "burnCpus",
9990
- envVar: "RUNCASTLE_BURN_CPUS",
9991
- restartRequired: false,
9992
- valueSchema: z5.number().positive().max(256),
9993
- parseEnv: (raw) => Number(raw)
9994
- },
9995
- {
9996
- key: "setupCommand",
9997
- configKey: "setupCommand",
9998
- envVar: "RUNCASTLE_SETUP_COMMAND",
9999
- projectColumn: "setupCommand",
10000
- restartRequired: false,
10001
- valueSchema: z5.string().min(1),
10002
- parseEnv: idEnv
10003
- },
10004
- {
10005
- key: "verifyCommands",
10006
- configKey: "verifyCommands",
10007
- envVar: "RUNCASTLE_VERIFY_COMMANDS",
10008
- projectColumn: "verifyCommands",
10009
- restartRequired: false,
10010
- valueSchema: z5.string().min(1),
10011
- parseEnv: idEnv
10012
- },
10013
- {
10014
- key: "knownFailures",
10015
- configKey: "knownFailures",
10016
- envVar: "RUNCASTLE_KNOWN_FAILURES",
10017
- projectColumn: "knownFailures",
10018
- restartRequired: false,
10019
- valueSchema: z5.string().min(1),
10020
- parseEnv: idEnv
10021
- },
10022
- {
10023
- key: "devCommand",
10024
- projectColumn: "devCommand",
10025
- restartRequired: false,
10026
- valueSchema: z5.string().min(1),
10027
- parseEnv: idEnv
10028
- },
10029
- {
10030
- key: "sessionBranch",
10031
- projectColumn: "sessionBranch",
10032
- restartRequired: false,
10033
- valueSchema: z5.string().min(1),
10034
- parseEnv: idEnv
10035
- },
10036
- {
10037
- key: "docsCommitPrefix",
10038
- projectColumn: "docsCommitPrefix",
10039
- restartRequired: false,
10040
- valueSchema: z5.string().min(1),
10041
- parseEnv: idEnv,
10042
- defaultValue: DEFAULT_DOCS_COMMIT_PREFIX
10043
- },
10044
- {
10045
- key: "dbResetCommand",
10046
- projectColumn: "dbResetCommand",
10047
- restartRequired: false,
10048
- valueSchema: z5.string().min(1),
10049
- parseEnv: idEnv
10050
- },
10051
- {
10052
- key: "driveSetupCommand",
10053
- projectColumn: "driveSetupCommand",
10054
- restartRequired: false,
10055
- valueSchema: z5.string().min(1),
10056
- parseEnv: idEnv
10057
- },
10058
- {
10059
- key: "driveStopCommand",
10060
- projectColumn: "driveStopCommand",
10061
- restartRequired: false,
10062
- valueSchema: z5.string().min(1),
10063
- parseEnv: idEnv
10064
- },
10065
- {
10066
- key: "driveInstructions",
10067
- projectColumn: "driveInstructions",
10068
- restartRequired: false,
10069
- valueSchema: z5.string().min(1),
10070
- parseEnv: idEnv
10071
- },
10072
- {
10073
- key: "scenarioRunner",
10074
- projectColumn: "scenarioRunner",
10075
- restartRequired: false,
10076
- valueSchema: z5.string().min(1),
10077
- parseEnv: idEnv
10078
- }
10079
- ];
10080
- DEFAULTS = RuncastleConfig.parse({});
10081
- GLOBAL_CLEARABLE_KEYS = new Set(["sandboxImage"]);
10082
- STEP_SET = new Set(MODEL_STEPS);
10083
- });
10084
-
10085
- // src/services/setup.ts
10086
- import { copyFileSync as copyFileSync2, existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync12, readdirSync as readdirSync6, writeFileSync as writeFileSync8 } from "fs";
10087
- import { dirname as dirname9, join as join17 } from "path";
10088
- async function writeGitIdentity(exec, identity) {
10089
- const name = identity.name.trim();
10090
- const email = identity.email.trim();
10091
- if (name.length === 0)
10092
- throw new InvalidInputError("git user.name cannot be empty");
10093
- if (!email.includes("@"))
10094
- throw new InvalidInputError("git user.email must be an email address");
10095
- await exec("git", ["config", "--global", "user.name", name]);
10096
- await exec("git", ["config", "--global", "user.email", email]);
10097
- return gitIdentityProbe(exec);
10098
- }
10099
- function upsertEnvVar(content, key, value) {
10100
- const line = `${key}=${value}`;
10101
- const lines2 = content.length === 0 ? [] : content.replace(/\n$/, "").split(`
10102
- `);
10103
- const matcher = new RegExp(`^(export\\s+)?${key}=`);
10104
- let replaced = false;
10105
- const next = lines2.map((l) => {
10106
- if (matcher.test(l)) {
10107
- replaced = true;
10108
- const exportPrefix = l.startsWith("export ") ? "export " : "";
10109
- return `${exportPrefix}${line}`;
10110
- }
10111
- return l;
10112
- });
10113
- if (!replaced)
10114
- next.push(line);
10115
- return `${next.join(`
10116
- `)}
10117
- `;
10118
- }
10119
- async function saveAfkCredential(io, rawValue, runtime = DEFAULT_RUNTIME) {
10120
- const spec = RUNTIME_SPECS[runtime];
10121
- const value = rawValue.trim();
10122
- if (value.length === 0)
10123
- throw new InvalidInputError(`${spec.label} ${spec.afkNoun} cannot be empty`);
10124
- if (/[\r\n]/.test(value)) {
10125
- throw new InvalidInputError(`${spec.label} ${spec.afkNoun} cannot contain a newline`);
10126
- }
10127
- io.write(upsertEnvVar(io.read(), spec.afkKey, value));
10128
- return io.verify(value);
10129
- }
10130
- function seedRuntimeFor(ready) {
10131
- return ready.includes(DEFAULT_RUNTIME) ? DEFAULT_RUNTIME : ready[0];
10132
- }
10133
- function seedModelDefaults(ctx, ready, io = {}) {
10134
- const runtime = seedRuntimeFor(ready);
10135
- if (!runtime)
10136
- return null;
10137
- const pair = RUNTIME_DEFAULT_MODELS[runtime];
10138
- const write = (key, value) => {
10139
- try {
10140
- updateSettings(ctx, { key, value }, io);
10141
- return value;
10142
- } catch (err) {
10143
- if (err instanceof InvalidInputError)
10144
- return;
10145
- throw err;
10146
- }
10147
- };
10148
- const model = write("model", pair.flagship);
10149
- const smoke = write("stepModels.smoke", pair.smoke);
10150
- return {
10151
- runtime,
10152
- ...model ? { model } : {},
10153
- ...smoke ? { smoke } : {}
10154
- };
10155
- }
10156
- function runtimeInstallGuide(platform) {
10157
- switch (platform) {
10158
- case "win32":
10159
- return {
10160
- command: "winget install RedHat.Podman",
10161
- note: "Then initialize the VM: podman machine init && podman machine start"
10162
- };
10163
- case "darwin":
10164
- return {
10165
- command: "brew install podman",
10166
- note: "Then initialize the VM: podman machine init && podman machine start"
10167
- };
10168
- default:
10169
- return {
10170
- command: "sudo apt install podman # or: sudo dnf install podman / sudo pacman -S podman",
10171
- note: "Podman is rootless on Linux \u2014 no machine step needed."
10172
- };
10173
- }
10174
- }
10175
- async function resolveRuntime(exec, preferred) {
10176
- const present = async (bin) => {
10177
- const out = await exec(bin, ["--version"]);
10178
- return out.ok && out.code === 0;
10179
- };
10180
- if (await present(preferred))
10181
- return preferred;
10182
- const other = preferred === "docker" ? "podman" : "docker";
10183
- if (await present(other))
10184
- return other;
10185
- return preferred;
10186
- }
10187
- function terminalSpec(kind) {
10188
- if (kind === "setup-token")
10189
- return { cmd: "claude", args: ["setup-token"] };
10190
- for (const spec of Object.values(RUNTIME_SPECS)) {
10191
- if (kind === LOGIN_TERMINAL_KIND[spec.runtime])
10192
- return { cmd: spec.bin, args: spec.loginArgs };
10193
- }
10194
- throw new InvalidInputError(`no terminal command for ${kind}`);
10195
- }
10196
- function refreshSandcastleConfig(templateDir, targetDir) {
10197
- const dir = join17(targetDir, ".sandcastle");
10198
- mkdirSync9(dir, { recursive: true });
10199
- for (const name of readdirSync6(templateDir)) {
10200
- copyFileSync2(join17(templateDir, name), join17(dir, name));
10201
- }
10202
- return dir;
10203
- }
10204
- function prepareSandboxBuildContext(templateDir = sandcastleTemplateDir(), target = sandboxBuildDir()) {
10205
- mkdirSync9(target, { recursive: true });
10206
- return refreshSandcastleConfig(templateDir, target);
10207
- }
10208
- function createCredentialVerifier(exec, runtime = DEFAULT_RUNTIME) {
10209
- const spec = RUNTIME_SPECS[runtime];
10210
- return async (value) => {
10211
- if (value.length < 8) {
10212
- return {
10213
- valid: false,
10214
- detail: `${spec.afkNoun} looks malformed (too short) \u2014 saved to ~/.runcastle/.env anyway`,
10215
- fix: `${spec.afkFix}. It starts with \`sk-\`.`
10216
- };
10217
- }
10218
- const out = await exec(spec.bin, ["--version"]);
10219
- if (!out.ok) {
10220
- return {
10221
- valid: false,
10222
- detail: `${spec.afkNoun} saved to ~/.runcastle/.env, but runcastle could not launch \`${spec.bin}\` to verify it. ` + "That is a PATH problem in this server process, not a missing install \u2014 a terminal that finds " + `\`${spec.bin}\` proves nothing about the PATH runcastle was started with.`,
10223
- fix: `Quit runcastle and start it again from a terminal where \`${spec.bin} --version\` works. ` + `If it still fails, pin the path: set ${spec.binOverrideEnv} to the full path from ` + `\`where.exe ${spec.bin}\` (Windows) or \`which ${spec.bin}\` (macOS/Linux), then restart runcastle.`
10224
- };
10225
- }
10226
- if (out.code !== 0) {
10227
- const why = (out.stderr.trim() || out.stdout.trim()).split(`
10228
- `)[0] ?? "";
10229
- return {
10230
- valid: false,
10231
- detail: `${spec.afkNoun} saved to ~/.runcastle/.env, but \`${spec.bin} --version\` exited ${out.code}` + `${why ? `: ${why}` : " with no output"}.`,
10232
- fix: `Run \`${spec.bin} --version\` yourself and fix what it reports \u2014 the ${spec.label} install is broken, not the ${spec.afkNoun}.`
10233
- };
10234
- }
10235
- return { valid: true, detail: `${spec.afkNoun} captured to ~/.runcastle/.env` };
10236
- };
10237
- }
10238
- function fileAfkTokenIo(exec, runtime = DEFAULT_RUNTIME) {
10239
- const path = envPath();
10240
- return {
10241
- read: () => existsSync16(path) ? readFileSync12(path, "utf8") : "",
10242
- write: (content) => {
10243
- mkdirSync9(dirname9(path), { recursive: true });
10244
- writeFileSync8(path, content, "utf8");
10245
- },
10246
- verify: createCredentialVerifier(exec, runtime)
10247
- };
10248
- }
10249
- var AFK_TOKEN_KEY, CODEX_API_KEY, RUNTIME_AUTH_KEY, RUNTIME_AUTH_SETUP_HINT, LOGIN_TERMINAL_KIND;
10250
- var init_setup = __esm(() => {
10251
- init_src();
10252
- init_paths();
10253
- init_doctor();
10254
- init_errors();
10255
- init_asset_paths();
10256
- init_settings();
10257
- AFK_TOKEN_KEY = RUNTIME_SPECS["claude-code"].afkKey;
10258
- CODEX_API_KEY = RUNTIME_SPECS.codex.afkKey;
10259
- RUNTIME_AUTH_KEY = {
10260
- "claude-code": AFK_TOKEN_KEY,
10261
- codex: CODEX_API_KEY
10262
- };
10263
- RUNTIME_AUTH_SETUP_HINT = {
10264
- "claude-code": RUNTIME_SPECS["claude-code"].afkFix,
10265
- codex: `Run \`${RUNTIME_SPECS.codex.loginCommand}\` on this host, then burn again`
10266
- };
10267
- LOGIN_TERMINAL_KIND = {
10268
- "claude-code": "claude-login",
10269
- codex: "codex-login"
10270
- };
10271
- });
10272
-
10273
- // src/services/agent-stream.ts
10274
- function beginTranscript(ticketId) {
10275
- transcripts.set(ticketId, { live: true, chunks: [], nextIndex: 0, bytes: 0 });
10276
- publishLive({ kind: "transcript", ticketId });
10277
- }
10278
- function appendTranscript(ticketId, chunk) {
10279
- const t = transcripts.get(ticketId);
10280
- if (!t)
10281
- return;
10282
- const full = { ...chunk, i: t.nextIndex, ts: chunk.ts ?? Date.now() };
10283
- t.nextIndex += 1;
10284
- t.chunks.push(full);
10285
- t.bytes += full.text.length;
10286
- while (t.chunks.length > MAX_CHUNKS || t.bytes > MAX_BYTES && t.chunks.length > 1) {
10287
- const dropped = t.chunks.shift();
10288
- if (!dropped)
10289
- break;
10290
- t.bytes -= dropped.text.length;
10291
- }
10292
- publishLive({ kind: "transcript", ticketId });
10293
- }
10294
- function endTranscript(ticketId) {
10295
- const t = transcripts.get(ticketId);
10296
- if (t)
10297
- t.live = false;
10298
- publishLive({ kind: "transcript", ticketId });
10299
- }
10300
- function readTranscript(ticketId, after = -1) {
10301
- const t = transcripts.get(ticketId);
10302
- if (!t)
10303
- return { live: false, chunks: [], firstIndex: 0, nextIndex: 0 };
10304
- return {
10305
- live: t.live,
10306
- chunks: after < 0 ? [...t.chunks] : t.chunks.filter((c) => c.i > after),
10307
- firstIndex: t.chunks[0]?.i ?? t.nextIndex,
10308
- nextIndex: t.nextIndex
10309
- };
10310
- }
10311
- var MAX_CHUNKS = 4000, MAX_BYTES = 1500000, transcripts;
10312
- var init_agent_stream = __esm(() => {
10313
- init_bus();
10314
- transcripts = new Map;
10315
- });
10316
-
10317
- // ../../node_modules/.bun/@ai-hero+sandcastle@0.12.0/node_modules/@ai-hero/sandcastle/dist/chunk-NGBM7T3E.js
10318
- import { createRequire as createRequire4 } from "module";
10319
- var require$1, __create, __defProp2, __getOwnPropDesc, __getOwnPropNames, __getProtoOf, __hasOwnProp, __require2, __commonJS = (cb, mod) => function __require22() {
10320
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10321
- }, __export2 = (target, all) => {
10322
- for (var name in all)
10323
- __defProp2(target, name, { get: all[name], enumerable: true });
10324
- }, __copyProps = (to, from, except, desc5) => {
10325
- if (from && typeof from === "object" || typeof from === "function") {
10326
- for (let key of __getOwnPropNames(from))
10327
- if (!__hasOwnProp.call(to, key) && key !== except)
10328
- __defProp2(to, key, { get: () => from[key], enumerable: !(desc5 = __getOwnPropDesc(from, key)) || desc5.enumerable });
10329
- }
10330
- return to;
10331
- }, __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")), __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)), MAX_TAIL_CHARS, BoundedTail = class {
10332
- items = [];
10333
- totalChars = 0;
10334
- maxChars;
10335
- separator;
10336
- constructor(maxChars = MAX_TAIL_CHARS, separator = "") {
10337
- this.maxChars = maxChars;
10338
- this.separator = separator;
10339
- }
10340
- push(item) {
10341
- const bounded = item.length > this.maxChars ? item.slice(item.length - this.maxChars) : item;
10342
- this.totalChars += bounded.length + (this.items.length > 0 ? this.separator.length : 0);
10343
- this.items.push(bounded);
10344
- while (this.totalChars > this.maxChars && this.items.length > 1) {
10345
- const dropped = this.items.shift();
10346
- this.totalChars -= dropped.length + this.separator.length;
10347
- }
10348
- }
10349
- toString() {
10350
- return this.items.join(this.separator);
10351
- }
10352
- }, elidePayloadTokens = (command) => command.replace(/'[A-Za-z0-9+\/=]{120,}'/g, "'\u2026'"), formatExecFailureMessage = (command, result, maxTailChars = MAX_TAIL_CHARS) => {
10353
- const output = [result.stdout, result.stderr].map((stream) => (stream ?? "").trimEnd()).filter((stream) => stream.length > 0).join(`
10354
- `);
10355
- const tail = output.length > maxTailChars ? output.slice(output.length - maxTailChars) : output;
10356
- const headline = `Command failed (exit ${result.exitCode}): ${elidePayloadTokens(command)}`;
10357
- return tail ? `${headline}
10358
- ${tail}` : headline;
10359
- };
10360
- var init_chunk_NGBM7T3E = __esm(() => {
10361
- require$1 = createRequire4(import.meta.url);
10362
- __create = Object.create;
10363
- __defProp2 = Object.defineProperty;
10364
- __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10365
- __getOwnPropNames = Object.getOwnPropertyNames;
10366
- __getProtoOf = Object.getPrototypeOf;
10367
- __hasOwnProp = Object.prototype.hasOwnProperty;
10368
- __require2 = /* @__PURE__ */ ((x) => typeof require$1 !== "undefined" ? require$1 : typeof Proxy !== "undefined" ? new Proxy(x, {
10369
- get: (a, b) => (typeof require$1 !== "undefined" ? require$1 : a)[b]
10370
- }) : x)(function(x) {
10371
- if (typeof require$1 !== "undefined")
10372
- return require$1.apply(this, arguments);
10373
- throw Error('Dynamic require of "' + x + '" is not supported');
10374
- });
10375
- MAX_TAIL_CHARS = 64 * 1024;
10376
- });
10377
-
10378
- // ../../node_modules/.bun/@ai-hero+sandcastle@0.12.0/node_modules/@ai-hero/sandcastle/dist/chunk-VOG34SRF.js
10379
- import { createRequire as createRequire5 } from "module";
10380
- import * as clack from "@clack/prompts";
10381
- import { join as join$1, basename as basename3, dirname as dirname10, resolve as resolve10, posix as posix2, normalize, isAbsolute as isAbsolute2 } from "path";
10382
- import { styleText, promisify } from "util";
10383
- import { existsSync as existsSync17, statSync as statSync5 } from "fs";
10384
- import { tmpdir as tmpdir2, homedir as homedir3 } from "os";
10385
- import { mkdtemp, writeFile, mkdir, readFile as readFile2, rm, readdir, stat } from "fs/promises";
10386
- import { exec, execFile } from "child_process";
10387
- import { randomBytes as randomBytes2 } from "crypto";
10388
- function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
10389
- switch (arguments.length) {
10390
- case 1:
10391
- return a;
10392
- case 2:
10393
- return ab(a);
10394
- case 3:
10395
- return bc(ab(a));
10396
- case 4:
10397
- return cd(bc(ab(a)));
10398
- case 5:
10399
- return de(cd(bc(ab(a))));
10400
- case 6:
10401
- return ef(de(cd(bc(ab(a)))));
10402
- case 7:
10403
- return fg(ef(de(cd(bc(ab(a))))));
10404
- case 8:
10405
- return gh(fg(ef(de(cd(bc(ab(a)))))));
10406
- case 9:
10407
- return hi(gh(fg(ef(de(cd(bc(ab(a))))))));
10408
- default: {
10409
- let ret = arguments[0];
10410
- for (let i = 1;i < arguments.length; i++) {
10411
- ret = arguments[i](ret);
10412
- }
10413
- return ret;
10414
- }
10415
- }
10416
- }
10417
- function mul64(out, aHi, aLo, bHi, bLo) {
10418
- let c1 = (aLo >>> 16) * (bLo & 65535) >>> 0;
10419
- let c0 = (aLo & 65535) * (bLo >>> 16) >>> 0;
10420
- let lo = (aLo & 65535) * (bLo & 65535) >>> 0;
10421
- let hi = (aLo >>> 16) * (bLo >>> 16) + ((c0 >>> 16) + (c1 >>> 16)) >>> 0;
10422
- c0 = c0 << 16 >>> 0;
10423
- lo = lo + c0 >>> 0;
10424
- if (lo >>> 0 < c0 >>> 0) {
10425
- hi = hi + 1 >>> 0;
10426
- }
10427
- c1 = c1 << 16 >>> 0;
10428
- lo = lo + c1 >>> 0;
10429
- if (lo >>> 0 < c1 >>> 0) {
10430
- hi = hi + 1 >>> 0;
10431
- }
10432
- hi = hi + Math.imul(aLo, bHi) >>> 0;
10433
- hi = hi + Math.imul(aHi, bLo) >>> 0;
10434
- out[0] = hi;
10435
- out[1] = lo;
10436
- }
10437
- function add64(out, aHi, aLo, bHi, bLo) {
10438
- let hi = aHi + bHi >>> 0;
10439
- const lo = aLo + bLo >>> 0;
10440
- if (lo >>> 0 < aLo >>> 0) {
10441
- hi = hi + 1 | 0;
10442
- }
10443
- out[0] = hi;
10444
- out[1] = lo;
10445
- }
10446
- function yieldWrapGet(self) {
10447
- if (typeof self === "object" && self !== null && YieldWrapTypeId in self) {
10448
- return self[YieldWrapTypeId]();
10449
- }
10450
- throw new Error(getBugErrorMessage("yieldWrapGet"));
10451
- }
10452
- function equals() {
10453
- if (arguments.length === 1) {
10454
- return (self) => compareBoth(self, arguments[0]);
10455
- }
10456
- return compareBoth(arguments[0], arguments[1]);
10457
- }
10458
- function compareBoth(self, that) {
10459
- if (self === that) {
10460
- return true;
10461
- }
10462
- const selfType = typeof self;
10463
- if (selfType !== typeof that) {
10464
- return false;
10465
- }
10466
- if (selfType === "object" || selfType === "function") {
10467
- if (self !== null && that !== null) {
10468
- if (isEqual(self) && isEqual(that)) {
10469
- if (hash(self) === hash(that) && self[symbol2](that)) {
10470
- return true;
10471
- } else {
10472
- return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
10473
- }
10474
- } else if (self instanceof Date && that instanceof Date) {
10475
- const t1 = self.getTime();
10476
- const t2 = that.getTime();
10477
- return t1 === t2 || Number.isNaN(t1) && Number.isNaN(t2);
10478
- } else if (self instanceof URL && that instanceof URL) {
10479
- return self.href === that.href;
10480
- }
10481
- }
10482
- if (structuralRegionState.enabled) {
10483
- if (Array.isArray(self) && Array.isArray(that)) {
10484
- return self.length === that.length && self.every((v, i) => compareBoth(v, that[i]));
10485
- }
10486
- if (Object.getPrototypeOf(self) === Object.prototype && Object.getPrototypeOf(that) === Object.prototype) {
10487
- const keysSelf = Object.keys(self);
10488
- const keysThat = Object.keys(that);
10489
- if (keysSelf.length === keysThat.length) {
10490
- for (const key of keysSelf) {
10491
- if (!((key in that) && compareBoth(self[key], that[key]))) {
10492
- return structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
10493
- }
10494
- }
10495
- return true;
10496
- }
10497
- }
10498
- return structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
10499
- }
10500
- }
10501
- return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
10502
- }
10503
- function formatDate(date2) {
10504
- try {
10505
- return date2.toISOString();
10506
- } catch {
10507
- return "Invalid Date";
10508
- }
10509
- }
10510
- function safeToString(input) {
10511
- try {
10512
- const s = input.toString();
10513
- return typeof s === "string" ? s : String(s);
10514
- } catch {
10515
- return "[toString threw]";
10516
- }
10517
- }
10518
- function formatPropertyKey(name) {
10519
- return isString(name) ? JSON.stringify(name) : String(name);
10520
- }
10521
- function formatUnknown(input, options) {
10522
- const seen = /* @__PURE__ */ new WeakSet;
10523
- const wrap = (v, body) => {
10524
- const ctor = v?.constructor;
10525
- return ctor && ctor !== Object.prototype.constructor && ctor.name ? `${ctor.name}(${body})` : body;
10526
- };
10527
- const ownKeys = (o) => {
10528
- try {
10529
- return Reflect.ownKeys(o);
10530
- } catch {
10531
- return ["[ownKeys threw]"];
10532
- }
10533
- };
10534
- function go2(v, d = 0) {
10535
- if (Array.isArray(v)) {
10536
- if (seen.has(v))
10537
- return CIRCULAR;
10538
- seen.add(v);
10539
- return `[${v.map((x) => go2(x, d)).join(",")}]`;
10540
- }
10541
- if (isDate(v))
10542
- return formatDate(v);
10543
- if (hasProperty(v, "toString") && isFunction2(v["toString"]) && v["toString"] !== Object.prototype.toString && v["toString"] !== Array.prototype.toString) {
10544
- const s = safeToString(v);
10545
- if (v instanceof Error && v.cause) {
10546
- return `${s} (cause: ${go2(v.cause, d)})`;
10547
- }
10548
- return s;
10549
- }
10550
- if (isString(v))
10551
- return JSON.stringify(v);
10552
- if (isNumber(v) || v == null || isBoolean(v) || isSymbol(v))
10553
- return String(v);
10554
- if (isBigInt(v))
10555
- return String(v) + "n";
10556
- if (v instanceof Set || v instanceof Map) {
10557
- if (seen.has(v))
10558
- return CIRCULAR;
10559
- seen.add(v);
10560
- return `${v.constructor.name}(${go2(Array.from(v), d)})`;
10561
- }
10562
- if (isObject(v)) {
10563
- if (seen.has(v))
10564
- return CIRCULAR;
10565
- seen.add(v);
10566
- const keys5 = ownKeys(v);
10567
- {
10568
- const body2 = `{${keys5.map((k) => `${formatPropertyKey(k)}:${go2(v[k], d)}`).join(",")}}`;
10569
- return wrap(v, body2);
10570
- }
10571
- }
10572
- return String(v);
10573
- }
10574
- return go2(input, 0);
10575
- }
10576
- function copy2(src, srcPos, dest, destPos, len) {
10577
- for (let i = srcPos;i < Math.min(src.length, srcPos + len); i++) {
10578
- dest[destPos + i - srcPos] = src[i];
10579
- }
10580
- return dest;
10581
- }
10582
- function popcount(x) {
10583
- x -= x >> 1 & 1431655765;
10584
- x = (x & 858993459) + (x >> 2 & 858993459);
10585
- x = x + (x >> 4) & 252645135;
10586
- x += x >> 8;
10587
- x += x >> 16;
10588
- return x & 127;
10589
- }
10590
- function hashFragment(shift2, h) {
10591
- return h >>> shift2 & MASK;
10592
- }
10593
- function toBitmap(x) {
10594
- return 1 << x;
10595
- }
10596
- function fromBitmap(bitmap, bit) {
10597
- return popcount(bitmap & bit - 1);
10598
- }
10599
- function arrayUpdate(mutate5, at, v, arr) {
10600
- let out = arr;
10601
- if (!mutate5) {
10602
- const len = arr.length;
10603
- out = new Array(len);
10604
- for (let i = 0;i < len; ++i)
10605
- out[i] = arr[i];
10606
- }
10607
- out[at] = v;
10608
- return out;
10609
- }
10610
- function arraySpliceOut(mutate5, at, arr) {
10611
- const newLen = arr.length - 1;
10612
- let i = 0;
10613
- let g = 0;
10614
- let out = arr;
10615
- if (mutate5) {
10616
- i = g = at;
10617
- } else {
10618
- out = new Array(newLen);
10619
- while (i < at)
10620
- out[g++] = arr[i++];
10621
- }
10622
- ++i;
10623
- while (i <= newLen)
10624
- out[g++] = arr[i++];
10625
- if (mutate5) {
10626
- out.length = newLen;
10627
- }
10628
- return out;
10629
- }
10630
- function arraySpliceIn(mutate5, at, v, arr) {
10631
- const len = arr.length;
10632
- if (mutate5) {
10633
- let i2 = len;
10634
- while (i2 >= at)
10635
- arr[i2--] = arr[i2];
10636
- arr[at] = v;
10637
- return arr;
10638
- }
10639
- let i = 0, g = 0;
10640
- const out = new Array(len + 1);
10641
- while (i < at)
10642
- out[g++] = arr[i++];
10643
- out[at] = v;
10644
- while (i < len)
10645
- out[++g] = arr[i++];
10646
- return out;
10647
- }
10648
- function isEmptyNode(a) {
10649
- return isTagged(a, "EmptyNode");
9978
+ function isEmptyNode(a) {
9979
+ return isTagged(a, "EmptyNode");
10650
9980
  }
10651
9981
  function isLeafNode(node) {
10652
9982
  return isEmptyNode(node) || node._tag === "LeafNode" || node._tag === "CollisionNode";
@@ -10746,8 +10076,8 @@ function taggedMatch() {
10746
10076
  const cases = arguments[1];
10747
10077
  return cases[value5._tag](value5);
10748
10078
  }
10749
- function aliasOrValue(field2, aliases) {
10750
- return aliases?.[field2.toLocaleLowerCase()] ?? Number(field2);
10079
+ function aliasOrValue(field, aliases) {
10080
+ return aliases?.[field.toLocaleLowerCase()] ?? Number(field);
10751
10081
  }
10752
10082
  function defineLength(length3, fn2) {
10753
10083
  return Object.defineProperty(fn2, "length", {
@@ -11072,7 +10402,7 @@ var Effect_exports, isFunction = (input) => typeof input === "function", dual =
11072
10402
  };
11073
10403
  };
11074
10404
  }
11075
- }, identity = (a) => a, constant = (value5) => () => value5, constTrue, constFalse, constNull, constUndefined, constVoid, make = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that), isStrictEquivalent = (x, y) => x === y, strict = () => isStrictEquivalent, number5, mapInput, Date2, array5 = (item) => make((self, that) => {
10405
+ }, identity = (a) => a, constant = (value5) => () => value5, constTrue, constFalse, constNull, constUndefined, constVoid, make = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that), isStrictEquivalent = (x, y) => x === y, strict = () => isStrictEquivalent, number4, mapInput, Date2, array4 = (item) => make((self, that) => {
11076
10406
  if (self.length !== that.length) {
11077
10407
  return false;
11078
10408
  }
@@ -11168,22 +10498,22 @@ var Effect_exports, isFunction = (input) => typeof input === "function", dual =
11168
10498
  case "number":
11169
10499
  return number22(self);
11170
10500
  case "bigint":
11171
- return string5(self.toString(10));
10501
+ return string4(self.toString(10));
11172
10502
  case "boolean":
11173
- return string5(String(self));
10503
+ return string4(String(self));
11174
10504
  case "symbol":
11175
- return string5(String(self));
10505
+ return string4(String(self));
11176
10506
  case "string":
11177
- return string5(self);
10507
+ return string4(self);
11178
10508
  case "undefined":
11179
- return string5("undefined");
10509
+ return string4("undefined");
11180
10510
  case "function":
11181
10511
  case "object": {
11182
10512
  if (self === null) {
11183
- return string5("null");
10513
+ return string4("null");
11184
10514
  } else if (self instanceof Date) {
11185
10515
  if (Number.isNaN(self.getTime())) {
11186
- return string5("Invalid Date");
10516
+ return string4("Invalid Date");
11187
10517
  }
11188
10518
  return hash(self.toISOString());
11189
10519
  } else if (self instanceof URL) {
@@ -11214,7 +10544,7 @@ var Effect_exports, isFunction = (input) => typeof input === "function", dual =
11214
10544
  h ^= n /= 4294967295;
11215
10545
  }
11216
10546
  return optimize(h);
11217
- }, string5 = (str) => {
10547
+ }, string4 = (str) => {
11218
10548
  let h = 5381, i = str.length;
11219
10549
  while (i) {
11220
10550
  h = h * 33 ^ str.charCodeAt(--i);
@@ -11223,7 +10553,7 @@ var Effect_exports, isFunction = (input) => typeof input === "function", dual =
11223
10553
  }, structureKeys = (o, keys5) => {
11224
10554
  let h = 12289;
11225
10555
  for (let i = 0;i < keys5.length; i++) {
11226
- h ^= pipe(string5(keys5[i]), combine(hash(o[keys5[i]])));
10556
+ h ^= pipe(string4(keys5[i]), combine(hash(o[keys5[i]])));
11227
10557
  }
11228
10558
  return optimize(h);
11229
10559
  }, structure = (o) => structureKeys(o, Object.keys(o)), array22 = (arr) => {
@@ -11459,7 +10789,7 @@ var Effect_exports, isFunction = (input) => typeof input === "function", dual =
11459
10789
  next4 = b2;
11460
10790
  }
11461
10791
  return out;
11462
- }, getEquivalence2, dedupeWith, dedupe = (self) => dedupeWith(self, equivalence()), join18, TypeId4, emptyArray, getEquivalence3 = (isEquivalent) => make((self, that) => self.length === that.length && toReadonlyArray(self).every((value5, i) => isEquivalent(value5, unsafeGet2(that, i)))), _equivalence3, ChunkProto, makeChunk = (backing) => {
10792
+ }, getEquivalence2, dedupeWith, dedupe = (self) => dedupeWith(self, equivalence()), join17, TypeId4, emptyArray, getEquivalence3 = (isEquivalent) => make((self, that) => self.length === that.length && toReadonlyArray(self).every((value5, i) => isEquivalent(value5, unsafeGet2(that, i)))), _equivalence3, ChunkProto, makeChunk = (backing) => {
11463
10793
  const chunk4 = Object.create(ChunkProto);
11464
10794
  chunk4.backing = backing;
11465
10795
  switch (backing._tag) {
@@ -11503,26 +10833,26 @@ var Effect_exports, isFunction = (input) => typeof input === "function", dual =
11503
10833
  }, isChunk = (u) => hasProperty(u, TypeId4), _empty, empty3 = () => _empty, make5 = (...as12) => unsafeFromNonEmptyArray(as12), of2 = (a) => makeChunk({
11504
10834
  _tag: "ISingleton",
11505
10835
  a
11506
- }), fromIterable3 = (self) => isChunk(self) ? self : unsafeFromArray(fromIterable2(self)), copyToArray = (self, array52, initial) => {
10836
+ }), fromIterable3 = (self) => isChunk(self) ? self : unsafeFromArray(fromIterable2(self)), copyToArray = (self, array5, initial) => {
11507
10837
  switch (self.backing._tag) {
11508
10838
  case "IArray": {
11509
- copy2(self.backing.array, 0, array52, initial, self.length);
10839
+ copy2(self.backing.array, 0, array5, initial, self.length);
11510
10840
  break;
11511
10841
  }
11512
10842
  case "IConcat": {
11513
- copyToArray(self.left, array52, initial);
11514
- copyToArray(self.right, array52, initial + self.left.length);
10843
+ copyToArray(self.left, array5, initial);
10844
+ copyToArray(self.right, array5, initial + self.left.length);
11515
10845
  break;
11516
10846
  }
11517
10847
  case "ISingleton": {
11518
- array52[initial] = self.backing.a;
10848
+ array5[initial] = self.backing.a;
11519
10849
  break;
11520
10850
  }
11521
10851
  case "ISlice": {
11522
10852
  let i = 0;
11523
10853
  let j = initial;
11524
10854
  while (i < self.length) {
11525
- array52[j] = unsafeGet2(self, i);
10855
+ array5[j] = unsafeGet2(self, i);
11526
10856
  i += 1;
11527
10857
  j += 1;
11528
10858
  }
@@ -13112,7 +12442,7 @@ ${prefix}}`;
13112
12442
  }), constContext, context = () => constContext, contextWithEffect = (f) => flatMap7(context(), f), provideContext, provideSomeContext, mapInputContext, filterEffectOrElse, filterEffectOrFail, currentSpanFromFiber = (fiber) => {
13113
12443
  const span4 = fiber.currentSpan;
13114
12444
  return span4 !== undefined && span4._tag === "Span" ? some2(span4) : none2();
13115
- }, NoopSpanProto, noopSpan = (options) => Object.assign(Object.create(NoopSpanProto), options), ClockSymbolKey = "effect/Clock", ClockTypeId, clockTag, MAX_TIMER_MILLIS, globalClockScheduler, performanceNowNanos, processOrPerformanceNow, ClockImpl, make20 = () => new ClockImpl, Order2, escape = (string52) => string52.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&"), OP_AND = "And", OP_OR = "Or", OP_INVALID_DATA = "InvalidData", OP_MISSING_DATA = "MissingData", OP_SOURCE_UNAVAILABLE = "SourceUnavailable", OP_UNSUPPORTED = "Unsupported", ConfigErrorSymbolKey = "effect/ConfigError", ConfigErrorTypeId, proto2, And = (self, that) => {
12445
+ }, NoopSpanProto, noopSpan = (options) => Object.assign(Object.create(NoopSpanProto), options), ClockSymbolKey = "effect/Clock", ClockTypeId, clockTag, MAX_TIMER_MILLIS, globalClockScheduler, performanceNowNanos, processOrPerformanceNow, ClockImpl, make20 = () => new ClockImpl, Order2, escape = (string5) => string5.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&"), OP_AND = "And", OP_OR = "Or", OP_INVALID_DATA = "InvalidData", OP_MISSING_DATA = "MissingData", OP_SOURCE_UNAVAILABLE = "SourceUnavailable", OP_UNSUPPORTED = "Unsupported", ConfigErrorSymbolKey = "effect/ConfigError", ConfigErrorTypeId, proto2, And = (self, that) => {
13116
12446
  const error3 = Object.create(proto2);
13117
12447
  error3._op = OP_AND;
13118
12448
  error3.left = self;
@@ -13158,7 +12488,7 @@ ${prefix}}`;
13158
12488
  Object.defineProperty(error3, "toString", {
13159
12489
  enumerable: false,
13160
12490
  value() {
13161
- const path2 = pipe(this.path, join18(options.pathDelim));
12491
+ const path2 = pipe(this.path, join17(options.pathDelim));
13162
12492
  return `(Invalid data at ${path2}: "${this.message}")`;
13163
12493
  }
13164
12494
  });
@@ -13173,7 +12503,7 @@ ${prefix}}`;
13173
12503
  Object.defineProperty(error3, "toString", {
13174
12504
  enumerable: false,
13175
12505
  value() {
13176
- const path2 = pipe(this.path, join18(options.pathDelim));
12506
+ const path2 = pipe(this.path, join17(options.pathDelim));
13177
12507
  return `(Missing data at ${path2}: "${this.message}")`;
13178
12508
  }
13179
12509
  });
@@ -13189,7 +12519,7 @@ ${prefix}}`;
13189
12519
  Object.defineProperty(error3, "toString", {
13190
12520
  enumerable: false,
13191
12521
  value() {
13192
- const path2 = pipe(this.path, join18(options.pathDelim));
12522
+ const path2 = pipe(this.path, join17(options.pathDelim));
13193
12523
  return `(Source unavailable at ${path2}: "${this.message}")`;
13194
12524
  }
13195
12525
  });
@@ -13204,7 +12534,7 @@ ${prefix}}`;
13204
12534
  Object.defineProperty(error3, "toString", {
13205
12535
  enumerable: false,
13206
12536
  value() {
13207
- const path2 = pipe(this.path, join18(options.pathDelim));
12537
+ const path2 = pipe(this.path, join17(options.pathDelim));
13208
12538
  return `(Unsupported operation at ${path2}: "${this.message}")`;
13209
12539
  }
13210
12540
  });
@@ -13234,7 +12564,7 @@ ${prefix}}`;
13234
12564
  pathDelim: "_",
13235
12565
  seqDelim: ","
13236
12566
  }, options);
13237
- const makePathString = (path) => pipe(path, join18(pathDelim));
12567
+ const makePathString = (path) => pipe(path, join17(pathDelim));
13238
12568
  const unmakePathString = (pathString) => pathString.split(pathDelim);
13239
12569
  const getEnv = () => typeof process !== "undefined" && ("env" in process) && typeof process.env === "object" ? process.env : {};
13240
12570
  const load = (path, primitive2, split2 = true) => {
@@ -13355,7 +12685,7 @@ ${prefix}}`;
13355
12685
  return fail2(right3.left);
13356
12686
  }
13357
12687
  if (isRight2(left3) && isRight2(right3)) {
13358
- const path = pipe(prefix, join18("."));
12688
+ const path = pipe(prefix, join17("."));
13359
12689
  const fail19 = fromFlatLoopFail(prefix, path);
13360
12690
  const [lefts, rights] = extend(fail19, fail19, pipe(left3.right, map3(right2)), pipe(right3.right, map3(right2)));
13361
12691
  return pipe(lefts, zip(rights), forEachSequential(([left4, right4]) => pipe(zip2(left4, right4), map10(([left5, right5]) => op.zip(left5, right5)))));
@@ -13375,8 +12705,8 @@ ${prefix}}`;
13375
12705
  }));
13376
12706
  }
13377
12707
  return pipe(splitPathString(text2, delimiter), forEachSequential((char) => primitive2.parse(char.trim())), mapError(prefixed(path)));
13378
- }, transpose = (array52) => {
13379
- return Object.keys(array52[0]).map((column) => array52.map((row) => row[column]));
12708
+ }, transpose = (array5) => {
12709
+ return Object.keys(array5[0]).map((column) => array5.map((row) => row[column]));
13380
12710
  }, indicesFrom = (quotedIndices) => pipe(forEachSequential(quotedIndices, parseQuotedIndex), mapBoth2({
13381
12711
  onFailure: () => empty2(),
13382
12712
  onSuccess: sort(Order2)
@@ -13629,7 +12959,7 @@ ${prefix}}`;
13629
12959
  return isMicroExit(that) && that._tag === options.op && equals(this[args], that[args]);
13630
12960
  },
13631
12961
  [symbol]() {
13632
- return cached2(this, combine(string5(options.op))(hash(this[args])));
12962
+ return cached2(this, combine(string4(options.op))(hash(this[args])));
13633
12963
  }
13634
12964
  };
13635
12965
  return function(value5) {
@@ -14955,9 +14285,9 @@ ${prefix}}`;
14955
14285
  return options?.discard !== true && reconcile._tag === "Some" ? map10(forEach7(effects, identity, options), reconcile.value) : forEach7(effects, identity, options);
14956
14286
  }, allWith = (options) => (arg) => all5(arg, options), allSuccesses = (elements, options) => map10(all5(fromIterable2(elements).map(exit), options), filterMap2((exit4) => exitIsSuccess(exit4) ? some2(exit4.effect_instruction_i0) : none2())), replicate, replicateEffect, forEach7, forEachParUnbounded = (self, f, batching) => suspend(() => {
14957
14287
  const as12 = fromIterable2(self);
14958
- const array52 = new Array(as12.length);
14959
- const fn2 = (a, i) => flatMap7(f(a, i), (b) => sync(() => array52[i] = b));
14960
- return zipRight2(forEachConcurrentDiscard(as12, fn2, batching, false), succeed(array52));
14288
+ const array5 = new Array(as12.length);
14289
+ const fn2 = (a, i) => flatMap7(f(a, i), (b) => sync(() => array5[i] = b));
14290
+ return zipRight2(forEachConcurrentDiscard(as12, fn2, batching, false), succeed(array5));
14961
14291
  }), forEachConcurrentDiscard = (self, f, batching, processAll, n) => uninterruptibleMask((restore) => transplant((graft) => withFiberRuntime((parent) => {
14962
14292
  let todos = Array.from(self).reverse();
14963
14293
  let target = todos.length;
@@ -15112,9 +14442,9 @@ ${prefix}}`;
15112
14442
  })));
15113
14443
  }))), forEachParN = (self, n, f, batching) => suspend(() => {
15114
14444
  const as12 = fromIterable2(self);
15115
- const array52 = new Array(as12.length);
15116
- const fn2 = (a, i) => map10(f(a, i), (b) => array52[i] = b);
15117
- return zipRight2(forEachConcurrentDiscard(as12, fn2, batching, false, n), succeed(array52));
14445
+ const array5 = new Array(as12.length);
14446
+ const fn2 = (a, i) => map10(f(a, i), (b) => array5[i] = b);
14447
+ return zipRight2(forEachConcurrentDiscard(as12, fn2, batching, false, n), succeed(array5));
15118
14448
  }), fork = (self) => withFiberRuntime((state, status3) => succeed(unsafeFork2(self, state, status3.runtimeFlags))), forkDaemon = (self) => forkWithScopeOverride(self, globalScope), forkWithErrorHandler, unsafeFork2 = (effect3, parentFiber, parentRuntimeFlags, overrideScope = null) => {
15119
14449
  const childFiber = unsafeMakeChildFiber(effect3, parentFiber, parentRuntimeFlags, overrideScope);
15120
14450
  childFiber.resume(effect3);
@@ -15531,11 +14861,11 @@ ${prefix}}`;
15531
14861
  return end5 - time2 <= 0 ? some2(computeCachedValue(self, timeToLive, time2)) : none2();
15532
14862
  }
15533
14863
  }
15534
- })), flatMap7((option5) => isNone2(option5) ? dieMessage("BUG: Effect.cachedInvalidate - please report an issue at https://github.com/Effect-TS/effect/issues") : restore(deferredAwait(option5.value[1]))))), invalidateCache = (cache) => set4(cache, none2()), ensuringChild, ensuringChildren, forkAll, forkIn, forkScoped = (self) => scopeWith((scope5) => forkIn(self, scope5)), fromFiber = (fiber) => join22(fiber), fromFiberEffect = (fiber) => suspend(() => flatMap7(fiber, join22)), memoKeySymbol, Key, cachedFunction = (f, eq12) => {
14864
+ })), flatMap7((option5) => isNone2(option5) ? dieMessage("BUG: Effect.cachedInvalidate - please report an issue at https://github.com/Effect-TS/effect/issues") : restore(deferredAwait(option5.value[1]))))), invalidateCache = (cache) => set4(cache, none2()), ensuringChild, ensuringChildren, forkAll, forkIn, forkScoped = (self) => scopeWith((scope5) => forkIn(self, scope5)), fromFiber = (fiber) => join22(fiber), fromFiberEffect = (fiber) => suspend(() => flatMap7(fiber, join22)), memoKeySymbol, Key, cachedFunction = (f, eq11) => {
15535
14865
  return pipe(sync(() => empty22()), flatMap7(makeSynchronized), map10((ref) => (a) => pipe(ref.modifyEffect((map27) => {
15536
- const result = pipe(map27, get12(new Key(a, eq12)));
14866
+ const result = pipe(map27, get12(new Key(a, eq11)));
15537
14867
  if (isNone2(result)) {
15538
- return pipe(deferredMake(), tap2((deferred) => pipe(diffFiberRefs(f(a)), intoDeferred(deferred), fork)), map10((deferred) => [deferred, pipe(map27, set6(new Key(a, eq12), deferred))]));
14868
+ return pipe(deferredMake(), tap2((deferred) => pipe(diffFiberRefs(f(a)), intoDeferred(deferred), fork)), map10((deferred) => [deferred, pipe(map27, set6(new Key(a, eq11), deferred))]));
15539
14869
  }
15540
14870
  return succeed([result.value, map27]);
15541
14871
  }), flatMap7(deferredAwait), flatMap7(([patch9, b]) => pipe(patchFiberRefs(patch9), as2(b))))));
@@ -16220,8 +15550,8 @@ ${prefix}}`;
16220
15550
  const capacity3 = options.max - options.min + 1;
16221
15551
  const values3 = /* @__PURE__ */ new Set;
16222
15552
  const fields = input.split(",");
16223
- for (const field2 of fields) {
16224
- const [raw, step4] = splitStep(field2);
15553
+ for (const field of fields) {
15554
+ const [raw, step4] = splitStep(field);
16225
15555
  if (raw === "*" && step4 === undefined) {
16226
15556
  return right2(/* @__PURE__ */ new Set);
16227
15557
  }
@@ -20244,9 +19574,9 @@ schema (${ast._tag}): ${ast}`;
20244
19574
  const transformations = [];
20245
19575
  for (let i = 0;i < ownKeys.length; i++) {
20246
19576
  const key = ownKeys[i];
20247
- const field2 = fields[key];
20248
- if (isPropertySignature(field2)) {
20249
- const ast = field2.ast;
19577
+ const field = fields[key];
19578
+ if (isPropertySignature(field)) {
19579
+ const ast = field.ast;
20250
19580
  switch (ast._tag) {
20251
19581
  case "PropertySignatureDeclaration": {
20252
19582
  const type2 = ast.type;
@@ -20266,9 +19596,9 @@ schema (${ast._tag}): ${ast}`;
20266
19596
  }
20267
19597
  }
20268
19598
  } else {
20269
- from.push(new PropertySignature(key, field2.ast, false, true));
20270
- to.push(new PropertySignature(key, typeAST(field2.ast), false, true));
20271
- pss.push(new PropertySignature(key, field2.ast, false, true));
19599
+ from.push(new PropertySignature(key, field.ast, false, true));
19600
+ to.push(new PropertySignature(key, typeAST(field.ast), false, true));
19601
+ pss.push(new PropertySignature(key, field.ast, false, true));
20272
19602
  }
20273
19603
  }
20274
19604
  if (isNonEmptyReadonlyArray(transformations)) {
@@ -20308,9 +19638,9 @@ schema (${ast._tag}): ${ast}`;
20308
19638
  }, lazilyMergeDefaults = (fields, out) => {
20309
19639
  const ownKeys = Reflect.ownKeys(fields);
20310
19640
  for (const key of ownKeys) {
20311
- const field2 = fields[key];
20312
- if (out[key] === undefined && isPropertySignature(field2)) {
20313
- const ast = field2.ast;
19641
+ const field = fields[key];
19642
+ if (out[key] === undefined && isPropertySignature(field)) {
19643
+ const ast = field.ast;
20314
19644
  const defaultValue = ast._tag === "PropertySignatureDeclaration" ? ast.defaultValue : ast.to.defaultValue;
20315
19645
  if (defaultValue !== undefined) {
20316
19646
  out[key] = defaultValue();
@@ -21287,7 +20617,7 @@ schema (${ast._tag}): ${ast}`;
21287
20617
  const cowFlags = getCopyOnWriteFlags(process.platform);
21288
20618
  for (const relativePath of paths) {
21289
20619
  const src = join$1(hostRepoDir, relativePath);
21290
- if (!existsSync17(src)) {
20620
+ if (!existsSync15(src)) {
21291
20621
  continue;
21292
20622
  }
21293
20623
  const dest = join$1(worktreePath, relativePath);
@@ -21429,7 +20759,7 @@ ${e instanceof Error ? e.message : String(e)}`
21429
20759
  await mkdir(patchesRoot, { recursive: true });
21430
20760
  let dirName = base;
21431
20761
  let counter6 = 0;
21432
- while (existsSync17(join$1(patchesRoot, dirName))) {
20762
+ while (existsSync15(join$1(patchesRoot, dirName))) {
21433
20763
  counter6++;
21434
20764
  dirName = `${base}-${counter6}`;
21435
20765
  }
@@ -21520,7 +20850,7 @@ ${e instanceof Error ? e.message : String(e)}`
21520
20850
  const hostFilePath = join$1(untrackedDir, relPath);
21521
20851
  yield* Effect_exports.tryPromise({
21522
20852
  try: async () => {
21523
- await mkdir(dirname10(hostFilePath), { recursive: true });
20853
+ await mkdir(dirname8(hostFilePath), { recursive: true });
21524
20854
  await handle.copyFileOut(sandboxFilePath, hostFilePath);
21525
20855
  },
21526
20856
  catch: (e) => new SyncError({
@@ -21552,7 +20882,7 @@ ${e instanceof Error ? e.message : String(e)}`
21552
20882
  for (const relPath of untrackedFiles) {
21553
20883
  const srcPath = join$1(untrackedDir, relPath);
21554
20884
  const destPath = join$1(hostRepoDir, relPath);
21555
- await mkdir(dirname10(destPath), { recursive: true });
20885
+ await mkdir(dirname8(destPath), { recursive: true });
21556
20886
  const content = await readFile2(srcPath);
21557
20887
  await writeFile(destPath, content);
21558
20888
  }
@@ -21937,7 +21267,7 @@ ${result.stderr}`
21937
21267
  yield* Effect_exports.gen(function* () {
21938
21268
  for (const relativePath of pathsToCopy) {
21939
21269
  const hostPath = join$1(options.hostRepoDir, relativePath);
21940
- if (!existsSync17(hostPath)) {
21270
+ if (!existsSync15(hostPath)) {
21941
21271
  continue;
21942
21272
  }
21943
21273
  const sandboxPath = posix2.join(handle.worktreePath, relativePath);
@@ -22079,7 +21409,7 @@ Worktree removed (no uncommitted changes)`);
22079
21409
  };
22080
21410
  }
22081
21411
  const resolvedHostPath = resolveHostPath(m.hostPath);
22082
- if (!existsSync17(resolvedHostPath)) {
21412
+ if (!existsSync15(resolvedHostPath)) {
22083
21413
  throw new Error(`Mount hostPath does not exist: ${m.hostPath}` + (m.hostPath !== resolvedHostPath ? ` (resolved to ${resolvedHostPath})` : ""));
22084
21414
  }
22085
21415
  return {
@@ -22203,7 +21533,7 @@ Worktree removed (no uncommitted changes)`);
22203
21533
  }
22204
21534
  if (!isFile2)
22205
21535
  continue;
22206
- const parentDir = dirname10(mount.sandboxPath);
21536
+ const parentDir = dirname8(mount.sandboxPath);
22207
21537
  if (parentDir === sandboxHomedir)
22208
21538
  continue;
22209
21539
  if (!parentDir.startsWith(sandboxHomedir + "/")) {
@@ -22591,9 +21921,9 @@ var init_chunk_VOG34SRF = __esm(() => {
22591
21921
  constNull = /* @__PURE__ */ constant(null);
22592
21922
  constUndefined = /* @__PURE__ */ constant(undefined);
22593
21923
  constVoid = constUndefined;
22594
- number5 = /* @__PURE__ */ strict();
21924
+ number4 = /* @__PURE__ */ strict();
22595
21925
  mapInput = /* @__PURE__ */ dual(2, (self, f) => make((x, y) => self(f(x), f(y))));
22596
- Date2 = /* @__PURE__ */ mapInput(number5, (date2) => date2.getTime());
21926
+ Date2 = /* @__PURE__ */ mapInput(number4, (date2) => date2.getTime());
22597
21927
  isFunction2 = isFunction;
22598
21928
  hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && (property in self));
22599
21929
  isTagged = /* @__PURE__ */ dual(2, (self, tag4) => hasProperty(self, "_tag") && self["_tag"] === tag4);
@@ -23178,7 +22508,7 @@ var init_chunk_VOG34SRF = __esm(() => {
23178
22508
  });
23179
22509
  reduce = /* @__PURE__ */ dual(3, (self, b, f) => fromIterable2(self).reduce((b2, a, i) => f(b2, a, i), b));
23180
22510
  reduceRight = /* @__PURE__ */ dual(3, (self, b, f) => fromIterable2(self).reduceRight((b2, a, i) => f(b2, a, i), b));
23181
- getEquivalence2 = array5;
22511
+ getEquivalence2 = array4;
23182
22512
  dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
23183
22513
  const input = fromIterable2(self);
23184
22514
  if (isNonEmptyReadonlyArray(input)) {
@@ -23193,7 +22523,7 @@ var init_chunk_VOG34SRF = __esm(() => {
23193
22523
  }
23194
22524
  return [];
23195
22525
  });
23196
- join18 = /* @__PURE__ */ dual(2, (self, sep2) => fromIterable2(self).join(sep2));
22526
+ join17 = /* @__PURE__ */ dual(2, (self, sep2) => fromIterable2(self).join(sep2));
23197
22527
  TypeId4 = /* @__PURE__ */ Symbol.for("effect/Chunk");
23198
22528
  emptyArray = [];
23199
22529
  _equivalence3 = /* @__PURE__ */ getEquivalence3(equals);
@@ -23671,7 +23001,7 @@ var init_chunk_VOG34SRF = __esm(() => {
23671
23001
  }
23672
23002
  }));
23673
23003
  forEach2 = /* @__PURE__ */ dual(2, (self, f) => forEach(self._keyMap, (_, k) => f(k)));
23674
- reduce4 = /* @__PURE__ */ dual(3, (self, zero2, f) => reduce3(self._keyMap, zero2, (z6, _, a) => f(z6, a)));
23004
+ reduce4 = /* @__PURE__ */ dual(3, (self, zero2, f) => reduce3(self._keyMap, zero2, (z5, _, a) => f(z5, a)));
23675
23005
  empty6 = empty5;
23676
23006
  fromIterable6 = fromIterable5;
23677
23007
  make9 = make8;
@@ -24320,7 +23650,7 @@ var init_chunk_VOG34SRF = __esm(() => {
24320
23650
  return self;
24321
23651
  });
24322
23652
  FiberIdTypeId = /* @__PURE__ */ Symbol.for(FiberIdSymbolKey);
24323
- emptyHash = /* @__PURE__ */ string5(`${FiberIdSymbolKey}-${OP_NONE}`);
23653
+ emptyHash = /* @__PURE__ */ string4(`${FiberIdSymbolKey}-${OP_NONE}`);
24324
23654
  None = class {
24325
23655
  [FiberIdTypeId] = FiberIdTypeId;
24326
23656
  _tag = OP_NONE;
@@ -24355,7 +23685,7 @@ var init_chunk_VOG34SRF = __esm(() => {
24355
23685
  this.startTimeMillis = startTimeMillis;
24356
23686
  }
24357
23687
  [symbol]() {
24358
- return cached2(this, string5(`${FiberIdSymbolKey}-${this._tag}-${this.id}-${this.startTimeMillis}`));
23688
+ return cached2(this, string4(`${FiberIdSymbolKey}-${this._tag}-${this.id}-${this.startTimeMillis}`));
24359
23689
  }
24360
23690
  [symbol2](that) {
24361
23691
  return isFiberId(that) && that._tag === OP_RUNTIME && this.id === that.id && this.startTimeMillis === that.startTimeMillis;
@@ -24386,7 +23716,7 @@ var init_chunk_VOG34SRF = __esm(() => {
24386
23716
  }
24387
23717
  _hash;
24388
23718
  [symbol]() {
24389
- return pipe(string5(`${FiberIdSymbolKey}-${this._tag}`), combine(hash(this.left)), combine(hash(this.right)), cached2(this));
23719
+ return pipe(string4(`${FiberIdSymbolKey}-${this._tag}`), combine(hash(this.left)), combine(hash(this.right)), cached2(this));
24390
23720
  }
24391
23721
  [symbol2](that) {
24392
23722
  return isFiberId(that) && that._tag === OP_COMPOSITE && equals(this.left, that.left) && equals(this.right, that.right);
@@ -24498,7 +23828,7 @@ var init_chunk_VOG34SRF = __esm(() => {
24498
23828
  return pipeArguments(this, arguments);
24499
23829
  }
24500
23830
  };
24501
- NilHash = /* @__PURE__ */ string5("Nil");
23831
+ NilHash = /* @__PURE__ */ string4("Nil");
24502
23832
  NilProto = {
24503
23833
  [TypeId8]: TypeId8,
24504
23834
  _tag: "Nil",
@@ -24947,7 +24277,7 @@ var init_chunk_VOG34SRF = __esm(() => {
24947
24277
  return exitIsExit(that) && that._op === "Failure" && equals(this.effect_instruction_i0, that.effect_instruction_i0);
24948
24278
  }
24949
24279
  [symbol]() {
24950
- return pipe(string5(this._tag), combine(hash(this.effect_instruction_i0)), cached2(this));
24280
+ return pipe(string4(this._tag), combine(hash(this.effect_instruction_i0)), cached2(this));
24951
24281
  }
24952
24282
  get cause() {
24953
24283
  return this.effect_instruction_i0;
@@ -24987,7 +24317,7 @@ var init_chunk_VOG34SRF = __esm(() => {
24987
24317
  return exitIsExit(that) && that._op === "Success" && equals(this.effect_instruction_i0, that.effect_instruction_i0);
24988
24318
  }
24989
24319
  [symbol]() {
24990
- return pipe(string5(this._tag), combine(hash(this.effect_instruction_i0)), cached2(this));
24320
+ return pipe(string4(this._tag), combine(hash(this.effect_instruction_i0)), cached2(this));
24991
24321
  }
24992
24322
  get value() {
24993
24323
  return this.effect_instruction_i0;
@@ -26142,7 +25472,7 @@ ${this.stack.split(`
26142
25472
  diff6 = diff5;
26143
25473
  patch7 = patch6;
26144
25474
  FiberStatusTypeId = /* @__PURE__ */ Symbol.for(FiberStatusSymbolKey);
26145
- DoneHash = /* @__PURE__ */ string5(`${FiberStatusSymbolKey}-${OP_DONE}`);
25475
+ DoneHash = /* @__PURE__ */ string4(`${FiberStatusSymbolKey}-${OP_DONE}`);
26146
25476
  Done = class {
26147
25477
  [FiberStatusTypeId] = FiberStatusTypeId;
26148
25478
  _tag = OP_DONE;
@@ -26670,7 +26000,7 @@ ${this.stack.split(`
26670
26000
  constructor(key, value5) {
26671
26001
  this.key = key;
26672
26002
  this.value = value5;
26673
- this._hash = string5(MetricLabelSymbolKey + this.key + this.value);
26003
+ this._hash = string4(MetricLabelSymbolKey + this.key + this.value);
26674
26004
  }
26675
26005
  [symbol]() {
26676
26006
  return this._hash;
@@ -26840,12 +26170,12 @@ ${this.stack.split(`
26840
26170
  while (!(next4 = iterator.next()).done) {
26841
26171
  const index2 = i++;
26842
26172
  const value5 = next4.value;
26843
- result = flatMap7(result, (state) => map10(f(state, value5, index2), ([z6, b]) => {
26173
+ result = flatMap7(result, (state) => map10(f(state, value5, index2), ([z5, b]) => {
26844
26174
  builder.push(b);
26845
- return z6;
26175
+ return z5;
26846
26176
  }));
26847
26177
  }
26848
- return map10(result, (z6) => [z6, builder]);
26178
+ return map10(result, (z5) => [z5, builder]);
26849
26179
  }));
26850
26180
  mapErrorCause = /* @__PURE__ */ dual(2, (self, f) => matchCauseEffect(self, {
26851
26181
  onFailure: (c) => failCauseSync(() => f(c)),
@@ -27241,7 +26571,7 @@ ${this.stack.split(`
27241
26571
  [MetricBoundariesTypeId] = MetricBoundariesTypeId;
27242
26572
  constructor(values3) {
27243
26573
  this.values = values3;
27244
- this._hash = pipe(string5(MetricBoundariesSymbolKey), combine(array22(this.values)));
26574
+ this._hash = pipe(string4(MetricBoundariesSymbolKey), combine(array22(this.values)));
27245
26575
  }
27246
26576
  _hash;
27247
26577
  [symbol]() {
@@ -27272,7 +26602,7 @@ ${this.stack.split(`
27272
26602
  constructor(incremental, bigint) {
27273
26603
  this.incremental = incremental;
27274
26604
  this.bigint = bigint;
27275
- this._hash = string5(CounterKeyTypeSymbolKey);
26605
+ this._hash = string4(CounterKeyTypeSymbolKey);
27276
26606
  }
27277
26607
  _hash;
27278
26608
  [symbol]() {
@@ -27291,7 +26621,7 @@ ${this.stack.split(`
27291
26621
  [HistogramKeyTypeTypeId] = HistogramKeyTypeTypeId;
27292
26622
  constructor(boundaries) {
27293
26623
  this.boundaries = boundaries;
27294
- this._hash = pipe(string5(HistogramKeyTypeSymbolKey), combine(hash(this.boundaries)));
26624
+ this._hash = pipe(string4(HistogramKeyTypeSymbolKey), combine(hash(this.boundaries)));
27295
26625
  }
27296
26626
  _hash;
27297
26627
  [symbol]() {
@@ -27320,7 +26650,7 @@ ${this.stack.split(`
27320
26650
  this.keyType = keyType;
27321
26651
  this.description = description;
27322
26652
  this.tags = tags2;
27323
- this._hash = pipe(string5(this.name + this.description), combine(hash(this.keyType)), combine(array22(this.tags)));
26653
+ this._hash = pipe(string4(this.name + this.description), combine(hash(this.keyType)), combine(array22(this.tags)));
27324
26654
  }
27325
26655
  _hash;
27326
26656
  [symbol]() {
@@ -27460,7 +26790,7 @@ ${this.stack.split(`
27460
26790
  }
27461
26791
  _hash;
27462
26792
  [symbol]() {
27463
- return pipe(string5(FrequencyStateSymbolKey), combine(array22(fromIterable2(this.occurrences.entries()))), cached2(this));
26793
+ return pipe(string4(FrequencyStateSymbolKey), combine(array22(fromIterable2(this.occurrences.entries()))), cached2(this));
27464
26794
  }
27465
26795
  [symbol2](that) {
27466
26796
  return isFrequencyState(that) && arrayEquals(fromIterable2(this.occurrences.entries()), fromIterable2(that.occurrences.entries()));
@@ -29054,9 +28384,9 @@ ${this.stack.split(`
29054
28384
  a;
29055
28385
  eq;
29056
28386
  [memoKeySymbol] = memoKeySymbol;
29057
- constructor(a, eq12) {
28387
+ constructor(a, eq11) {
29058
28388
  this.a = a;
29059
- this.eq = eq12;
28389
+ this.eq = eq11;
29060
28390
  }
29061
28391
  [symbol2](that) {
29062
28392
  if (hasProperty(that, memoKeySymbol)) {
@@ -29765,7 +29095,7 @@ ${this.stack.split(`
29765
29095
  ...ProtoTimeZone,
29766
29096
  _tag: "Named",
29767
29097
  [symbol]() {
29768
- return cached2(this, string5(`Named:${this.id}`));
29098
+ return cached2(this, string4(`Named:${this.id}`));
29769
29099
  },
29770
29100
  [symbol2](that) {
29771
29101
  return isTimeZone(that) && that._tag === "Named" && this.id === that.id;
@@ -29785,7 +29115,7 @@ ${this.stack.split(`
29785
29115
  ...ProtoTimeZone,
29786
29116
  _tag: "Offset",
29787
29117
  [symbol]() {
29788
- return cached2(this, string5(`Offset:${this.offset}`));
29118
+ return cached2(this, string4(`Offset:${this.offset}`));
29789
29119
  },
29790
29120
  [symbol2](that) {
29791
29121
  return isTimeZone(that) && that._tag === "Offset" && this.offset === that.offset;
@@ -29868,7 +29198,7 @@ ${this.stack.split(`
29868
29198
  [ParseErrorTypeId] = ParseErrorTypeId;
29869
29199
  };
29870
29200
  Equivalence2 = /* @__PURE__ */ make((self, that) => restrictionsEquals(self.seconds, that.seconds) && restrictionsEquals(self.minutes, that.minutes) && restrictionsEquals(self.hours, that.hours) && restrictionsEquals(self.days, that.days) && restrictionsEquals(self.months, that.months) && restrictionsEquals(self.weekdays, that.weekdays));
29871
- restrictionsArrayEquals = /* @__PURE__ */ array5(number5);
29201
+ restrictionsArrayEquals = /* @__PURE__ */ array4(number4);
29872
29202
  equals3 = /* @__PURE__ */ dual(2, (self, that) => Equivalence2(self, that));
29873
29203
  secondOptions = {
29874
29204
  min: 0,
@@ -30081,8 +29411,8 @@ ${this.stack.split(`
30081
29411
  onDecision = /* @__PURE__ */ dual(2, (self, f) => makeWithState(self.initial, (now2, input, state) => flatMap7(self.step(now2, input, state), ([state2, out, decision]) => as2(f(out, decision), [state2, out, decision]))));
30082
29412
  provideContext3 = /* @__PURE__ */ dual(2, (self, context8) => makeWithState(self.initial, (now2, input, state) => provideContext(self.step(now2, input, state), context8)));
30083
29413
  provideService2 = /* @__PURE__ */ dual(3, (self, tag4, service3) => makeWithState(self.initial, (now2, input, state) => contextWithEffect((env2) => provideContext(self.step(now2, input, state), add4(env2, tag4, service3)))));
30084
- reduce11 = /* @__PURE__ */ dual(3, (self, zero2, f) => reduceEffect2(self, zero2, (z6, out) => sync(() => f(z6, out))));
30085
- reduceEffect2 = /* @__PURE__ */ dual(3, (self, zero2, f) => makeWithState([self.initial, zero2], (now2, input, [s, z6]) => flatMap7(self.step(now2, input, s), ([s2, out, decision]) => isDone4(decision) ? succeed([[s2, z6], z6, decision]) : map10(f(z6, out), (z22) => [[s2, z22], z6, decision]))));
29414
+ reduce11 = /* @__PURE__ */ dual(3, (self, zero2, f) => reduceEffect2(self, zero2, (z5, out) => sync(() => f(z5, out))));
29415
+ reduceEffect2 = /* @__PURE__ */ dual(3, (self, zero2, f) => makeWithState([self.initial, zero2], (now2, input, [s, z5]) => flatMap7(self.step(now2, input, s), ([s2, out, decision]) => isDone4(decision) ? succeed([[s2, z5], z5, decision]) : map10(f(z5, out), (z22) => [[s2, z22], z5, decision]))));
30086
29416
  resetAfter = /* @__PURE__ */ dual(2, (self, durationInput) => {
30087
29417
  const duration4 = decode(durationInput);
30088
29418
  return pipe(self, intersect5(elapsed), resetWhen(([, time2]) => greaterThanOrEqualTo(time2, duration4)), map17((out) => out[0]));
@@ -31892,7 +31222,7 @@ ${this.stack.split(`
31892
31222
  return match9(exit4, {
31893
31223
  onFailure: (cause3) => onDecision3(done10(failCause3(cause3))),
31894
31224
  onSuccess: match({
31895
- onLeft: (z6) => onDecision3(done10(succeed3(z6))),
31225
+ onLeft: (z5) => onDecision3(done10(succeed3(z5))),
31896
31226
  onRight: (elem) => succeed10(flatMap13(write(elem), () => flatMap13(fromEffect5(forkIn2(interruptible4(pull), scope5)), (leftFiber) => go2(both2(leftFiber, fiber)))))
31897
31227
  })
31898
31228
  });
@@ -32358,9 +31688,9 @@ ${this.stack.split(`
32358
31688
  upstreamDone.ref = true;
32359
31689
  }), succeedNow(done10))
32360
31690
  });
32361
- const transducer = pipe(sink, toChannel, collectElements, flatMap13(([leftover2, z6]) => pipe(succeed12([upstreamDone.ref, concatAndGet(leftover2)]), flatMap13(([done10, newLeftovers]) => {
31691
+ const transducer = pipe(sink, toChannel, collectElements, flatMap13(([leftover2, z5]) => pipe(succeed12([upstreamDone.ref, concatAndGet(leftover2)]), flatMap13(([done10, newLeftovers]) => {
32362
31692
  const nextChannel = done10 && isEmpty(newLeftovers) ? void_7 : transducer;
32363
- return pipe(write(of2(z6)), flatMap13(() => nextChannel));
31693
+ return pipe(write(of2(z5)), flatMap13(() => nextChannel));
32364
31694
  }))));
32365
31695
  return pipe(toChannel2(self), pipeTo(upstreamMarker), pipeTo(buffer3), pipeToOrFail(transducer));
32366
31696
  });
@@ -33514,7 +32844,7 @@ ${this.stack.split(`
33514
32844
  FileDisplay = {
33515
32845
  layer: (filePath) => Layer_exports.effect(Display, Effect_exports.gen(function* () {
33516
32846
  const fs = yield* FileSystem_exports.FileSystem;
33517
- yield* fs.makeDirectory(dirname10(filePath), { recursive: true }).pipe(Effect_exports.orDie);
32847
+ yield* fs.makeDirectory(dirname8(filePath), { recursive: true }).pipe(Effect_exports.orDie);
33518
32848
  const delimiter = `
33519
32849
  --- Run started: ${(/* @__PURE__ */ new Date()).toISOString()} ---
33520
32850
  `;
@@ -46048,17 +45378,17 @@ ${len.toString(16)}\r
46048
45378
  lastCall() {
46049
45379
  return this.logs.at(-1);
46050
45380
  }
46051
- nthCall(number6) {
46052
- if (typeof number6 !== "number") {
45381
+ nthCall(number5) {
45382
+ if (typeof number5 !== "number") {
46053
45383
  throw new InvalidArgumentError("nthCall must be called with a number");
46054
45384
  }
46055
- if (!Number.isInteger(number6)) {
45385
+ if (!Number.isInteger(number5)) {
46056
45386
  throw new InvalidArgumentError("nthCall must be called with an integer");
46057
45387
  }
46058
- if (Math.sign(number6) !== 1) {
45388
+ if (Math.sign(number5) !== 1) {
46059
45389
  throw new InvalidArgumentError("nthCall must be called with a positive value. use firstCall or lastCall instead");
46060
45390
  }
46061
- return this.logs.at(number6 - 1);
45391
+ return this.logs.at(number5 - 1);
46062
45392
  }
46063
45393
  filterCalls(criteria, options) {
46064
45394
  if (this.logs.length === 0) {
@@ -50353,24 +49683,24 @@ ${pendingInterceptorsFormatter.format(pending3)}`.trim());
50353
49683
  }
50354
49684
  toSortedArray() {
50355
49685
  const size6 = this.headersMap.size;
50356
- const array6 = new Array(size6);
49686
+ const array5 = new Array(size6);
50357
49687
  if (size6 <= 32) {
50358
49688
  if (size6 === 0) {
50359
- return array6;
49689
+ return array5;
50360
49690
  }
50361
49691
  const iterator = this.headersMap[Symbol.iterator]();
50362
49692
  const firstValue = iterator.next().value;
50363
- array6[0] = [firstValue[0], firstValue[1].value];
49693
+ array5[0] = [firstValue[0], firstValue[1].value];
50364
49694
  assert(firstValue[1].value !== null);
50365
49695
  for (let i = 1, j = 0, right3 = 0, left3 = 0, pivot = 0, x, value;i < size6; ++i) {
50366
49696
  value = iterator.next().value;
50367
- x = array6[i] = [value[0], value[1].value];
49697
+ x = array5[i] = [value[0], value[1].value];
50368
49698
  assert(x[1] !== null);
50369
49699
  left3 = 0;
50370
49700
  right3 = i;
50371
49701
  while (left3 < right3) {
50372
49702
  pivot = left3 + (right3 - left3 >> 1);
50373
- if (array6[pivot][0] <= x[0]) {
49703
+ if (array5[pivot][0] <= x[0]) {
50374
49704
  left3 = pivot + 1;
50375
49705
  } else {
50376
49706
  right3 = pivot;
@@ -50379,22 +49709,22 @@ ${pendingInterceptorsFormatter.format(pending3)}`.trim());
50379
49709
  if (i !== pivot) {
50380
49710
  j = i;
50381
49711
  while (j > left3) {
50382
- array6[j] = array6[--j];
49712
+ array5[j] = array5[--j];
50383
49713
  }
50384
- array6[left3] = x;
49714
+ array5[left3] = x;
50385
49715
  }
50386
49716
  }
50387
49717
  if (!iterator.next().done) {
50388
49718
  throw new TypeError("Unreachable");
50389
49719
  }
50390
- return array6;
49720
+ return array5;
50391
49721
  } else {
50392
49722
  let i = 0;
50393
49723
  for (const { 0: name, 1: { value } } of this.headersMap) {
50394
- array6[i++] = [name, value];
49724
+ array5[i++] = [name, value];
50395
49725
  assert(value !== null);
50396
49726
  }
50397
- return array6.sort(compareHeaderName);
49727
+ return array5.sort(compareHeaderName);
50398
49728
  }
50399
49729
  }
50400
49730
  };
@@ -55583,14 +54913,14 @@ ${pendingInterceptorsFormatter.format(pending3)}`.trim());
55583
54913
  data = new Uint8Array(ArrayBuffer.isView(chunk) ? new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength) : chunk.slice());
55584
54914
  opcode = opcodes.BINARY;
55585
54915
  } else {
55586
- let string6;
54916
+ let string5;
55587
54917
  try {
55588
- string6 = webidl.converters.DOMString(chunk);
54918
+ string5 = webidl.converters.DOMString(chunk);
55589
54919
  } catch (e) {
55590
54920
  promise3.reject(e);
55591
54921
  return promise3.promise;
55592
54922
  }
55593
- data = new TextEncoder().encode(string6);
54923
+ data = new TextEncoder().encode(string5);
55594
54924
  opcode = opcodes.TEXT;
55595
54925
  }
55596
54926
  if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
@@ -55883,41 +55213,41 @@ ${pendingInterceptorsFormatter.format(pending3)}`.trim());
55883
55213
  if (colonPosition === 0) {
55884
55214
  return;
55885
55215
  }
55886
- let field2 = "";
55216
+ let field = "";
55887
55217
  let value = "";
55888
55218
  if (colonPosition !== -1) {
55889
- field2 = line.subarray(0, colonPosition).toString("utf8");
55219
+ field = line.subarray(0, colonPosition).toString("utf8");
55890
55220
  let valueStart = colonPosition + 1;
55891
55221
  if (line[valueStart] === SPACE) {
55892
55222
  ++valueStart;
55893
55223
  }
55894
55224
  value = line.subarray(valueStart).toString("utf8");
55895
55225
  } else {
55896
- field2 = line.toString("utf8");
55226
+ field = line.toString("utf8");
55897
55227
  value = "";
55898
55228
  }
55899
- switch (field2) {
55229
+ switch (field) {
55900
55230
  case "data":
55901
- if (event[field2] === undefined) {
55902
- event[field2] = value;
55231
+ if (event[field] === undefined) {
55232
+ event[field] = value;
55903
55233
  } else {
55904
- event[field2] += `
55234
+ event[field] += `
55905
55235
  ${value}`;
55906
55236
  }
55907
55237
  break;
55908
55238
  case "retry":
55909
55239
  if (isASCIINumber(value)) {
55910
- event[field2] = value;
55240
+ event[field] = value;
55911
55241
  }
55912
55242
  break;
55913
55243
  case "id":
55914
55244
  if (isValidLastEventId(value)) {
55915
- event[field2] = value;
55245
+ event[field] = value;
55916
55246
  }
55917
55247
  break;
55918
55248
  case "event":
55919
55249
  if (value.length > 0) {
55920
- event[field2] = value;
55250
+ event[field] = value;
55921
55251
  }
55922
55252
  break;
55923
55253
  }
@@ -56989,8 +56319,8 @@ var init_chunk_62WN33RK = __esm(() => {
56989
56319
 
56990
56320
  // ../../node_modules/.bun/@ai-hero+sandcastle@0.12.0/node_modules/@ai-hero/sandcastle/dist/index.js
56991
56321
  import { createRequire as createRequire9 } from "module";
56992
- import { mkdirSync as mkdirSync10, appendFileSync } from "fs";
56993
- import path, { join as join20, posix as posix4, dirname as dirname12, relative as relative3 } from "path";
56322
+ import { mkdirSync as mkdirSync8, appendFileSync } from "fs";
56323
+ import path, { join as join19, posix as posix4, dirname as dirname10, relative as relative3 } from "path";
56994
56324
  import { styleText as styleText2 } from "util";
56995
56325
  import * as clack2 from "@clack/prompts";
56996
56326
  import { readdir as readdir2, access as access3, readFile as readFile4, mkdir as mkdir3, writeFile as writeFile3, rm as rm3 } from "fs/promises";
@@ -57059,7 +56389,7 @@ async function run6(options) {
57059
56389
  const targetBranch = effectiveBranchType === "merge-to-head" ? currentHostBranch : undefined;
57060
56390
  const resolvedLogging = options.logging ?? {
57061
56391
  type: "file",
57062
- path: join20(hostRepoDir, ".sandcastle", "logs", buildLogFilename(resolvedBranch, targetBranch, options.name))
56392
+ path: join19(hostRepoDir, ".sandcastle", "logs", buildLogFilename(resolvedBranch, targetBranch, options.name))
57063
56393
  };
57064
56394
  const displayLayer = resolvedLogging.type === "file" ? (() => {
57065
56395
  printFileDisplayStartup({
@@ -57693,7 +57023,7 @@ ${errorDetail}`
57693
57023
  }
57694
57024
  return vars;
57695
57025
  }), resolveEnv = (repoDir) => Effect_exports.gen(function* () {
57696
- const sandcastleEnv = yield* parseEnvFile2(join20(repoDir, ".sandcastle", ".env"));
57026
+ const sandcastleEnv = yield* parseEnvFile2(join19(repoDir, ".sandcastle", ".env"));
57697
57027
  const result = {};
57698
57028
  for (const key of Object.keys(sandcastleEnv)) {
57699
57029
  const value = sandcastleEnv[key] || process.env[key];
@@ -57890,7 +57220,7 @@ Emit only a corrected <${error.tag}> block. Do not change files or run commands.
57890
57220
  if (logging.type === "file") {
57891
57221
  const logPath = logging.path;
57892
57222
  try {
57893
- mkdirSync10(path.dirname(logPath), { recursive: true });
57223
+ mkdirSync8(path.dirname(logPath), { recursive: true });
57894
57224
  } catch {}
57895
57225
  return (line) => {
57896
57226
  try {
@@ -57965,7 +57295,7 @@ Emit only a corrected <${error.tag}> block. Do not change files or run commands.
57965
57295
  }).pipe(Effect_exports.provide(silentDisplayLayer)));
57966
57296
  const resolvedLogging = runOptions.logging ?? {
57967
57297
  type: "file",
57968
- path: join20(hostRepoDir, ".sandcastle", "logs", buildLogFilename(branch, undefined, runOptions.name))
57298
+ path: join19(hostRepoDir, ".sandcastle", "logs", buildLogFilename(branch, undefined, runOptions.name))
57969
57299
  };
57970
57300
  const runDisplayLayer = resolvedLogging.type === "file" ? (() => {
57971
57301
  printFileDisplayStartup({
@@ -58191,7 +57521,7 @@ Emit only a corrected <${error.tag}> block. Do not change files or run commands.
58191
57521
  hostRepoDir: hostRepoDir2,
58192
57522
  env,
58193
57523
  worktreeOrRepoPath: worktreePath2
58194
- }) : resolveGitMounts(join20(hostRepoDir2, ".git")).pipe(Effect_exports.provide(NodeFileSystem_exports2.layer), Effect_exports.catchAll(() => Effect_exports.succeed([])), Effect_exports.flatMap((gitMounts) => patchGitMountsForWindows(gitMounts, worktreePath2, SANDBOX_REPO_DIR)), Effect_exports.flatMap((gitMounts) => startSandbox({
57524
+ }) : resolveGitMounts(join19(hostRepoDir2, ".git")).pipe(Effect_exports.provide(NodeFileSystem_exports2.layer), Effect_exports.catchAll(() => Effect_exports.succeed([])), Effect_exports.flatMap((gitMounts) => patchGitMountsForWindows(gitMounts, worktreePath2, SANDBOX_REPO_DIR)), Effect_exports.flatMap((gitMounts) => startSandbox({
58195
57525
  provider,
58196
57526
  hostRepoDir: hostRepoDir2,
58197
57527
  env,
@@ -58276,11 +57606,11 @@ Worktree preserved at ${worktreePath}`);
58276
57606
  const normalized = isRoot ? cwd : cwd.replace(/[\\/]+$/, "");
58277
57607
  return normalized.replace(/^([A-Za-z]):/, "$1").replace(/[\\/]/g, "-");
58278
57608
  }, claudeHostSessionPath = (cwd, id3, projectsDir) => {
58279
- const base = projectsDir ?? join20(process.env.HOME ?? "~", ".claude", "projects");
58280
- return join20(base, encodeProjectPath(cwd), `${id3}.jsonl`);
57609
+ const base = projectsDir ?? join19(process.env.HOME ?? "~", ".claude", "projects");
57610
+ return join19(base, encodeProjectPath(cwd), `${id3}.jsonl`);
58281
57611
  }, claudeSandboxSessionPath = (cwd, id3, projectsDir) => posix4.join(projectsDir, encodeProjectPath(cwd), `${id3}.jsonl`), claudeSubagentsDirInSandbox = (cwd, id3, projectsDir) => posix4.join(projectsDir, encodeProjectPath(cwd), id3, "subagents"), claudeSubagentsDirOnHost = (cwd, id3, projectsDir) => {
58282
- const base = projectsDir ?? join20(process.env.HOME ?? "~", ".claude", "projects");
58283
- return join20(base, encodeProjectPath(cwd), id3, "subagents");
57612
+ const base = projectsDir ?? join19(process.env.HOME ?? "~", ".claude", "projects");
57613
+ return join19(base, encodeProjectPath(cwd), id3, "subagents");
58284
57614
  }, listClaudeSubagentSessionsInSandbox = async (cwd, id3, handle, sandboxProjectsDir) => {
58285
57615
  const dir = claudeSubagentsDirInSandbox(cwd, id3, sandboxProjectsDir);
58286
57616
  const result = await handle.exec(`find ${JSON.stringify(dir)} -type f -name ${JSON.stringify("agent-*.jsonl")} 2>/dev/null`);
@@ -58292,7 +57622,7 @@ Worktree preserved at ${worktreePath}`);
58292
57622
  return stdout.split(`
58293
57623
  `).filter((line) => line !== "");
58294
57624
  }, findClaudeSessionOnHost = async (id3, projectsDir) => {
58295
- const root = projectsDir ?? join20(process.env.HOME ?? "~", ".claude", "projects");
57625
+ const root = projectsDir ?? join19(process.env.HOME ?? "~", ".claude", "projects");
58296
57626
  let entries;
58297
57627
  try {
58298
57628
  entries = await readdir2(root, { withFileTypes: true });
@@ -58302,7 +57632,7 @@ Worktree preserved at ${worktreePath}`);
58302
57632
  for (const entry of entries) {
58303
57633
  if (!entry.isDirectory())
58304
57634
  continue;
58305
- const candidate = join20(root, entry.name, `${id3}.jsonl`);
57635
+ const candidate = join19(root, entry.name, `${id3}.jsonl`);
58306
57636
  if (await pathExists(candidate)) {
58307
57637
  return { path: candidate, searchedRoot: root };
58308
57638
  }
@@ -58338,7 +57668,7 @@ Worktree preserved at ${worktreePath}`);
58338
57668
  return;
58339
57669
  }
58340
57670
  for (const entry of entries) {
58341
- const child = join20(dir, entry.name);
57671
+ const child = join19(dir, entry.name);
58342
57672
  if (entry.isFile() && isCodexSessionFilename(entry.name, id3)) {
58343
57673
  return child;
58344
57674
  }
@@ -58352,11 +57682,11 @@ Worktree preserved at ${worktreePath}`);
58352
57682
  };
58353
57683
  return visit(rootDir);
58354
57684
  }, findCodexSessionOnHost = async (id3, sessionsDir) => {
58355
- const root = sessionsDir ?? join20(process.env.HOME ?? "~", ".codex", "sessions");
57685
+ const root = sessionsDir ?? join19(process.env.HOME ?? "~", ".codex", "sessions");
58356
57686
  const path2 = await findCodexSessionPath(root, id3);
58357
57687
  return { path: path2, searchedRoot: root };
58358
57688
  }, locateCodexHostSession = async (id3, sessionsDir) => {
58359
- const root = sessionsDir ?? join20(process.env.HOME ?? "~", ".codex", "sessions");
57689
+ const root = sessionsDir ?? join19(process.env.HOME ?? "~", ".codex", "sessions");
58360
57690
  const path2 = await findCodexSessionPath(root, id3);
58361
57691
  if (!path2)
58362
57692
  throw new Error(`session ${id3} not found in ${root}`);
@@ -58432,7 +57762,7 @@ Worktree preserved at ${worktreePath}`);
58432
57762
  } catch {}
58433
57763
  return [];
58434
57764
  }, CURSOR_PRINT_PROMPT_MAX_BYTES, readSandboxFile = async (handle, sandboxPath, tag) => {
58435
- const tmpPath = join20(tmpdir4(), `sandcastle-${tag}-${Date.now()}-${Math.random().toString(36).slice(2)}.jsonl`);
57765
+ const tmpPath = join19(tmpdir4(), `sandcastle-${tag}-${Date.now()}-${Math.random().toString(36).slice(2)}.jsonl`);
58436
57766
  await handle.copyFileOut(sandboxPath, tmpPath);
58437
57767
  try {
58438
57768
  return await readFile4(tmpPath, "utf-8");
@@ -58440,7 +57770,7 @@ Worktree preserved at ${worktreePath}`);
58440
57770
  await rm3(tmpPath, { force: true }).catch(() => {});
58441
57771
  }
58442
57772
  }, writeSandboxFile = async (handle, sandboxPath, content, tag) => {
58443
- const tmpPath = join20(tmpdir4(), `sandcastle-${tag}-${Date.now()}-${Math.random().toString(36).slice(2)}.jsonl`);
57773
+ const tmpPath = join19(tmpdir4(), `sandcastle-${tag}-${Date.now()}-${Math.random().toString(36).slice(2)}.jsonl`);
58444
57774
  await writeFile3(tmpPath, content);
58445
57775
  try {
58446
57776
  await handle.exec(`mkdir -p ${JSON.stringify(posix4.dirname(sandboxPath))}`);
@@ -58458,7 +57788,7 @@ Worktree preserved at ${worktreePath}`);
58458
57788
  }) => {
58459
57789
  const jsonl = await readSandboxFile(handle, sourcePath, tag);
58460
57790
  const rewritten = transferClaudeSession(jsonl, fromCwd, toCwd);
58461
- await mkdir3(dirname12(destPath), { recursive: true });
57791
+ await mkdir3(dirname10(destPath), { recursive: true });
58462
57792
  await writeFile3(destPath, rewritten);
58463
57793
  }, makeClaudeSessionStorage = (options) => {
58464
57794
  const hostProjectsDir = options?.sessionStorage?.hostProjectsDir;
@@ -58490,7 +57820,7 @@ Worktree preserved at ${worktreePath}`);
58490
57820
  sourcePath: sandboxSubagentPath,
58491
57821
  fromCwd: sandboxCwd,
58492
57822
  toCwd: hostCwd,
58493
- destPath: join20(hostSubagentsDir, posix4.basename(sandboxSubagentPath)),
57823
+ destPath: join19(hostSubagentsDir, posix4.basename(sandboxSubagentPath)),
58494
57824
  tag: "claude-sub"
58495
57825
  });
58496
57826
  } catch (err) {
@@ -58527,9 +57857,9 @@ Worktree preserved at ${worktreePath}`);
58527
57857
  const located = await locateCodexSandboxSession(sessionId, handle, sandboxSessionsDir);
58528
57858
  const jsonl = await readSandboxFile(handle, located.path, "codex-cap");
58529
57859
  const rewritten = transferCodexSession(jsonl, sandboxCwd, hostCwd);
58530
- const root = hostSessionsDir ?? join20(process.env.HOME ?? "~", ".codex", "sessions");
58531
- const target = join20(root, located.relativePath);
58532
- await mkdir3(dirname12(target), { recursive: true });
57860
+ const root = hostSessionsDir ?? join19(process.env.HOME ?? "~", ".codex", "sessions");
57861
+ const target = join19(root, located.relativePath);
57862
+ await mkdir3(dirname10(target), { recursive: true });
58533
57863
  await writeFile3(target, rewritten);
58534
57864
  capturedPaths.set(sessionId, target);
58535
57865
  },
@@ -58648,90 +57978,763 @@ Worktree preserved at ${worktreePath}`);
58648
57978
  } else if (dangerouslySkipPermissions) {
58649
57979
  args2.push("--dangerously-skip-permissions");
58650
57980
  }
58651
- args2.push("--model", model);
58652
- if (options?.effort)
58653
- args2.push("--effort", options.effort);
58654
- if (prompt)
58655
- args2.push(prompt);
58656
- return args2;
58657
- },
58658
- parseStreamLine(line) {
58659
- return parseStreamJsonLine(line);
58660
- },
58661
- parseSessionUsage(content) {
58662
- const lines2 = content.split(`
57981
+ args2.push("--model", model);
57982
+ if (options?.effort)
57983
+ args2.push("--effort", options.effort);
57984
+ if (prompt)
57985
+ args2.push(prompt);
57986
+ return args2;
57987
+ },
57988
+ parseStreamLine(line) {
57989
+ return parseStreamJsonLine(line);
57990
+ },
57991
+ parseSessionUsage(content) {
57992
+ const lines2 = content.split(`
57993
+ `);
57994
+ for (let i = lines2.length - 1;i >= 0; i--) {
57995
+ const line = lines2[i];
57996
+ if (!line.startsWith("{"))
57997
+ continue;
57998
+ try {
57999
+ const obj = JSON.parse(line);
58000
+ if (obj.type === "assistant" && obj.message?.usage) {
58001
+ const u = obj.message.usage;
58002
+ if (typeof u.input_tokens === "number" && typeof u.cache_creation_input_tokens === "number" && typeof u.cache_read_input_tokens === "number" && typeof u.output_tokens === "number") {
58003
+ return {
58004
+ inputTokens: u.input_tokens,
58005
+ cacheCreationInputTokens: u.cache_creation_input_tokens,
58006
+ cacheReadInputTokens: u.cache_read_input_tokens,
58007
+ outputTokens: u.output_tokens
58008
+ };
58009
+ }
58010
+ }
58011
+ } catch {}
58012
+ }
58013
+ return;
58014
+ }
58015
+ });
58016
+ var init_dist = __esm(() => {
58017
+ init_chunk_DJRHWPEH();
58018
+ init_chunk_VOG34SRF();
58019
+ init_chunk_BIWNFKGV();
58020
+ init_chunk_62WN33RK();
58021
+ init_chunk_NGBM7T3E();
58022
+ init_chunk_NGBM7T3E();
58023
+ createRequire9(import.meta.url);
58024
+ AgentStreamEmitter = class extends Context_exports.Tag("AgentStreamEmitter")() {
58025
+ };
58026
+ MARKED_SHELL_BLOCK_PATTERN = new RegExp(`!${SHELL_BLOCK_MARKER}\`([^\`]+)\``, "g");
58027
+ SENTENCE_BOUNDARY_RE = /[.!?] $/;
58028
+ DEFAULT_IDLE_TIMEOUT_SECONDS = 10 * 60;
58029
+ SHELL_BLOCK_PATTERN = /!`([^`]+)`/g;
58030
+ BUILT_IN_PROMPT_ARG_KEYS = [
58031
+ "SOURCE_BRANCH",
58032
+ "TARGET_BRANCH"
58033
+ ];
58034
+ PLACEHOLDER_PATTERN = /\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
58035
+ StructuredOutputError = class extends Error {
58036
+ tag;
58037
+ rawMatched;
58038
+ cause;
58039
+ commits;
58040
+ branch;
58041
+ preservedWorktreePath;
58042
+ sessionId;
58043
+ sessionFilePath;
58044
+ constructor(message, options) {
58045
+ super(message);
58046
+ this.name = "StructuredOutputError";
58047
+ this.tag = options.tag;
58048
+ this.rawMatched = options.rawMatched;
58049
+ this.cause = options.cause;
58050
+ this.commits = options.commits;
58051
+ this.branch = options.branch;
58052
+ this.preservedWorktreePath = options.preservedWorktreePath;
58053
+ this.sessionId = options.sessionId;
58054
+ this.sessionFilePath = options.sessionFilePath;
58055
+ }
58056
+ };
58057
+ TOOL_ARG_FIELDS = {
58058
+ Bash: "command",
58059
+ WebSearch: "query",
58060
+ WebFetch: "url",
58061
+ Agent: "description"
58062
+ };
58063
+ CURSOR_PRINT_PROMPT_MAX_BYTES = 120 * 1024;
58064
+ COPILOT_PRINT_PROMPT_MAX_BYTES = 120 * 1024;
58065
+ });
58066
+
58067
+ // src/services/settings.ts
58068
+ import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
58069
+ import { dirname as dirname11 } from "path";
58070
+ import * as z5 from "zod";
58071
+ import { eq as eq11 } from "drizzle-orm";
58072
+ function hostDefaults(logicalCpus) {
58073
+ return { ...DEFAULTS, burnConcurrency: resolveDefaultBurnConcurrency(logicalCpus) };
58074
+ }
58075
+ function readRawConfig(configFile) {
58076
+ if (!existsSync16(configFile))
58077
+ return {};
58078
+ try {
58079
+ const parsed = JSON.parse(readFileSync11(configFile, "utf8"));
58080
+ if (typeof parsed !== "object" || parsed === null)
58081
+ return {};
58082
+ return foldLegacyModelConfig(migrateCollapsedModelSteps(parsed));
58083
+ } catch {
58084
+ return {};
58085
+ }
58086
+ }
58087
+ function rawStepModels(fileRaw) {
58088
+ const raw = fileRaw.stepModels;
58089
+ return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
58090
+ }
58091
+ function stepModelFields(fileRaw) {
58092
+ const set7 = rawStepModels(fileRaw);
58093
+ return MODEL_STEPS.map((step4) => {
58094
+ const base = { key: `stepModels.${step4}`, restartRequired: false, scope: "global" };
58095
+ const v = set7[step4];
58096
+ if (typeof v === "string" && v !== "") {
58097
+ return { ...base, value: v, source: "file", editable: true };
58098
+ }
58099
+ return { ...base, value: DEFAULTS.stepModels[step4] ?? null, source: "default", editable: true };
58100
+ });
58101
+ }
58102
+ function projectOverrides(ctx, projectId) {
58103
+ const row = ctx.db.select({
58104
+ model: projects.model,
58105
+ sandbox: projects.sandbox,
58106
+ sandboxImage: projects.sandboxImage,
58107
+ sessionBranch: projects.sessionBranch,
58108
+ devCommand: projects.devCommand,
58109
+ setupCommand: projects.setupCommand,
58110
+ verifyCommands: projects.verifyCommands,
58111
+ knownFailures: projects.knownFailures,
58112
+ dbResetCommand: projects.dbResetCommand,
58113
+ driveSetupCommand: projects.driveSetupCommand,
58114
+ driveStopCommand: projects.driveStopCommand,
58115
+ driveInstructions: projects.driveInstructions,
58116
+ scenarioRunner: projects.scenarioRunner,
58117
+ docsCommitPrefix: projects.docsCommitPrefix
58118
+ }).from(projects).where(eq11(projects.id, projectId)).get();
58119
+ return {
58120
+ model: row?.model ?? null,
58121
+ sandbox: row?.sandbox ?? null,
58122
+ sandboxImage: row?.sandboxImage ?? null,
58123
+ sessionBranch: row?.sessionBranch ?? null,
58124
+ devCommand: row?.devCommand ?? null,
58125
+ setupCommand: row?.setupCommand ?? null,
58126
+ verifyCommands: row?.verifyCommands ?? null,
58127
+ knownFailures: row?.knownFailures ?? null,
58128
+ dbResetCommand: row?.dbResetCommand ?? null,
58129
+ driveSetupCommand: row?.driveSetupCommand ?? null,
58130
+ driveStopCommand: row?.driveStopCommand ?? null,
58131
+ driveInstructions: row?.driveInstructions ?? null,
58132
+ scenarioRunner: row?.scenarioRunner ?? null,
58133
+ docsCommitPrefix: row?.docsCommitPrefix ?? null
58134
+ };
58135
+ }
58136
+ function resolveField(desc5, layers) {
58137
+ const scoped7 = layers.overrides !== null;
58138
+ const scope5 = scoped7 && desc5.projectColumn ? "project" : "global";
58139
+ const base = { key: desc5.key, restartRequired: desc5.restartRequired, scope: scope5 };
58140
+ if (desc5.envVar) {
58141
+ const raw = layers.env[desc5.envVar];
58142
+ if (raw !== undefined && raw !== "") {
58143
+ return { ...base, value: desc5.parseEnv(raw), source: "env", editable: false };
58144
+ }
58145
+ }
58146
+ if (layers.overrides && desc5.projectColumn) {
58147
+ const ov = layers.overrides[desc5.projectColumn];
58148
+ if (ov !== null && ov !== "") {
58149
+ return { ...base, value: ov, source: "project", editable: true };
58150
+ }
58151
+ }
58152
+ if (desc5.configKey && Object.prototype.hasOwnProperty.call(layers.fileRaw, desc5.configKey)) {
58153
+ return { ...base, value: layers.fileRaw[desc5.configKey], source: "file", editable: true };
58154
+ }
58155
+ const value = desc5.configKey ? layers.defaults[desc5.configKey] ?? null : desc5.defaultValue ?? null;
58156
+ return { ...base, value, source: "default", editable: true };
58157
+ }
58158
+ function getSettings(ctx, projectId, io = {}) {
58159
+ const env = io.env ?? process.env;
58160
+ const fileRaw = readRawConfig(io.configFile ?? configPath());
58161
+ const overrides = projectId !== undefined ? projectOverrides(ctx, projectId) : null;
58162
+ const defaults = hostDefaults(io.logicalCpus ?? hostLogicalCpus());
58163
+ const visible = DESCRIPTORS.filter((d) => projectId !== undefined || d.configKey !== undefined);
58164
+ const fields = visible.map((d) => resolveField(d, { env, fileRaw, overrides, defaults }));
58165
+ return {
58166
+ projectId,
58167
+ fields: [...fields, ...stepModelFields(fileRaw)],
58168
+ discovery: discoverySnapshot(ctx)
58169
+ };
58170
+ }
58171
+ function updateSettings(ctx, input, io = {}) {
58172
+ const env = io.env ?? process.env;
58173
+ const configFile = io.configFile ?? configPath();
58174
+ if (input.key.startsWith("stepModels.")) {
58175
+ return updateStepModel(ctx, input, configFile, io);
58176
+ }
58177
+ const desc5 = DESCRIPTORS.find((d) => d.key === input.key);
58178
+ if (!desc5)
58179
+ throw new InvalidInputError(`unknown setting: ${input.key}`);
58180
+ if (desc5.envVar) {
58181
+ const raw = env[desc5.envVar];
58182
+ if (raw !== undefined && raw !== "") {
58183
+ throw new InvalidInputError(`${desc5.key} is set by environment variable ${desc5.envVar}; unset it to edit`);
58184
+ }
58185
+ }
58186
+ const toProject = input.projectId !== undefined && desc5.projectColumn !== undefined;
58187
+ if (input.value === null) {
58188
+ if (!toProject)
58189
+ return clearGlobal(ctx, desc5, input, configFile, io);
58190
+ const project3 = requireProjectById(ctx, input.projectId);
58191
+ ctx.db.update(projects).set({ [desc5.projectColumn]: null }).where(eq11(projects.id, project3.id)).run();
58192
+ recordHuman(ctx, project3.id, desc5.key, null);
58193
+ emitProject(ctx, project3.id, {
58194
+ type: "settings.updated",
58195
+ message: `${desc5.key} override cleared`,
58196
+ data: { key: desc5.key, scope: "project", value: null }
58197
+ });
58198
+ return field(getSettings(ctx, input.projectId, io), desc5.key);
58199
+ }
58200
+ const parsed = desc5.valueSchema.safeParse(input.value);
58201
+ if (!parsed.success) {
58202
+ throw new InvalidInputError(`invalid value for ${desc5.key}: ${parsed.error.issues[0]?.message}`);
58203
+ }
58204
+ const value = parsed.data;
58205
+ if (toProject) {
58206
+ const project3 = requireProjectById(ctx, input.projectId);
58207
+ ctx.db.update(projects).set({ [desc5.projectColumn]: String(value) }).where(eq11(projects.id, project3.id)).run();
58208
+ recordHuman(ctx, project3.id, desc5.key, String(value));
58209
+ emitProject(ctx, project3.id, {
58210
+ type: "settings.updated",
58211
+ message: `${desc5.key} override set to ${String(value)}`,
58212
+ data: { key: desc5.key, scope: "project", value }
58213
+ });
58214
+ return field(getSettings(ctx, input.projectId, io), desc5.key);
58215
+ }
58216
+ if (!desc5.configKey) {
58217
+ throw new InvalidInputError(`${desc5.key} is a per-project setting; provide a projectId`);
58218
+ }
58219
+ writeGlobal(configFile, desc5.configKey, value);
58220
+ ctx.config[desc5.configKey] = value;
58221
+ emitProject(ctx, GLOBAL_EVENT_KEY, {
58222
+ type: "settings.updated",
58223
+ message: `${desc5.key} set to ${describeValue(value)}`,
58224
+ data: { key: desc5.key, scope: "global", value }
58225
+ });
58226
+ return field(getSettings(ctx, input.projectId, io), desc5.key);
58227
+ }
58228
+ function clearGlobal(ctx, desc5, input, configFile, io) {
58229
+ if (!desc5.configKey || !GLOBAL_CLEARABLE_KEYS.has(desc5.key)) {
58230
+ throw new InvalidInputError(`${desc5.key} cannot be cleared`);
58231
+ }
58232
+ removeGlobal(configFile, desc5.configKey);
58233
+ delete ctx.config[desc5.configKey];
58234
+ emitProject(ctx, GLOBAL_EVENT_KEY, {
58235
+ type: "settings.updated",
58236
+ message: `${desc5.key} cleared`,
58237
+ data: { key: desc5.key, scope: "global", value: null }
58238
+ });
58239
+ return field(getSettings(ctx, input.projectId, io), desc5.key);
58240
+ }
58241
+ function describeValue(value) {
58242
+ return typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
58243
+ }
58244
+ function writeGlobal(configFile, configKey, value) {
58245
+ const raw = readRawConfig(configFile);
58246
+ raw[configKey] = value;
58247
+ saveRawConfig(configFile, raw);
58248
+ }
58249
+ function removeGlobal(configFile, configKey) {
58250
+ const raw = readRawConfig(configFile);
58251
+ delete raw[configKey];
58252
+ saveRawConfig(configFile, raw);
58253
+ }
58254
+ function saveRawConfig(configFile, raw) {
58255
+ mkdirSync9(dirname11(configFile), { recursive: true });
58256
+ writeFileSync7(configFile, `${JSON.stringify(raw, null, 2)}
58257
+ `);
58258
+ }
58259
+ function updateStepModel(ctx, input, configFile, io) {
58260
+ const step4 = input.key.slice("stepModels.".length);
58261
+ if (!STEP_SET.has(step4))
58262
+ throw new InvalidInputError(`unknown model step: ${step4}`);
58263
+ const modelStep = step4;
58264
+ let value = null;
58265
+ if (input.value !== null) {
58266
+ const parsed = z5.string().min(1).safeParse(input.value);
58267
+ if (!parsed.success) {
58268
+ throw new InvalidInputError(`invalid value for ${input.key}: ${parsed.error.issues[0]?.message}`);
58269
+ }
58270
+ value = parsed.data;
58271
+ }
58272
+ writeStepModel(configFile, modelStep, value);
58273
+ const stepModels = ctx.config.stepModels ?? {};
58274
+ if (value === null)
58275
+ delete stepModels[modelStep];
58276
+ else
58277
+ stepModels[modelStep] = value;
58278
+ ctx.config.stepModels = stepModels;
58279
+ emitProject(ctx, GLOBAL_EVENT_KEY, {
58280
+ type: "settings.updated",
58281
+ message: value === null ? `${input.key} override cleared` : `${input.key} set to ${value}`,
58282
+ data: { key: input.key, scope: "global", value }
58283
+ });
58284
+ return field(getSettings(ctx, input.projectId, io), input.key);
58285
+ }
58286
+ function writeStepModel(configFile, step4, value) {
58287
+ const raw = readRawConfig(configFile);
58288
+ const stepModels = { ...rawStepModels(raw) };
58289
+ if (value === null)
58290
+ delete stepModels[step4];
58291
+ else
58292
+ stepModels[step4] = value;
58293
+ raw.stepModels = stepModels;
58294
+ saveRawConfig(configFile, raw);
58295
+ }
58296
+ function warnLegacyGlobalImage(ctx) {
58297
+ const legacy = legacyGlobalImage(ctx.config.sandboxImage, allProjects(ctx).map((p) => p.id));
58298
+ if (legacy === null)
58299
+ return null;
58300
+ const message = legacyGlobalImageReason(legacy);
58301
+ console.warn(`runcastle: ${message}`);
58302
+ emitProject(ctx, GLOBAL_EVENT_KEY, {
58303
+ type: "settings.legacyImage",
58304
+ message,
58305
+ data: { key: "sandboxImage", scope: "global", value: legacy }
58306
+ });
58307
+ return legacy;
58308
+ }
58309
+ function field(view, key) {
58310
+ const f = view.fields.find((x) => x.key === key);
58311
+ if (!f)
58312
+ throw new InvalidInputError(`setting ${key} not visible in this scope`);
58313
+ return f;
58314
+ }
58315
+ var GLOBAL_EVENT_KEY = "global", idEnv = (raw) => raw, DESCRIPTORS, DEFAULTS, GLOBAL_CLEARABLE_KEYS, STEP_SET;
58316
+ var init_settings = __esm(() => {
58317
+ init_src();
58318
+ init_config_load();
58319
+ init_paths();
58320
+ init_model_discovery();
58321
+ init_schema();
58322
+ init_errors();
58323
+ init_events();
58324
+ init_findings();
58325
+ init_repo();
58326
+ init_sandbox_image();
58327
+ DESCRIPTORS = [
58328
+ {
58329
+ key: "serverPort",
58330
+ configKey: "serverPort",
58331
+ envVar: "RUNCASTLE_SERVER_PORT",
58332
+ restartRequired: true,
58333
+ valueSchema: z5.number().int().positive(),
58334
+ parseEnv: (raw) => Number(raw)
58335
+ },
58336
+ {
58337
+ key: "model",
58338
+ configKey: "model",
58339
+ envVar: "RUNCASTLE_MODEL",
58340
+ projectColumn: "model",
58341
+ restartRequired: false,
58342
+ valueSchema: z5.string().min(1),
58343
+ parseEnv: idEnv
58344
+ },
58345
+ {
58346
+ key: "models",
58347
+ configKey: "models",
58348
+ restartRequired: false,
58349
+ valueSchema: z5.array(ModelEntry),
58350
+ parseEnv: idEnv
58351
+ },
58352
+ {
58353
+ key: "sandbox",
58354
+ configKey: "sandbox",
58355
+ envVar: "RUNCASTLE_SANDBOX",
58356
+ projectColumn: "sandbox",
58357
+ restartRequired: false,
58358
+ valueSchema: z5.enum(["docker", "podman", "noSandbox"]),
58359
+ parseEnv: idEnv
58360
+ },
58361
+ {
58362
+ key: "sandboxImage",
58363
+ configKey: "sandboxImage",
58364
+ envVar: "RUNCASTLE_SANDBOX_IMAGE",
58365
+ projectColumn: "sandboxImage",
58366
+ restartRequired: false,
58367
+ valueSchema: z5.string().min(1),
58368
+ parseEnv: idEnv
58369
+ },
58370
+ {
58371
+ key: "sessionMcp",
58372
+ configKey: "sessionMcp",
58373
+ envVar: "RUNCASTLE_SESSION_MCP",
58374
+ restartRequired: false,
58375
+ valueSchema: z5.enum(["inherit", "runcastleOnly"]),
58376
+ parseEnv: idEnv
58377
+ },
58378
+ {
58379
+ key: "burnConcurrency",
58380
+ configKey: "burnConcurrency",
58381
+ envVar: "RUNCASTLE_BURN_CONCURRENCY",
58382
+ restartRequired: false,
58383
+ valueSchema: z5.number().int().min(1).max(8),
58384
+ parseEnv: (raw) => Number(raw)
58385
+ },
58386
+ {
58387
+ key: "burnMaxIterations",
58388
+ configKey: "burnMaxIterations",
58389
+ envVar: "RUNCASTLE_BURN_MAX_ITERATIONS",
58390
+ restartRequired: false,
58391
+ valueSchema: z5.number().int().min(1).max(10),
58392
+ parseEnv: (raw) => Number(raw)
58393
+ },
58394
+ {
58395
+ key: "burnAttempts",
58396
+ configKey: "burnAttempts",
58397
+ envVar: "RUNCASTLE_BURN_ATTEMPTS",
58398
+ restartRequired: false,
58399
+ valueSchema: z5.number().int().min(1).max(5),
58400
+ parseEnv: (raw) => Number(raw)
58401
+ },
58402
+ {
58403
+ key: "burnConflictAttempts",
58404
+ configKey: "burnConflictAttempts",
58405
+ envVar: "RUNCASTLE_BURN_CONFLICT_ATTEMPTS",
58406
+ restartRequired: false,
58407
+ valueSchema: z5.number().int().min(0).max(3),
58408
+ parseEnv: (raw) => Number(raw)
58409
+ },
58410
+ {
58411
+ key: "burnCpus",
58412
+ configKey: "burnCpus",
58413
+ envVar: "RUNCASTLE_BURN_CPUS",
58414
+ restartRequired: false,
58415
+ valueSchema: z5.number().positive().max(256),
58416
+ parseEnv: (raw) => Number(raw)
58417
+ },
58418
+ {
58419
+ key: "setupCommand",
58420
+ configKey: "setupCommand",
58421
+ envVar: "RUNCASTLE_SETUP_COMMAND",
58422
+ projectColumn: "setupCommand",
58423
+ restartRequired: false,
58424
+ valueSchema: z5.string().min(1),
58425
+ parseEnv: idEnv
58426
+ },
58427
+ {
58428
+ key: "verifyCommands",
58429
+ configKey: "verifyCommands",
58430
+ envVar: "RUNCASTLE_VERIFY_COMMANDS",
58431
+ projectColumn: "verifyCommands",
58432
+ restartRequired: false,
58433
+ valueSchema: z5.string().min(1),
58434
+ parseEnv: idEnv
58435
+ },
58436
+ {
58437
+ key: "knownFailures",
58438
+ configKey: "knownFailures",
58439
+ envVar: "RUNCASTLE_KNOWN_FAILURES",
58440
+ projectColumn: "knownFailures",
58441
+ restartRequired: false,
58442
+ valueSchema: z5.string().min(1),
58443
+ parseEnv: idEnv
58444
+ },
58445
+ {
58446
+ key: "devCommand",
58447
+ projectColumn: "devCommand",
58448
+ restartRequired: false,
58449
+ valueSchema: z5.string().min(1),
58450
+ parseEnv: idEnv
58451
+ },
58452
+ {
58453
+ key: "sessionBranch",
58454
+ projectColumn: "sessionBranch",
58455
+ restartRequired: false,
58456
+ valueSchema: z5.string().min(1),
58457
+ parseEnv: idEnv
58458
+ },
58459
+ {
58460
+ key: "docsCommitPrefix",
58461
+ projectColumn: "docsCommitPrefix",
58462
+ restartRequired: false,
58463
+ valueSchema: z5.string().min(1),
58464
+ parseEnv: idEnv,
58465
+ defaultValue: DEFAULT_DOCS_COMMIT_PREFIX
58466
+ },
58467
+ {
58468
+ key: "dbResetCommand",
58469
+ projectColumn: "dbResetCommand",
58470
+ restartRequired: false,
58471
+ valueSchema: z5.string().min(1),
58472
+ parseEnv: idEnv
58473
+ },
58474
+ {
58475
+ key: "driveSetupCommand",
58476
+ projectColumn: "driveSetupCommand",
58477
+ restartRequired: false,
58478
+ valueSchema: z5.string().min(1),
58479
+ parseEnv: idEnv
58480
+ },
58481
+ {
58482
+ key: "driveStopCommand",
58483
+ projectColumn: "driveStopCommand",
58484
+ restartRequired: false,
58485
+ valueSchema: z5.string().min(1),
58486
+ parseEnv: idEnv
58487
+ },
58488
+ {
58489
+ key: "driveInstructions",
58490
+ projectColumn: "driveInstructions",
58491
+ restartRequired: false,
58492
+ valueSchema: z5.string().min(1),
58493
+ parseEnv: idEnv
58494
+ },
58495
+ {
58496
+ key: "scenarioRunner",
58497
+ projectColumn: "scenarioRunner",
58498
+ restartRequired: false,
58499
+ valueSchema: z5.string().min(1),
58500
+ parseEnv: idEnv
58501
+ }
58502
+ ];
58503
+ DEFAULTS = RuncastleConfig.parse({});
58504
+ GLOBAL_CLEARABLE_KEYS = new Set(["sandboxImage"]);
58505
+ STEP_SET = new Set(MODEL_STEPS);
58506
+ });
58507
+
58508
+ // src/services/setup.ts
58509
+ import { copyFileSync as copyFileSync2, existsSync as existsSync17, mkdirSync as mkdirSync10, readFileSync as readFileSync12, readdirSync as readdirSync6, writeFileSync as writeFileSync8 } from "fs";
58510
+ import { dirname as dirname12, join as join20 } from "path";
58511
+ async function writeGitIdentity(exec3, identity4) {
58512
+ const name = identity4.name.trim();
58513
+ const email = identity4.email.trim();
58514
+ if (name.length === 0)
58515
+ throw new InvalidInputError("git user.name cannot be empty");
58516
+ if (!email.includes("@"))
58517
+ throw new InvalidInputError("git user.email must be an email address");
58518
+ await exec3("git", ["config", "--global", "user.name", name]);
58519
+ await exec3("git", ["config", "--global", "user.email", email]);
58520
+ return gitIdentityProbe(exec3);
58521
+ }
58522
+ function upsertEnvVar(content, key, value) {
58523
+ const line = `${key}=${value}`;
58524
+ const lines2 = content.length === 0 ? [] : content.replace(/\n$/, "").split(`
58663
58525
  `);
58664
- for (let i = lines2.length - 1;i >= 0; i--) {
58665
- const line = lines2[i];
58666
- if (!line.startsWith("{"))
58667
- continue;
58668
- try {
58669
- const obj = JSON.parse(line);
58670
- if (obj.type === "assistant" && obj.message?.usage) {
58671
- const u = obj.message.usage;
58672
- if (typeof u.input_tokens === "number" && typeof u.cache_creation_input_tokens === "number" && typeof u.cache_read_input_tokens === "number" && typeof u.output_tokens === "number") {
58673
- return {
58674
- inputTokens: u.input_tokens,
58675
- cacheCreationInputTokens: u.cache_creation_input_tokens,
58676
- cacheReadInputTokens: u.cache_read_input_tokens,
58677
- outputTokens: u.output_tokens
58678
- };
58679
- }
58680
- }
58681
- } catch {}
58526
+ const matcher = new RegExp(`^(export\\s+)?${key}=`);
58527
+ let replaced = false;
58528
+ const next4 = lines2.map((l) => {
58529
+ if (matcher.test(l)) {
58530
+ replaced = true;
58531
+ const exportPrefix = l.startsWith("export ") ? "export " : "";
58532
+ return `${exportPrefix}${line}`;
58682
58533
  }
58683
- return;
58534
+ return l;
58535
+ });
58536
+ if (!replaced)
58537
+ next4.push(line);
58538
+ return `${next4.join(`
58539
+ `)}
58540
+ `;
58541
+ }
58542
+ async function saveAfkCredential(io, rawValue, runtime5 = DEFAULT_RUNTIME) {
58543
+ const spec = RUNTIME_SPECS[runtime5];
58544
+ const value = rawValue.trim();
58545
+ if (value.length === 0)
58546
+ throw new InvalidInputError(`${spec.label} ${spec.afkNoun} cannot be empty`);
58547
+ if (/[\r\n]/.test(value)) {
58548
+ throw new InvalidInputError(`${spec.label} ${spec.afkNoun} cannot contain a newline`);
58684
58549
  }
58685
- });
58686
- var init_dist = __esm(() => {
58687
- init_chunk_DJRHWPEH();
58688
- init_chunk_VOG34SRF();
58689
- init_chunk_BIWNFKGV();
58690
- init_chunk_62WN33RK();
58691
- init_chunk_NGBM7T3E();
58692
- init_chunk_NGBM7T3E();
58693
- createRequire9(import.meta.url);
58694
- AgentStreamEmitter = class extends Context_exports.Tag("AgentStreamEmitter")() {
58550
+ io.write(upsertEnvVar(io.read(), spec.afkKey, value));
58551
+ return io.verify(value);
58552
+ }
58553
+ function seedRuntimeFor(ready) {
58554
+ return ready.includes(DEFAULT_RUNTIME) ? DEFAULT_RUNTIME : ready[0];
58555
+ }
58556
+ function seedModelDefaults(ctx, ready, io = {}) {
58557
+ const runtime5 = seedRuntimeFor(ready);
58558
+ if (!runtime5)
58559
+ return null;
58560
+ const pair = RUNTIME_DEFAULT_MODELS[runtime5];
58561
+ const write4 = (key, value) => {
58562
+ try {
58563
+ updateSettings(ctx, { key, value }, io);
58564
+ return value;
58565
+ } catch (err) {
58566
+ if (err instanceof InvalidInputError)
58567
+ return;
58568
+ throw err;
58569
+ }
58695
58570
  };
58696
- MARKED_SHELL_BLOCK_PATTERN = new RegExp(`!${SHELL_BLOCK_MARKER}\`([^\`]+)\``, "g");
58697
- SENTENCE_BOUNDARY_RE = /[.!?] $/;
58698
- DEFAULT_IDLE_TIMEOUT_SECONDS = 10 * 60;
58699
- SHELL_BLOCK_PATTERN = /!`([^`]+)`/g;
58700
- BUILT_IN_PROMPT_ARG_KEYS = [
58701
- "SOURCE_BRANCH",
58702
- "TARGET_BRANCH"
58703
- ];
58704
- PLACEHOLDER_PATTERN = /\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
58705
- StructuredOutputError = class extends Error {
58706
- tag;
58707
- rawMatched;
58708
- cause;
58709
- commits;
58710
- branch;
58711
- preservedWorktreePath;
58712
- sessionId;
58713
- sessionFilePath;
58714
- constructor(message, options) {
58715
- super(message);
58716
- this.name = "StructuredOutputError";
58717
- this.tag = options.tag;
58718
- this.rawMatched = options.rawMatched;
58719
- this.cause = options.cause;
58720
- this.commits = options.commits;
58721
- this.branch = options.branch;
58722
- this.preservedWorktreePath = options.preservedWorktreePath;
58723
- this.sessionId = options.sessionId;
58724
- this.sessionFilePath = options.sessionFilePath;
58571
+ const model = write4("model", pair.flagship);
58572
+ const smoke = write4("stepModels.smoke", pair.smoke);
58573
+ return {
58574
+ runtime: runtime5,
58575
+ ...model ? { model } : {},
58576
+ ...smoke ? { smoke } : {}
58577
+ };
58578
+ }
58579
+ function runtimeInstallGuide(platform) {
58580
+ switch (platform) {
58581
+ case "win32":
58582
+ return {
58583
+ command: "winget install RedHat.Podman",
58584
+ note: "Then initialize the VM: podman machine init && podman machine start"
58585
+ };
58586
+ case "darwin":
58587
+ return {
58588
+ command: "brew install podman",
58589
+ note: "Then initialize the VM: podman machine init && podman machine start"
58590
+ };
58591
+ default:
58592
+ return {
58593
+ command: "sudo apt install podman # or: sudo dnf install podman / sudo pacman -S podman",
58594
+ note: "Podman is rootless on Linux \u2014 no machine step needed."
58595
+ };
58596
+ }
58597
+ }
58598
+ async function resolveRuntime(exec3, preferred) {
58599
+ const present = async (bin) => {
58600
+ const out = await exec3(bin, ["--version"]);
58601
+ return out.ok && out.code === 0;
58602
+ };
58603
+ if (await present(preferred))
58604
+ return preferred;
58605
+ const other = preferred === "docker" ? "podman" : "docker";
58606
+ if (await present(other))
58607
+ return other;
58608
+ return preferred;
58609
+ }
58610
+ function terminalSpec(kind) {
58611
+ if (kind === "setup-token")
58612
+ return { cmd: "claude", args: ["setup-token"] };
58613
+ for (const spec of Object.values(RUNTIME_SPECS)) {
58614
+ if (kind === LOGIN_TERMINAL_KIND[spec.runtime])
58615
+ return { cmd: spec.bin, args: spec.loginArgs };
58616
+ }
58617
+ throw new InvalidInputError(`no terminal command for ${kind}`);
58618
+ }
58619
+ function refreshSandcastleConfig(templateDir, targetDir) {
58620
+ const dir = join20(targetDir, ".sandcastle");
58621
+ mkdirSync10(dir, { recursive: true });
58622
+ for (const name of readdirSync6(templateDir)) {
58623
+ copyFileSync2(join20(templateDir, name), join20(dir, name));
58624
+ }
58625
+ return dir;
58626
+ }
58627
+ function prepareSandboxBuildContext(templateDir = sandcastleTemplateDir(), target = sandboxBuildDir()) {
58628
+ mkdirSync10(target, { recursive: true });
58629
+ return refreshSandcastleConfig(templateDir, target);
58630
+ }
58631
+ function createCredentialVerifier(exec3, runtime5 = DEFAULT_RUNTIME) {
58632
+ const spec = RUNTIME_SPECS[runtime5];
58633
+ return async (value) => {
58634
+ if (value.length < 8) {
58635
+ return {
58636
+ valid: false,
58637
+ detail: `${spec.afkNoun} looks malformed (too short) \u2014 saved to ~/.runcastle/.env anyway`,
58638
+ fix: `${spec.afkFix}. It starts with \`sk-\`.`
58639
+ };
58640
+ }
58641
+ const out = await exec3(spec.bin, ["--version"]);
58642
+ if (!out.ok) {
58643
+ return {
58644
+ valid: false,
58645
+ detail: `${spec.afkNoun} saved to ~/.runcastle/.env, but runcastle could not launch \`${spec.bin}\` to verify it. ` + "That is a PATH problem in this server process, not a missing install \u2014 a terminal that finds " + `\`${spec.bin}\` proves nothing about the PATH runcastle was started with.`,
58646
+ fix: `Quit runcastle and start it again from a terminal where \`${spec.bin} --version\` works. ` + `If it still fails, pin the path: set ${spec.binOverrideEnv} to the full path from ` + `\`where.exe ${spec.bin}\` (Windows) or \`which ${spec.bin}\` (macOS/Linux), then restart runcastle.`
58647
+ };
58648
+ }
58649
+ if (out.code !== 0) {
58650
+ const why = (out.stderr.trim() || out.stdout.trim()).split(`
58651
+ `)[0] ?? "";
58652
+ return {
58653
+ valid: false,
58654
+ detail: `${spec.afkNoun} saved to ~/.runcastle/.env, but \`${spec.bin} --version\` exited ${out.code}` + `${why ? `: ${why}` : " with no output"}.`,
58655
+ fix: `Run \`${spec.bin} --version\` yourself and fix what it reports \u2014 the ${spec.label} install is broken, not the ${spec.afkNoun}.`
58656
+ };
58725
58657
  }
58658
+ return { valid: true, detail: `${spec.afkNoun} captured to ~/.runcastle/.env` };
58726
58659
  };
58727
- TOOL_ARG_FIELDS = {
58728
- Bash: "command",
58729
- WebSearch: "query",
58730
- WebFetch: "url",
58731
- Agent: "description"
58660
+ }
58661
+ function fileAfkTokenIo(exec3, runtime5 = DEFAULT_RUNTIME) {
58662
+ const path2 = envPath();
58663
+ return {
58664
+ read: () => existsSync17(path2) ? readFileSync12(path2, "utf8") : "",
58665
+ write: (content) => {
58666
+ mkdirSync10(dirname12(path2), { recursive: true });
58667
+ writeFileSync8(path2, content, "utf8");
58668
+ },
58669
+ verify: createCredentialVerifier(exec3, runtime5)
58732
58670
  };
58733
- CURSOR_PRINT_PROMPT_MAX_BYTES = 120 * 1024;
58734
- COPILOT_PRINT_PROMPT_MAX_BYTES = 120 * 1024;
58671
+ }
58672
+ var AFK_TOKEN_KEY, CODEX_API_KEY, RUNTIME_AUTH_KEY, RUNTIME_AUTH_SETUP_HINT, LOGIN_TERMINAL_KIND;
58673
+ var init_setup = __esm(() => {
58674
+ init_src();
58675
+ init_paths();
58676
+ init_doctor();
58677
+ init_errors();
58678
+ init_asset_paths();
58679
+ init_settings();
58680
+ AFK_TOKEN_KEY = RUNTIME_SPECS["claude-code"].afkKey;
58681
+ CODEX_API_KEY = RUNTIME_SPECS.codex.afkKey;
58682
+ RUNTIME_AUTH_KEY = {
58683
+ "claude-code": AFK_TOKEN_KEY,
58684
+ codex: CODEX_API_KEY
58685
+ };
58686
+ RUNTIME_AUTH_SETUP_HINT = {
58687
+ "claude-code": RUNTIME_SPECS["claude-code"].afkFix,
58688
+ codex: `Run \`${RUNTIME_SPECS.codex.loginCommand}\` on this host, then burn again`
58689
+ };
58690
+ LOGIN_TERMINAL_KIND = {
58691
+ "claude-code": "claude-login",
58692
+ codex: "codex-login"
58693
+ };
58694
+ });
58695
+
58696
+ // src/services/agent-stream.ts
58697
+ function beginTranscript(ticketId) {
58698
+ transcripts.set(ticketId, { live: true, chunks: [], nextIndex: 0, bytes: 0 });
58699
+ publishLive({ kind: "transcript", ticketId });
58700
+ }
58701
+ function appendTranscript(ticketId, chunk) {
58702
+ const t = transcripts.get(ticketId);
58703
+ if (!t)
58704
+ return;
58705
+ const full = { ...chunk, i: t.nextIndex, ts: chunk.ts ?? Date.now() };
58706
+ t.nextIndex += 1;
58707
+ t.chunks.push(full);
58708
+ t.bytes += full.text.length;
58709
+ while (t.chunks.length > MAX_CHUNKS || t.bytes > MAX_BYTES && t.chunks.length > 1) {
58710
+ const dropped = t.chunks.shift();
58711
+ if (!dropped)
58712
+ break;
58713
+ t.bytes -= dropped.text.length;
58714
+ }
58715
+ publishLive({ kind: "transcript", ticketId });
58716
+ }
58717
+ function endTranscript(ticketId) {
58718
+ const t = transcripts.get(ticketId);
58719
+ if (t)
58720
+ t.live = false;
58721
+ publishLive({ kind: "transcript", ticketId });
58722
+ }
58723
+ function readTranscript(ticketId, after3 = -1) {
58724
+ const t = transcripts.get(ticketId);
58725
+ if (!t)
58726
+ return { live: false, chunks: [], firstIndex: 0, nextIndex: 0 };
58727
+ return {
58728
+ live: t.live,
58729
+ chunks: after3 < 0 ? [...t.chunks] : t.chunks.filter((c) => c.i > after3),
58730
+ firstIndex: t.chunks[0]?.i ?? t.nextIndex,
58731
+ nextIndex: t.nextIndex
58732
+ };
58733
+ }
58734
+ var MAX_CHUNKS = 4000, MAX_BYTES = 1500000, transcripts;
58735
+ var init_agent_stream = __esm(() => {
58736
+ init_bus();
58737
+ transcripts = new Map;
58735
58738
  });
58736
58739
 
58737
58740
  // src/workflows/burn-guard.ts
@@ -59031,252 +59034,8 @@ var init_recorder_reap = __esm(() => {
59031
59034
  };
59032
59035
  });
59033
59036
 
59034
- // src/workflows/review-gates.ts
59035
- var exports_review_gates = {};
59036
- __export(exports_review_gates, {
59037
- withThrowawayBranch: () => withThrowawayBranch,
59038
- timeoutReason: () => timeoutReason,
59039
- runReviewGates: () => runReviewGates,
59040
- reviewGateBranch: () => reviewGateBranch,
59041
- parseVerifyCommands: () => parseVerifyCommands,
59042
- headline: () => headline,
59043
- execWithTimeout: () => execWithTimeout,
59044
- errorText: () => errorText,
59045
- errorDetail: () => errorDetail,
59046
- burnGateSandbox: () => burnGateSandbox,
59047
- SandboxSetupError: () => SandboxSetupError,
59048
- GATE_COMMAND_TIMEOUT_MS: () => GATE_COMMAND_TIMEOUT_MS
59049
- });
59050
- import { mkdirSync as mkdirSync11, rmSync as rmSync3, writeFileSync as writeFileSync9 } from "fs";
59051
- import { stripVTControlCharacters as stripVTControlCharacters2 } from "util";
59052
- function reviewGateBranch(ticketId) {
59053
- return `runcastle/gates/${ticketId}`;
59054
- }
59055
- function parseVerifyCommands(verifyCommands) {
59056
- return (verifyCommands ?? "").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
59057
- }
59058
- function errorText(err) {
59059
- return err instanceof Error ? err.message : String(err);
59060
- }
59061
- function errorDetail(err) {
59062
- if (err instanceof SandboxSetupError)
59063
- return `${err.message}
59064
-
59065
- ${stripVTControlCharacters2(err.output)}`;
59066
- return err instanceof Error ? err.stack ?? err.message : String(err);
59067
- }
59068
- function headline(text3) {
59069
- return text3.split(/\r?\n/).find((line) => line.trim())?.trim() ?? "unknown error";
59070
- }
59071
- async function withThrowawayBranch(repoPath, branch, sha, use) {
59072
- const discardBranch = async () => {
59073
- await cleanupBurnWorktree(repoPath, branch);
59074
- await deleteTempBranch(repoPath, branch);
59075
- };
59076
- try {
59077
- await discardBranch();
59078
- await pinBranchAt(repoPath, branch, sha);
59079
- await excludeBurnWorktrees(repoPath);
59080
- return await use();
59081
- } finally {
59082
- await discardBranch();
59083
- }
59084
- }
59085
- async function execWithTimeout(sandbox3, command, timeoutMs) {
59086
- let timer;
59087
- const timedOut = new Promise((done10) => {
59088
- timer = setTimeout(() => done10("timeout"), timeoutMs);
59089
- });
59090
- try {
59091
- return await Promise.race([sandbox3.exec(command), timedOut]);
59092
- } finally {
59093
- clearTimeout(timer);
59094
- }
59095
- }
59096
- async function runSandboxSetup(exec3, setup, timeoutMs) {
59097
- const streamed = [];
59098
- const result = await execWithTimeout({ exec: (command) => exec3(command, { onLine: (line) => streamed.push(line) }) }, setup, timeoutMs);
59099
- if (result === "timeout") {
59100
- throw new SandboxSetupError(`the sync-and-install setup ${timeoutReason(timeoutMs)}`, streamed.join(`
59101
- `));
59102
- }
59103
- if (result.exitCode !== 0) {
59104
- throw new SandboxSetupError(`the sync-and-install setup exited ${result.exitCode}`, [result.stdout, result.stderr].filter(Boolean).join(`
59105
- `));
59106
- }
59107
- }
59108
- function timeoutReason(timeoutMs) {
59109
- return `timed out after ${Math.round(timeoutMs / 60000)} minutes`;
59110
- }
59111
- async function runReviewGates(input) {
59112
- const { config: config2, project: project3, ticketId, sha } = input;
59113
- const commands = parseVerifyCommands(resolvePreparedSettings(config2, project3).verifyCommands);
59114
- if (commands.length === 0)
59115
- return { status: "none_configured" };
59116
- const withSandbox = input.deps?.withSandbox ?? burnGateSandbox(config2, project3);
59117
- const timeoutMs = input.deps?.commandTimeoutMs ?? GATE_COMMAND_TIMEOUT_MS;
59118
- const branch = reviewGateBranch(ticketId);
59119
- const results = [];
59120
- try {
59121
- rmSync3(reviewGateLogDir(ticketId), { recursive: true, force: true });
59122
- mkdirSync11(reviewGateLogDir(ticketId), { recursive: true });
59123
- await withThrowawayBranch(project3.repoPath, branch, sha, async () => {
59124
- while (results.length < commands.length) {
59125
- await withSandbox(branch, async (sandbox3) => {
59126
- for (const [i, command] of commands.entries()) {
59127
- if (i < results.length)
59128
- continue;
59129
- const { result, stillRunning } = await runGateCommand(sandbox3, command, ticketId, `${i}.log`, timeoutMs);
59130
- results.push(result);
59131
- if (stillRunning)
59132
- return;
59133
- }
59134
- });
59135
- }
59136
- });
59137
- return { status: "ran", commit: sha, commands: results };
59138
- } catch (err) {
59139
- if (results.length > 0) {
59140
- const detail = errorDetail(err);
59141
- const reason = `the gate sandbox could not be reopened: ${headline(errorText(err))}`;
59142
- for (const [i, command] of commands.entries()) {
59143
- if (i < results.length)
59144
- continue;
59145
- writeFileSync9(reviewGateLogPath(ticketId, `${i}.log`), `${detail}
59146
- `);
59147
- results.push({ command, outcome: "couldnt_run", exitCode: null, reason, log: `${i}.log` });
59148
- }
59149
- return { status: "ran", commit: sha, commands: results };
59150
- }
59151
- return {
59152
- status: "couldnt_run",
59153
- commit: sha,
59154
- reason: `the gate sandbox could not be set up: ${headline(errorText(err))}`,
59155
- log: writeRunLog(ticketId, err)
59156
- };
59157
- }
59158
- }
59159
- function writeRunLog(ticketId, err) {
59160
- try {
59161
- writeFileSync9(reviewGateLogPath(ticketId, "run.log"), `${errorDetail(err)}
59162
- `);
59163
- return "run.log";
59164
- } catch {
59165
- return null;
59166
- }
59167
- }
59168
- async function runGateCommand(sandbox3, command, ticketId, log6, timeoutMs) {
59169
- const logPath = reviewGateLogPath(ticketId, log6);
59170
- try {
59171
- const result = await execWithTimeout(sandbox3, command, timeoutMs);
59172
- if (result === "timeout") {
59173
- const reason = timeoutReason(timeoutMs);
59174
- writeFileSync9(logPath, `${reason}
59175
- `);
59176
- return {
59177
- result: { command, outcome: "couldnt_run", exitCode: null, reason, log: log6 },
59178
- stillRunning: true
59179
- };
59180
- }
59181
- writeFileSync9(logPath, [result.stdout, result.stderr].filter(Boolean).join(`
59182
- `));
59183
- return {
59184
- result: result.exitCode === 0 ? { command, outcome: "passed", exitCode: 0, log: log6 } : { command, outcome: "failed", exitCode: result.exitCode, log: log6 },
59185
- stillRunning: false
59186
- };
59187
- } catch (err) {
59188
- const reason = `could not start: ${headline(errorText(err))}`;
59189
- writeFileSync9(logPath, `${errorText(err)}
59190
- `);
59191
- return {
59192
- result: { command, outcome: "couldnt_run", exitCode: null, reason, log: log6 },
59193
- stillRunning: false
59194
- };
59195
- }
59196
- }
59197
- function burnGateSandbox(config2, project3, deps = {}) {
59198
- const open3 = deps.open ?? createSandbox;
59199
- const setupTimeoutMs = deps.setupTimeoutMs ?? SETUP_HOOK_TIMEOUT_MS;
59200
- return (branch, use) => {
59201
- const allocator = resolveBurnCacheMode(config2) === "volume" ? getBurnSlotAllocator(config2.burnConcurrency) : undefined;
59202
- return withBurnCacheSlot(allocator, async (slot) => {
59203
- if (slot !== undefined) {
59204
- await ensureBurnCacheVolume({
59205
- engine: config2.sandbox === "podman" ? "podman" : "docker",
59206
- imageName: resolveSandboxImage(config2, project3),
59207
- projectId: project3.id,
59208
- exec: createSystemExec({ cwd: project3.repoPath })
59209
- });
59210
- }
59211
- const workspaceMode = resolveBurnWorkspaceMode(slot === undefined ? { ...config2, burnCache: "off" } : config2);
59212
- const toolchain = readRepoToolchain(project3.repoPath);
59213
- const pm = detectPackageManager(toolchain);
59214
- const setupCommand = resolveSetupCommand(toolchain, resolvePreparedSettings(config2, project3).setupCommand);
59215
- const cache = buildBurnCacheMounts(slot, project3.id, config2.sandbox, pm);
59216
- const onHost2 = config2.sandbox === "noSandbox";
59217
- for (const mount of cache.mounts) {
59218
- if ("hostPath" in mount)
59219
- mkdirSync11(mount.hostPath, { recursive: true });
59220
- }
59221
- const setup = slot !== undefined ? buildSlotSetupCommand(slot, branch, setupCommand, pm, buildSlotStamp(resolveSandboxImage(config2, project3), toolchain.packageManagerField)) : workspaceMode === "isolated" ? buildIsolatedSetupCommand(branch, setupCommand, pm) : setupCommand;
59222
- const cwd = slot !== undefined ? slotRepoPath(slot) : workspaceMode === "isolated" ? ISOLATED_REPO_PATH : undefined;
59223
- const lane = branch;
59224
- const sandbox3 = await open3({
59225
- branch,
59226
- sandbox: selectSandbox(config2, project3, cache.mounts, cache.env, {
59227
- onChildSpawn: registerHostChildren(lane, {})
59228
- }),
59229
- cwd: project3.repoPath
59230
- });
59231
- let running3 = 0;
59232
- const exec3 = async (command, opts) => {
59233
- running3++;
59234
- try {
59235
- return await sandbox3.exec(command, opts);
59236
- } finally {
59237
- running3--;
59238
- }
59239
- };
59240
- try {
59241
- if (setup) {
59242
- const script = onHost2 ? setup : `git config --global --add safe.directory '*' && ${setup}`;
59243
- await runSandboxSetup(exec3, script, setupTimeoutMs);
59244
- }
59245
- return await use({
59246
- exec: (command) => exec3(command, cwd ? { cwd } : {})
59247
- });
59248
- } finally {
59249
- if (running3 > 0)
59250
- await killRegistry().killAndWait(lane);
59251
- killRegistry().release(lane);
59252
- await sandbox3.close();
59253
- }
59254
- });
59255
- };
59256
- }
59257
- var GATE_COMMAND_TIMEOUT_MS, SandboxSetupError;
59258
- var init_review_gates2 = __esm(() => {
59259
- init_dist();
59260
- init_src();
59261
- init_paths();
59262
- init_system_exec();
59263
- init_git();
59264
- init_burn_cache();
59265
- init_kill_registry();
59266
- init_ticket_burner();
59267
- GATE_COMMAND_TIMEOUT_MS = SETUP_HOOK_TIMEOUT_MS;
59268
- SandboxSetupError = class SandboxSetupError extends Error {
59269
- output;
59270
- constructor(message, output) {
59271
- super(message);
59272
- this.output = output;
59273
- this.name = "SandboxSetupError";
59274
- }
59275
- };
59276
- });
59277
-
59278
59037
  // src/workflows/review-ticket.ts
59279
- import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync13, readdirSync as readdirSync7, renameSync, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "fs";
59038
+ import { existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync13, readdirSync as readdirSync7, renameSync, rmSync as rmSync3, writeFileSync as writeFileSync9 } from "fs";
59280
59039
  import { spawnSync } from "child_process";
59281
59040
  import { basename as basename4, dirname as dirname13, join as join23 } from "path";
59282
59041
  function reviewTemplatePath(ticket) {
@@ -59415,10 +59174,10 @@ function composeReviewDigest(resolution, agentDigest) {
59415
59174
  if (resolution.reviewVerdict !== "unverified")
59416
59175
  return agentDigest;
59417
59176
  const mode = resolution.reviewMode;
59418
- const headline2 = `${mode ? `${mode} mode` : "mode unrecorded"} \xB7 ` + `${mode ? `${mode.toUpperCase()} FAILED` : "NO DECLARATION"} \xB7 nothing verified` + (resolution.reason ? ` \u2014 ${resolution.reason}` : "");
59419
- return agentDigest ? `${headline2}
59177
+ const headline = `${mode ? `${mode} mode` : "mode unrecorded"} \xB7 ` + `${mode ? `${mode.toUpperCase()} FAILED` : "NO DECLARATION"} \xB7 nothing verified` + (resolution.reason ? ` \u2014 ${resolution.reason}` : "");
59178
+ return agentDigest ? `${headline}
59420
59179
 
59421
- ${agentDigest}` : headline2;
59180
+ ${agentDigest}` : headline;
59422
59181
  }
59423
59182
  function buildDriveInstructions(instructions) {
59424
59183
  const text3 = instructions?.trim();
@@ -59475,7 +59234,7 @@ function buildGateNotes(gateRun, ticketId, config2, project3) {
59475
59234
  out.push(`The server could not run the gates on the feature branch${gateRun.commit ? ` at \`${shortCommit(gateRun.commit)}\`` : ""}: ${gateRun.reason}.`, ...gateRun.log ? [`Its captured output is at \`${reviewGateLogPath(ticketId, gateRun.log)}\`.`] : [], "", "That is an observation about the environment, not a defect against the branch: report it as an observation, say plainly in your digest that the gates did not run, and carry on with the review. Never describe the gates as passed.");
59476
59235
  break;
59477
59236
  case "ran":
59478
- out.push(`Before you started, the server ran this project's verify commands once each on the feature branch at \`${shortCommit(gateRun.commit)}\`, in a sandbox with the branch checked out and its dependencies installed:`, "", ...gateRun.commands.map((result) => gateCommandNote(ticketId, result)), "", "A failed command is a defect against the branch, with the command as its repro: read its output file, then read the branch (`git diff` / `git show`) to explain what broke it. A command that couldn't run is an observation, not a defect.");
59237
+ out.push(gateRun.reusedFrom ? `The server did not re-run this project's verify commands for this pass: the result below is from an earlier pass on the feature branch at \`${shortCommit(gateRun.commit)}\`, and the branch has not moved since (or only this feature's docs changed). They ran once each, in a sandbox with the branch checked out and its dependencies installed:` : `Before you started, the server ran this project's verify commands once each on the feature branch at \`${shortCommit(gateRun.commit)}\`, in a sandbox with the branch checked out and its dependencies installed:`, "", ...gateRun.commands.map((result) => gateCommandNote(ticketId, result)), "", "A failed command is a defect against the branch, with the command as its repro: read its output file, then read the branch (`git diff` / `git show`) to explain what broke it. A command that couldn't run is an observation, not a defect.");
59479
59238
  break;
59480
59239
  }
59481
59240
  out.push("");
@@ -59522,7 +59281,7 @@ async function writeReviewArtifacts(ticket, runId, config2, recorderReap = reapR
59522
59281
  await prepareReviewArtifactsDirectory(ticket.id, dir, { recorderReap });
59523
59282
  const mcpConfigPath = join23(dir, "mcp.json");
59524
59283
  const mcpConfig = renderRunMcpConfig(runId, config2);
59525
- writeFileSync10(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), "utf8");
59284
+ writeFileSync9(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), "utf8");
59526
59285
  return {
59527
59286
  dir,
59528
59287
  mcp: { path: mcpConfigPath, config: mcpConfig },
@@ -59551,6 +59310,11 @@ async function runBranchGates(ctx, ticket, deps) {
59551
59310
  };
59552
59311
  }
59553
59312
  try {
59313
+ const reused = await ctx.reuseGates?.(ticket.id, sha).catch(() => {
59314
+ return;
59315
+ });
59316
+ if (reused)
59317
+ return reused;
59554
59318
  const runGates = deps.runGates ?? (await Promise.resolve().then(() => (init_review_gates2(), exports_review_gates))).runReviewGates;
59555
59319
  return await runGates({ config: deps.config, project: project3, ticketId: ticket.id, sha });
59556
59320
  } catch (err) {
@@ -59605,7 +59369,7 @@ async function reviewTicketOutcome(ctx, ticket, deps, timer) {
59605
59369
  VERIFIES_PASS: verifies ? `#${verifies.seq} \xB7 ${inheritedMode === "drive" ? "Drive" : "Gates"} mode` : "no earlier review in this run \xB7 Gates mode",
59606
59370
  AUTO_FIX_CAP: String(AUTO_FIX_CAP)
59607
59371
  });
59608
- mkdirSync12(logsDir(), { recursive: true });
59372
+ mkdirSync11(logsDir(), { recursive: true });
59609
59373
  const throttle = createStreamThrottle((e) => ctx.emitEvent({ ...e, ticketId: ticket.id }));
59610
59374
  beginTranscript(ticket.id);
59611
59375
  const ticketAbort = registerTicketAbort(ticket.id);
@@ -59708,13 +59472,13 @@ async function reviewTicketOutcome(ctx, ticket, deps, timer) {
59708
59472
  };
59709
59473
  }
59710
59474
  function couldNotReview(ticket, reason, digest) {
59711
- const headline2 = `Review could not run: ${reason}`;
59475
+ const headline = `Review could not run: ${reason}`;
59712
59476
  return {
59713
59477
  status: "failed",
59714
- error: `ticket ${ticket.seq}: ${headline2}`,
59478
+ error: `ticket ${ticket.seq}: ${headline}`,
59715
59479
  digest: digest ? `${digest}
59716
59480
 
59717
- **${headline2}**` : `**${headline2}**`
59481
+ **${headline}**` : `**${headline}**`
59718
59482
  };
59719
59483
  }
59720
59484
  var FFMPEG_BIN = "ffmpeg", spawnVersion = (path2) => {
@@ -59739,10 +59503,10 @@ var init_review_ticket = __esm(() => {
59739
59503
  withheldDrives = new Map;
59740
59504
  DECLARATION = /(?:^|\n)REVIEW-MODE:\s*(drive|gates)\s*\nREVIEW-VERDICT:\s*(verified|unverified)\b(?:\s*\nREVIEW-REASON:[ \t]*([^\r\n]*))?/i;
59741
59505
  REVIEW_DIRECTORY_FS = {
59742
- mkdir: mkdirSync12,
59506
+ mkdir: mkdirSync11,
59743
59507
  readDir: readdirSync7,
59744
59508
  rename: renameSync,
59745
- remove: rmSync4
59509
+ remove: rmSync3
59746
59510
  };
59747
59511
  });
59748
59512
 
@@ -60300,7 +60064,7 @@ var init_podman = __esm(() => {
60300
60064
  });
60301
60065
 
60302
60066
  // src/workflows/ticket-burner.ts
60303
- import { existsSync as existsSync20, mkdirSync as mkdirSync13, readFileSync as readFileSync14, readdirSync as readdirSync8, rmSync as rmSync5 } from "fs";
60067
+ import { existsSync as existsSync20, mkdirSync as mkdirSync12, readFileSync as readFileSync14, readdirSync as readdirSync8, rmSync as rmSync4 } from "fs";
60304
60068
  import { dirname as dirname14, join as join25, posix as posixPath, win32 as winPath } from "path";
60305
60069
  import { fileURLToPath as fileURLToPath6 } from "url";
60306
60070
  function missingImageRuntimeMessage(runtime5, image) {
@@ -60619,7 +60383,7 @@ function buildFixNotes(ticket) {
60619
60383
  return [
60620
60384
  "### This ticket fixes a review finding",
60621
60385
  "",
60622
- "It was minted from a defect the review of this same lap reported, and its `context` carries the reviewer's repro step verbatim. **Before you declare done, re-run that repro step exactly, and say in your digest that you re-ran it and what happened.** Nothing reviews your change afterwards \u2014 that repro step is the check, and the verify commands run on top of it."
60386
+ "It was minted from a defect the review of this same lap reported, and its `context` carries the reviewer's repro step verbatim. **Before you declare done, re-run that repro step exactly, and say in your digest that you re-ran it and what happened.** Nothing reviews your change afterwards \u2014 that repro step is the check, and the host's gates run on top of it. If the defect is a failed gate, re-run exactly the check that failed, narrowed to what failed (the failing test files, or the failing command), and say in your digest that you did; never the full suite."
60623
60387
  ].join(`
60624
60388
  `);
60625
60389
  }
@@ -60792,7 +60556,7 @@ function takeSetupMarker(worktreePath) {
60792
60556
  } catch {
60793
60557
  return;
60794
60558
  }
60795
- rmSync5(file, { force: true });
60559
+ rmSync4(file, { force: true });
60796
60560
  return parseSetupMarker(text3);
60797
60561
  }
60798
60562
  function fmtSeconds(ms) {
@@ -60885,7 +60649,7 @@ function buildAttachmentCopyCommands(sources, platform = process.platform) {
60885
60649
  ];
60886
60650
  }
60887
60651
  async function clearAttachments(workspacePath, repoPath) {
60888
- rmSync5(join25(workspacePath, ATTACHMENTS_DIR), { recursive: true, force: true });
60652
+ rmSync4(join25(workspacePath, ATTACHMENTS_DIR), { recursive: true, force: true });
60889
60653
  await unexcludePath(repoPath, ATTACHMENTS_PREFIX);
60890
60654
  }
60891
60655
  function buildVerifyNotes(config2) {
@@ -60893,15 +60657,15 @@ function buildVerifyNotes(config2) {
60893
60657
  const failures2 = config2.knownFailures?.trim();
60894
60658
  const out = [];
60895
60659
  if (commands) {
60896
- out.push("Verify with exactly these commands \u2014 they are correct for this repo, so do not go looking for alternatives or guess at workspace/package filter names:", "", "```", commands, "```");
60660
+ out.push("The host runs these commands once, in full, at the end of the round. They are correct for this repo, so use them to learn the right tools and workspace/package filter names rather than guessing \u2014 but do NOT run them whole. Run the static check (typecheck or its equivalent) once across the project, and narrow the tests to the files that cover your change:", "", "```", commands, "```");
60897
60661
  } else {
60898
- out.push("No verification commands are configured, so derive them ONCE from the repo (root `package.json` scripts, the workspace's own manifest, CI config) before your first test run \u2014 reading a manifest is free, discovering a filter name by running the wrong suite is not. Write the working commands into your notes and reuse them verbatim for the rest of the ticket.");
60662
+ out.push("No verification commands are configured, so derive the static-check and test commands ONCE from the repo (root `package.json` scripts, the workspace's own manifest, CI config) \u2014 reading a manifest is free, discovering a filter name by running the wrong suite is not. Then run the static check once across the project and the tests narrowed to the files that cover your change; never the whole suite. Reuse the commands verbatim for the rest of the ticket.");
60899
60663
  }
60900
60664
  out.push("");
60901
60665
  if (failures2) {
60902
- out.push("These tests ALREADY fail on this repo before you touch anything:", "", "```", failures2, "```", "", "Treat that as your baseline \u2014 do NOT spend a run establishing it yourself. Only a failure outside this set is yours to fix; if you hit one that looks pre-existing but is not listed, confirm it on a single targeted run of that one test, never a whole-suite re-run.");
60666
+ out.push("These tests ALREADY fail on this repo before you touch anything:", "", "```", failures2, "```", "", "Treat that as your baseline \u2014 do NOT spend a run establishing it yourself. A failing test in a targeted run that is in this list is not yours. Only a failure outside this set is yours to fix; if you hit one that looks pre-existing but is not listed, confirm it on a single targeted run of that one test, never a whole-suite re-run.");
60903
60667
  } else {
60904
- out.push("No pre-existing-failure baseline is configured. If the suite is already red, capture the baseline ONCE \u2014 the first full run you do, before your changes land, is the baseline \u2014 and compare every later run against those saved results. Never re-run a whole suite just to re-establish what was already failing.");
60668
+ out.push("No pre-existing-failure baseline is configured, and you do not run the whole suite to build one. If a targeted test fails and looks unrelated to your change, confirm it ONCE against the pre-change code (`git show <base>:<path>`, where `<base>` is the commit your branch started from, or a detached scratch worktree at it) \u2014 never with a full run.");
60905
60669
  }
60906
60670
  return out.join(`
60907
60671
  `);
@@ -61220,8 +60984,8 @@ function delayUnlessAborted(ms, signal) {
61220
60984
  function stopTicketRun(ticketId) {
61221
60985
  return abortTicketRun(ticketId, new Error("ticket stopped by user"));
61222
60986
  }
61223
- function haltTicketRun(ticketId, headline2) {
61224
- return abortTicketRun(ticketId, new RunHaltedAbort(headline2));
60987
+ function haltTicketRun(ticketId, headline) {
60988
+ return abortTicketRun(ticketId, new RunHaltedAbort(headline));
61225
60989
  }
61226
60990
  function ticketStopReason(reason) {
61227
60991
  return reason instanceof RunHaltedAbort ? `stopped: run halted (${reason.headline})` : "stopped by user";
@@ -61953,7 +61717,7 @@ async function burnTicket(ctx, ticket, config2, token, model, hostAgentVersions,
61953
61717
  const mounts = [...cache.mounts];
61954
61718
  for (const mount of cache.mounts) {
61955
61719
  if ("hostPath" in mount)
61956
- mkdirSync13(mount.hostPath, { recursive: true });
61720
+ mkdirSync12(mount.hostPath, { recursive: true });
61957
61721
  }
61958
61722
  const codexAuthMount = codexAuthMountFor(model.runtime, config2.sandbox);
61959
61723
  if (codexAuthMount)
@@ -61963,7 +61727,7 @@ async function burnTicket(ctx, ticket, config2, token, model, hostAgentVersions,
61963
61727
  const agentOptions = guardInstalled ? { bypassHookTrust: true } : {};
61964
61728
  const slotStamp = buildSlotStamp(resolveSandboxImage(config2, project3), toolchain.packageManagerField);
61965
61729
  const setupHookFor = (branch) => withPrelude(slot !== undefined ? buildSlotSetupCommand(slot, branch, setupCommand, pm, slotStamp) : workspaceMode === "isolated" ? buildIsolatedSetupCommand(branch, setupCommand, pm) : setupCommand);
61966
- mkdirSync13(logsDir(), { recursive: true });
61730
+ mkdirSync12(logsDir(), { recursive: true });
61967
61731
  const logFilePath = join25(logsDir(), `burn-${feature.id}-${ticket.seq}.log`);
61968
61732
  const throttle = createStreamThrottle((e) => ctx.emitEvent({ ...e, ticketId: ticket.id }));
61969
61733
  beginTranscript(ticket.id);
@@ -62303,22 +62067,22 @@ ${retryNotes}` : basePrompt,
62303
62067
  }
62304
62068
  const verdict = classifyTicketRunError(err, model.runtime, setupCommand);
62305
62069
  if (verdict === "retryable" && attempt < maxAttempts) {
62306
- const headline2 = errorHeadline(msg);
62070
+ const headline = errorHeadline(msg);
62307
62071
  retryNotes = buildRetryNotes({
62308
- error: headline2,
62072
+ error: headline,
62309
62073
  commitCount: salvaged.length,
62310
62074
  lastCommand: lastCommand.last()
62311
62075
  });
62312
62076
  ctx.emitEvent({
62313
62077
  type: "ticket.retrying",
62314
- message: `ticket ${ticket.seq} attempt ${attempt}/${maxAttempts} died (${headline2}) \u2014 retrying${salvaged.length > 0 ? ` from ${salvaged.length} preserved commit(s)` : ""}`,
62078
+ message: `ticket ${ticket.seq} attempt ${attempt}/${maxAttempts} died (${headline}) \u2014 retrying${salvaged.length > 0 ? ` from ${salvaged.length} preserved commit(s)` : ""}`,
62315
62079
  ticketId: ticket.id,
62316
62080
  data: { attempt, maxAttempts, error: msg, preservedCommits: salvaged.length }
62317
62081
  });
62318
62082
  appendTranscript(ticket.id, {
62319
62083
  kind: "text",
62320
62084
  text: `
62321
- \u2014 attempt ${attempt} interrupted (${headline2}); starting attempt ${attempt + 1}${salvaged.length > 0 ? " with committed work preserved" : ""} \u2014
62085
+ \u2014 attempt ${attempt} interrupted (${headline}); starting attempt ${attempt + 1}${salvaged.length > 0 ? " with committed work preserved" : ""} \u2014
62322
62086
  `
62323
62087
  });
62324
62088
  await delayUnlessAborted(retryDelayMs(attempt), signal);
@@ -62631,9 +62395,9 @@ var init_ticket_burner = __esm(() => {
62631
62395
  activeTicketAborts = new Map;
62632
62396
  RunHaltedAbort = class RunHaltedAbort extends Error {
62633
62397
  headline;
62634
- constructor(headline2) {
62635
- super(`ticket stopped: run halted (${headline2})`);
62636
- this.headline = headline2;
62398
+ constructor(headline) {
62399
+ super(`ticket stopped: run halted (${headline})`);
62400
+ this.headline = headline;
62637
62401
  this.name = "RunHaltedAbort";
62638
62402
  }
62639
62403
  };
@@ -62644,6 +62408,316 @@ var init_ticket_burner = __esm(() => {
62644
62408
  };
62645
62409
  });
62646
62410
 
62411
+ // src/workflows/review-gates.ts
62412
+ var exports_review_gates = {};
62413
+ __export(exports_review_gates, {
62414
+ withThrowawayBranch: () => withThrowawayBranch,
62415
+ timeoutReason: () => timeoutReason,
62416
+ runReviewGates: () => runReviewGates,
62417
+ reviewGateBranch: () => reviewGateBranch,
62418
+ parseVerifyCommands: () => parseVerifyCommands,
62419
+ headline: () => headline,
62420
+ execWithTimeout: () => execWithTimeout,
62421
+ errorText: () => errorText,
62422
+ errorDetail: () => errorDetail,
62423
+ burnGateSandbox: () => burnGateSandbox,
62424
+ SandboxSetupError: () => SandboxSetupError,
62425
+ GATE_COMMAND_TIMEOUT_MS: () => GATE_COMMAND_TIMEOUT_MS
62426
+ });
62427
+ import { mkdirSync as mkdirSync13, rmSync as rmSync5, writeFileSync as writeFileSync10 } from "fs";
62428
+ import { stripVTControlCharacters as stripVTControlCharacters2 } from "util";
62429
+ function reviewGateBranch(ticketId) {
62430
+ return `runcastle/gates/${ticketId}`;
62431
+ }
62432
+ function parseVerifyCommands(verifyCommands) {
62433
+ return (verifyCommands ?? "").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
62434
+ }
62435
+ function errorText(err) {
62436
+ return err instanceof Error ? err.message : String(err);
62437
+ }
62438
+ function errorDetail(err) {
62439
+ if (err instanceof SandboxSetupError)
62440
+ return `${err.message}
62441
+
62442
+ ${stripVTControlCharacters2(err.output)}`;
62443
+ return err instanceof Error ? err.stack ?? err.message : String(err);
62444
+ }
62445
+ function headline(text3) {
62446
+ return text3.split(/\r?\n/).find((line) => line.trim())?.trim() ?? "unknown error";
62447
+ }
62448
+ async function withThrowawayBranch(repoPath, branch, sha, use) {
62449
+ const discardBranch = async () => {
62450
+ await cleanupBurnWorktree(repoPath, branch);
62451
+ await deleteTempBranch(repoPath, branch);
62452
+ };
62453
+ try {
62454
+ await discardBranch();
62455
+ await pinBranchAt(repoPath, branch, sha);
62456
+ await excludeBurnWorktrees(repoPath);
62457
+ return await use();
62458
+ } finally {
62459
+ await discardBranch();
62460
+ }
62461
+ }
62462
+ async function execWithTimeout(sandbox3, command, timeoutMs) {
62463
+ let timer;
62464
+ const timedOut = new Promise((done10) => {
62465
+ timer = setTimeout(() => done10("timeout"), timeoutMs);
62466
+ });
62467
+ try {
62468
+ return await Promise.race([sandbox3.exec(command), timedOut]);
62469
+ } finally {
62470
+ clearTimeout(timer);
62471
+ }
62472
+ }
62473
+ async function runSandboxSetup(exec3, setup, timeoutMs) {
62474
+ const streamed = [];
62475
+ const result = await execWithTimeout({ exec: (command) => exec3(command, { onLine: (line) => streamed.push(line) }) }, setup, timeoutMs);
62476
+ if (result === "timeout") {
62477
+ throw new SandboxSetupError(`the sync-and-install setup ${timeoutReason(timeoutMs)}`, streamed.join(`
62478
+ `));
62479
+ }
62480
+ if (result.exitCode !== 0) {
62481
+ throw new SandboxSetupError(`the sync-and-install setup exited ${result.exitCode}`, [result.stdout, result.stderr].filter(Boolean).join(`
62482
+ `));
62483
+ }
62484
+ }
62485
+ function timeoutReason(timeoutMs) {
62486
+ return `timed out after ${Math.round(timeoutMs / 60000)} minutes`;
62487
+ }
62488
+ async function runReviewGates(input) {
62489
+ const { config: config2, project: project3, ticketId, sha } = input;
62490
+ const commands = parseVerifyCommands(resolvePreparedSettings(config2, project3).verifyCommands);
62491
+ if (commands.length === 0)
62492
+ return { status: "none_configured" };
62493
+ const withSandbox = input.deps?.withSandbox ?? burnGateSandbox(config2, project3);
62494
+ const timeoutMs = input.deps?.commandTimeoutMs ?? GATE_COMMAND_TIMEOUT_MS;
62495
+ const branch = reviewGateBranch(ticketId);
62496
+ const results = [];
62497
+ try {
62498
+ rmSync5(reviewGateLogDir(ticketId), { recursive: true, force: true });
62499
+ mkdirSync13(reviewGateLogDir(ticketId), { recursive: true });
62500
+ await withThrowawayBranch(project3.repoPath, branch, sha, async () => {
62501
+ while (results.length < commands.length) {
62502
+ await withSandbox(branch, async (sandbox3) => {
62503
+ for (const [i, command] of commands.entries()) {
62504
+ if (i < results.length)
62505
+ continue;
62506
+ const { result, stillRunning } = await runGateCommand(sandbox3, command, ticketId, `${i}.log`, timeoutMs);
62507
+ results.push(result);
62508
+ if (stillRunning)
62509
+ return;
62510
+ }
62511
+ });
62512
+ }
62513
+ });
62514
+ return { status: "ran", commit: sha, commands: results };
62515
+ } catch (err) {
62516
+ if (results.length > 0) {
62517
+ const detail = errorDetail(err);
62518
+ const reason = `the gate sandbox could not be reopened: ${headline(errorText(err))}`;
62519
+ for (const [i, command] of commands.entries()) {
62520
+ if (i < results.length)
62521
+ continue;
62522
+ writeFileSync10(reviewGateLogPath(ticketId, `${i}.log`), `${detail}
62523
+ `);
62524
+ results.push({ command, outcome: "couldnt_run", exitCode: null, reason, log: `${i}.log` });
62525
+ }
62526
+ return { status: "ran", commit: sha, commands: results };
62527
+ }
62528
+ return {
62529
+ status: "couldnt_run",
62530
+ commit: sha,
62531
+ reason: `the gate sandbox could not be set up: ${headline(errorText(err))}`,
62532
+ log: writeRunLog(ticketId, err)
62533
+ };
62534
+ }
62535
+ }
62536
+ function writeRunLog(ticketId, err) {
62537
+ try {
62538
+ writeFileSync10(reviewGateLogPath(ticketId, "run.log"), `${errorDetail(err)}
62539
+ `);
62540
+ return "run.log";
62541
+ } catch {
62542
+ return null;
62543
+ }
62544
+ }
62545
+ async function runGateCommand(sandbox3, command, ticketId, log6, timeoutMs) {
62546
+ const logPath = reviewGateLogPath(ticketId, log6);
62547
+ try {
62548
+ const result = await execWithTimeout(sandbox3, command, timeoutMs);
62549
+ if (result === "timeout") {
62550
+ const reason = timeoutReason(timeoutMs);
62551
+ writeFileSync10(logPath, `${reason}
62552
+ `);
62553
+ return {
62554
+ result: { command, outcome: "couldnt_run", exitCode: null, reason, log: log6 },
62555
+ stillRunning: true
62556
+ };
62557
+ }
62558
+ writeFileSync10(logPath, [result.stdout, result.stderr].filter(Boolean).join(`
62559
+ `));
62560
+ return {
62561
+ result: result.exitCode === 0 ? { command, outcome: "passed", exitCode: 0, log: log6 } : { command, outcome: "failed", exitCode: result.exitCode, log: log6 },
62562
+ stillRunning: false
62563
+ };
62564
+ } catch (err) {
62565
+ const reason = `could not start: ${headline(errorText(err))}`;
62566
+ writeFileSync10(logPath, `${errorText(err)}
62567
+ `);
62568
+ return {
62569
+ result: { command, outcome: "couldnt_run", exitCode: null, reason, log: log6 },
62570
+ stillRunning: false
62571
+ };
62572
+ }
62573
+ }
62574
+ function burnGateSandbox(config2, project3, deps = {}) {
62575
+ const open3 = deps.open ?? createSandbox;
62576
+ const setupTimeoutMs = deps.setupTimeoutMs ?? SETUP_HOOK_TIMEOUT_MS;
62577
+ return (branch, use) => {
62578
+ const allocator = resolveBurnCacheMode(config2) === "volume" ? getBurnSlotAllocator(config2.burnConcurrency) : undefined;
62579
+ return withBurnCacheSlot(allocator, async (slot) => {
62580
+ if (slot !== undefined) {
62581
+ await ensureBurnCacheVolume({
62582
+ engine: config2.sandbox === "podman" ? "podman" : "docker",
62583
+ imageName: resolveSandboxImage(config2, project3),
62584
+ projectId: project3.id,
62585
+ exec: createSystemExec({ cwd: project3.repoPath })
62586
+ });
62587
+ }
62588
+ const workspaceMode = resolveBurnWorkspaceMode(slot === undefined ? { ...config2, burnCache: "off" } : config2);
62589
+ const toolchain = readRepoToolchain(project3.repoPath);
62590
+ const pm = detectPackageManager(toolchain);
62591
+ const setupCommand = resolveSetupCommand(toolchain, resolvePreparedSettings(config2, project3).setupCommand);
62592
+ const cache = buildBurnCacheMounts(slot, project3.id, config2.sandbox, pm);
62593
+ const onHost2 = config2.sandbox === "noSandbox";
62594
+ for (const mount of cache.mounts) {
62595
+ if ("hostPath" in mount)
62596
+ mkdirSync13(mount.hostPath, { recursive: true });
62597
+ }
62598
+ const setup = slot !== undefined ? buildSlotSetupCommand(slot, branch, setupCommand, pm, buildSlotStamp(resolveSandboxImage(config2, project3), toolchain.packageManagerField)) : workspaceMode === "isolated" ? buildIsolatedSetupCommand(branch, setupCommand, pm) : setupCommand;
62599
+ const cwd = slot !== undefined ? slotRepoPath(slot) : workspaceMode === "isolated" ? ISOLATED_REPO_PATH : undefined;
62600
+ const lane = branch;
62601
+ const sandbox3 = await open3({
62602
+ branch,
62603
+ sandbox: selectSandbox(config2, project3, cache.mounts, cache.env, {
62604
+ onChildSpawn: registerHostChildren(lane, {})
62605
+ }),
62606
+ cwd: project3.repoPath
62607
+ });
62608
+ let running3 = 0;
62609
+ const exec3 = async (command, opts) => {
62610
+ running3++;
62611
+ try {
62612
+ return await sandbox3.exec(command, opts);
62613
+ } finally {
62614
+ running3--;
62615
+ }
62616
+ };
62617
+ try {
62618
+ if (setup) {
62619
+ const script = onHost2 ? setup : `git config --global --add safe.directory '*' && ${setup}`;
62620
+ await runSandboxSetup(exec3, script, setupTimeoutMs);
62621
+ }
62622
+ return await use({
62623
+ exec: (command) => exec3(command, cwd ? { cwd } : {})
62624
+ });
62625
+ } finally {
62626
+ if (running3 > 0)
62627
+ await killRegistry().killAndWait(lane);
62628
+ killRegistry().release(lane);
62629
+ await sandbox3.close();
62630
+ }
62631
+ });
62632
+ };
62633
+ }
62634
+ var GATE_COMMAND_TIMEOUT_MS, SandboxSetupError;
62635
+ var init_review_gates2 = __esm(() => {
62636
+ init_dist();
62637
+ init_src();
62638
+ init_paths();
62639
+ init_system_exec();
62640
+ init_git();
62641
+ init_burn_cache();
62642
+ init_kill_registry();
62643
+ init_ticket_burner();
62644
+ GATE_COMMAND_TIMEOUT_MS = SETUP_HOOK_TIMEOUT_MS;
62645
+ SandboxSetupError = class SandboxSetupError extends Error {
62646
+ output;
62647
+ constructor(message, output) {
62648
+ super(message);
62649
+ this.output = output;
62650
+ this.name = "SandboxSetupError";
62651
+ }
62652
+ };
62653
+ });
62654
+
62655
+ // src/workflows/gate-reuse.ts
62656
+ import { cpSync as cpSync2, existsSync as existsSync21, mkdirSync as mkdirSync14, rmSync as rmSync6 } from "fs";
62657
+ function pickReusableGates(candidates, commands, unmoved) {
62658
+ return [...candidates].sort((a, b) => b.at - a.at).find((c) => c.gates.status === "ran" && c.gates.commands.every((r) => r.outcome !== "couldnt_run") && c.gates.commands.length === commands.length && c.gates.commands.every((r, i) => r.command === commands[i]) && unmoved(c.gates.commit));
62659
+ }
62660
+ function onlyFeatureDocs(paths, slug) {
62661
+ const prefix = `${featureDocsRel(slug)}/`;
62662
+ return paths.every((p) => p.startsWith(prefix));
62663
+ }
62664
+ async function reuseGateResult(input) {
62665
+ const { ctx, config: config2, project: project3, feature, ownerId, sha } = input;
62666
+ try {
62667
+ const { parseVerifyCommands: parseVerifyCommands2 } = await Promise.resolve().then(() => (init_review_gates2(), exports_review_gates));
62668
+ const commands = parseVerifyCommands2(resolvePreparedSettings(config2, project3).verifyCommands);
62669
+ if (commands.length === 0)
62670
+ return;
62671
+ const candidates = [];
62672
+ for (const run7 of listRunsByFeature(ctx, feature.id)) {
62673
+ if (run7.gates && run7.id !== ownerId) {
62674
+ candidates.push({ kind: "round", id: run7.id, at: run7.endedAt ?? run7.startedAt, gates: run7.gates });
62675
+ }
62676
+ }
62677
+ for (const t of listByFeature(ctx, feature.id)) {
62678
+ if (t.kind === "review" && t.reviewGateRun && t.id !== ownerId) {
62679
+ candidates.push({ kind: "review", id: t.id, at: t.completedAt ?? Date.now(), gates: t.reviewGateRun });
62680
+ }
62681
+ }
62682
+ const verdicts = new Map;
62683
+ for (const c of candidates) {
62684
+ if (c.gates.status !== "ran" || verdicts.has(c.gates.commit))
62685
+ continue;
62686
+ const commit = c.gates.commit;
62687
+ if (commit === sha) {
62688
+ verdicts.set(commit, true);
62689
+ } else if (!await headSha(project3.repoPath, commit)) {
62690
+ verdicts.set(commit, false);
62691
+ } else {
62692
+ const paths = await diffPaths(project3.repoPath, commit, sha, { throwOnError: true }).catch(() => {
62693
+ return;
62694
+ });
62695
+ verdicts.set(commit, paths !== undefined && onlyFeatureDocs(paths, feature.slug));
62696
+ }
62697
+ }
62698
+ const hit = pickReusableGates(candidates, commands, (commit) => verdicts.get(commit) === true);
62699
+ if (!hit || hit.gates.status !== "ran")
62700
+ return;
62701
+ const from = reviewGateLogDir(hit.id);
62702
+ if (!existsSync21(from))
62703
+ return;
62704
+ const to = reviewGateLogDir(ownerId);
62705
+ rmSync6(to, { recursive: true, force: true });
62706
+ mkdirSync14(to, { recursive: true });
62707
+ cpSync2(from, to, { recursive: true });
62708
+ return { ...hit.gates, reusedFrom: { kind: hit.kind, id: hit.id } };
62709
+ } catch {
62710
+ return;
62711
+ }
62712
+ }
62713
+ var init_gate_reuse = __esm(() => {
62714
+ init_src();
62715
+ init_paths();
62716
+ init_git();
62717
+ init_repo();
62718
+ init_tickets();
62719
+ });
62720
+
62647
62721
  // src/workflows/registry.ts
62648
62722
  function getWorkflow(id3) {
62649
62723
  return workflowRegistry.get(id3);
@@ -62724,6 +62798,7 @@ async function startRun(ctx, featureId, workflowId, opts = {}) {
62724
62798
  addTicketTokens: (id3, usage2, sessionIds) => addTicketTokens(ctx, id3, usage2, sessionIds),
62725
62799
  storeTickets: (inputs) => storeTickets(ctx, featureId, inputs),
62726
62800
  listFindings: () => listByFeature2(ctx, featureId),
62801
+ reuseGates: (ownerId, sha) => reuseGateResult({ ctx, config: ctx.config, project: project3, feature, ownerId, sha }),
62727
62802
  updateFinding: (findingId, progress, reason) => {
62728
62803
  markFixProgress(ctx, findingId, progress, reason);
62729
62804
  },
@@ -62746,7 +62821,9 @@ async function endRound(ctx, runId, featureId, runGates) {
62746
62821
  const project3 = projectForFeature(ctx, feature);
62747
62822
  let gates;
62748
62823
  try {
62749
- gates = await runGates({ ctx, project: project3, feature, runId });
62824
+ const sha = await headSha(project3.repoPath, feature.branch);
62825
+ const reused = sha ? await reuseGateResult({ ctx, config: ctx.config, project: project3, feature, ownerId: runId, sha }) : undefined;
62826
+ gates = reused ?? await runGates({ ctx, project: project3, feature, runId });
62750
62827
  } catch (err) {
62751
62828
  gates = {
62752
62829
  status: "couldnt_run",
@@ -62856,6 +62933,7 @@ var init_runner = __esm(() => {
62856
62933
  init_tickets();
62857
62934
  init_usage2();
62858
62935
  init_kill_registry();
62936
+ init_gate_reuse();
62859
62937
  init_registry2();
62860
62938
  controllers = new Map;
62861
62939
  BRANCH_CLAIMING = new Set(["ticket-burner"]);
@@ -62916,7 +62994,7 @@ var init_prep = __esm(() => {
62916
62994
  });
62917
62995
 
62918
62996
  // src/services/project-notes.ts
62919
- import { existsSync as existsSync21, mkdirSync as mkdirSync14, rmSync as rmSync6, writeFileSync as writeFileSync11 } from "fs";
62997
+ import { existsSync as existsSync22, mkdirSync as mkdirSync15, rmSync as rmSync7, writeFileSync as writeFileSync11 } from "fs";
62920
62998
  import { and as and11, count as count3, desc as desc6, eq as eq14, inArray as inArray8 } from "drizzle-orm";
62921
62999
  function rowToNote(row) {
62922
63000
  return ProjectNote.parse({
@@ -62925,7 +63003,7 @@ function rowToNote(row) {
62925
63003
  featureId: row.featureId ?? undefined,
62926
63004
  driveBranch: row.driveBranch ?? undefined,
62927
63005
  driveCommit: row.driveCommit ?? undefined,
62928
- screenshotUrl: existsSync21(projectNotePath(row.id)) ? projectNoteScreenshotUrl(row.id) : undefined
63006
+ screenshotUrl: existsSync22(projectNotePath(row.id)) ? projectNoteScreenshotUrl(row.id) : undefined
62929
63007
  });
62930
63008
  }
62931
63009
  function clean(value, label) {
@@ -62981,7 +63059,7 @@ function deleteNote(ctx, noteId) {
62981
63059
  const note2 = getNote(ctx, noteId);
62982
63060
  requireOpen(note2, "delete");
62983
63061
  ctx.db.delete(projectNotes).where(eq14(projectNotes.id, noteId)).run();
62984
- rmSync6(projectNotePath(noteId), { force: true });
63062
+ rmSync7(projectNotePath(noteId), { force: true });
62985
63063
  emitProject(ctx, note2.projectId, { type: "project_note.deleted", message: "project note deleted", data: { noteId } });
62986
63064
  }
62987
63065
  function triage(ctx, noteIds, outcome, featureId, verb = "triaged") {
@@ -63023,7 +63101,7 @@ function reopenNote(ctx, noteId) {
63023
63101
  }
63024
63102
  function attachScreenshot(ctx, noteId, png) {
63025
63103
  const note2 = getNote(ctx, noteId);
63026
- mkdirSync14(projectNotesDir(), { recursive: true });
63104
+ mkdirSync15(projectNotesDir(), { recursive: true });
63027
63105
  writeFileSync11(projectNotePath(note2.id), png);
63028
63106
  emitProject(ctx, note2.projectId, { type: "project_note.screenshot", message: "screenshot attached to project note", data: { noteId } });
63029
63107
  return getNote(ctx, noteId);
@@ -63589,7 +63667,7 @@ var init_conversations = __esm(() => {
63589
63667
  });
63590
63668
 
63591
63669
  // src/services/main-chat-excerpt.ts
63592
- import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync12 } from "fs";
63670
+ import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync12 } from "fs";
63593
63671
  import { join as join27 } from "path";
63594
63672
  function trimTurn(text3) {
63595
63673
  const t = text3.trim();
@@ -63643,7 +63721,7 @@ function mainChatContext(ctx, feature, sessionId, base) {
63643
63721
  const tooLong = quote.length > EXCERPT_INLINE_MAX_CHARS || base.length + quote.length + 1000 > MAX_KICKOFF_ARGV;
63644
63722
  if (tooLong) {
63645
63723
  const dir = sessionDir(sessionId);
63646
- mkdirSync15(dir, { recursive: true });
63724
+ mkdirSync16(dir, { recursive: true });
63647
63725
  const file = join27(dir, "main-chat-excerpt.md");
63648
63726
  writeFileSync12(file, `${quote}
63649
63727
  `, "utf8");
@@ -63813,7 +63891,7 @@ var init_untouched = __esm(() => {
63813
63891
  });
63814
63892
 
63815
63893
  // src/launcher/launcher.ts
63816
- import { existsSync as existsSync22 } from "fs";
63894
+ import { existsSync as existsSync23 } from "fs";
63817
63895
  import { join as join28 } from "path";
63818
63896
  import { and as and13, eq as eq16 } from "drizzle-orm";
63819
63897
  function ptyExitMessage(exitCode) {
@@ -64479,7 +64557,7 @@ async function launchScenarioSession(ctx, input, opts = {}) {
64479
64557
  });
64480
64558
  return { sessionId: docked.id };
64481
64559
  }
64482
- const setup = !existsSync22(join28(project3.repoPath, ".runcastle", "scenarios"));
64560
+ const setup = !existsSync23(join28(project3.repoPath, ".runcastle", "scenarios"));
64483
64561
  const model = resolveModelEntry("prepare", rosterConfig(ctx), project3);
64484
64562
  const runtime5 = runtimeAdapterFor(model.runtime);
64485
64563
  assertRuntimeReady(runtime5, opts);
@@ -64687,7 +64765,7 @@ async function buildPrepareBrief(ctx, project3) {
64687
64765
  };
64688
64766
  }
64689
64767
  function probePrepareHost(repoPath) {
64690
- const has4 = (rel) => existsSync22(join28(repoPath, rel));
64768
+ const has4 = (rel) => existsSync23(join28(repoPath, rel));
64691
64769
  const lock = LOCKFILES.find(([file]) => has4(file));
64692
64770
  return {
64693
64771
  platform: process.platform,
@@ -65039,9 +65117,10 @@ function gatesLine(gates) {
65039
65117
  if (gates.status === "couldnt_run")
65040
65118
  return `Gates: could not run \u2014 ${gates.reason}`;
65041
65119
  const failed = gates.commands.filter((c) => c.outcome !== "passed");
65120
+ const reused = gates.reusedFrom ? ` (not re-run: the branch had not moved since commit ${gates.commit.slice(0, 7)}, where they ran)` : "";
65042
65121
  if (failed.length === 0)
65043
- return `Gates: all ${gates.commands.length} verify command(s) passed.`;
65044
- return `Gates: FAILED \u2014 ${failed.map((c) => `\`${c.command}\` (${c.outcome})`).join(", ")}.`;
65122
+ return `Gates: all ${gates.commands.length} verify command(s) passed${reused}.`;
65123
+ return `Gates: FAILED${reused} \u2014 ${failed.map((c) => `\`${c.command}\` (${c.outcome})`).join(", ")}.`;
65045
65124
  }
65046
65125
  function composeRoundWake(ctx, featureId, runId) {
65047
65126
  const run7 = getRunRow(ctx, runId);
@@ -65094,7 +65173,7 @@ var init_lead_delivery = __esm(() => {
65094
65173
 
65095
65174
  // src/services/features.ts
65096
65175
  import { asc as asc6, desc as desc8, eq as eq17, or } from "drizzle-orm";
65097
- import { rmSync as rmSync7 } from "fs";
65176
+ import { rmSync as rmSync8 } from "fs";
65098
65177
  async function createFeature(ctx, input) {
65099
65178
  const project3 = requireProjectById(ctx, input.projectId);
65100
65179
  const slug = uniqueSlug(ctx, project3.id, input.title);
@@ -65544,7 +65623,7 @@ async function deleteFeature(ctx, featureId) {
65544
65623
  }
65545
65624
  for (const s of listSessionsByFeature(ctx, featureId)) {
65546
65625
  try {
65547
- rmSync7(sessionDir(s.id), { recursive: true, force: true });
65626
+ rmSync8(sessionDir(s.id), { recursive: true, force: true });
65548
65627
  } catch {}
65549
65628
  }
65550
65629
  deleteFeatureRows(ctx, featureId);
@@ -65594,7 +65673,7 @@ var init_features = __esm(() => {
65594
65673
  });
65595
65674
 
65596
65675
  // src/services/test-notes.ts
65597
- import { existsSync as existsSync23, mkdirSync as mkdirSync16, rmSync as rmSync8, writeFileSync as writeFileSync13 } from "fs";
65676
+ import { existsSync as existsSync24, mkdirSync as mkdirSync17, rmSync as rmSync9, writeFileSync as writeFileSync13 } from "fs";
65598
65677
  import { asc as asc7, eq as eq18, inArray as inArray10 } from "drizzle-orm";
65599
65678
  function rowToNote2(row) {
65600
65679
  return TestNote.parse({
@@ -65606,7 +65685,7 @@ function rowToNote2(row) {
65606
65685
  ticketId: row.ticketId ?? undefined,
65607
65686
  reviewTicketId: row.reviewTicketId ?? undefined,
65608
65687
  videoTimestamp: row.videoTimestamp ?? undefined,
65609
- screenshotUrl: existsSync23(annotationPath(row.id)) ? noteScreenshotUrl(row.id) : undefined,
65688
+ screenshotUrl: existsSync24(annotationPath(row.id)) ? noteScreenshotUrl(row.id) : undefined,
65610
65689
  sentAt: row.sentAt ?? undefined,
65611
65690
  createdAt: row.createdAt,
65612
65691
  updatedAt: row.updatedAt
@@ -65670,7 +65749,7 @@ function editNote2(ctx, noteId, text3) {
65670
65749
  function deleteNote2(ctx, noteId) {
65671
65750
  const current2 = getNote2(ctx, noteId);
65672
65751
  ctx.db.delete(testNotes).where(eq18(testNotes.id, noteId)).run();
65673
- rmSync8(annotationPath(noteId), { force: true });
65752
+ rmSync9(annotationPath(noteId), { force: true });
65674
65753
  emit(ctx, current2.featureId, {
65675
65754
  type: "note.deleted",
65676
65755
  message: "note deleted",
@@ -65679,7 +65758,7 @@ function deleteNote2(ctx, noteId) {
65679
65758
  }
65680
65759
  function attachScreenshot2(ctx, noteId, png) {
65681
65760
  const note2 = getNote2(ctx, noteId);
65682
- mkdirSync16(annotationsDir(), { recursive: true });
65761
+ mkdirSync17(annotationsDir(), { recursive: true });
65683
65762
  writeFileSync13(annotationPath(noteId), png);
65684
65763
  emit(ctx, note2.featureId, {
65685
65764
  type: "note.screenshot",
@@ -65770,7 +65849,7 @@ var init_drive_call = __esm(() => {
65770
65849
  });
65771
65850
 
65772
65851
  // src/services/outcome.ts
65773
- import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync14 } from "fs";
65852
+ import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync14 } from "fs";
65774
65853
  import { join as join29 } from "path";
65775
65854
  function digestHasSubstance(text3) {
65776
65855
  return text3.split(`
@@ -65862,7 +65941,7 @@ async function promoteOutcomeDoc(ctx, project3, feature, target, delta) {
65862
65941
  });
65863
65942
  await onBranch(project3.repoPath, target, async () => {
65864
65943
  const docsDir = join29(project3.repoPath, ...featureDocsRel(feature.slug).split("/"));
65865
- mkdirSync17(docsDir, { recursive: true });
65944
+ mkdirSync18(docsDir, { recursive: true });
65866
65945
  writeFileSync14(join29(docsDir, "outcome.md"), doc, "utf8");
65867
65946
  await commitDocs(project3.repoPath, docsCommitMessage(`outcome for ${feature.slug}`, project3.docsCommitPrefix));
65868
65947
  });
@@ -65982,7 +66061,7 @@ var init_merge = __esm(() => {
65982
66061
  });
65983
66062
 
65984
66063
  // src/mcp/orchestrator-tools.ts
65985
- import { existsSync as existsSync24, mkdirSync as mkdirSync18, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
66064
+ import { existsSync as existsSync25, mkdirSync as mkdirSync19, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
65986
66065
  import { dirname as dirname15 } from "path";
65987
66066
  import { and as and14, eq as eq19 } from "drizzle-orm";
65988
66067
  import * as z6 from "zod";
@@ -66142,12 +66221,12 @@ var init_orchestrator_tools = __esm(() => {
66142
66221
  }
66143
66222
  const project3 = projectForFeature(ctx, feature);
66144
66223
  const worktree = worktreeDir(project3.id, feature.slug);
66145
- if (!existsSync24(worktree)) {
66224
+ if (!existsSync25(worktree)) {
66146
66225
  throw new GateError(`\`${feature.slug}\` has no worktree to write its brief in.`);
66147
66226
  }
66148
66227
  const briefPath = featureDocPath(project3, feature, "brief.md");
66149
- const prior = existsSync24(briefPath) ? readFileSync16(briefPath, "utf8") : "";
66150
- mkdirSync18(dirname15(briefPath), { recursive: true });
66228
+ const prior = existsSync25(briefPath) ? readFileSync16(briefPath, "utf8") : "";
66229
+ mkdirSync19(dirname15(briefPath), { recursive: true });
66151
66230
  writeFileSync15(briefPath, withBriefSection(prior, text3), "utf8");
66152
66231
  await commitDocs(worktree, docsCommitMessage(`add to ${feature.slug} brief`, project3.docsCommitPrefix));
66153
66232
  await landChatCommits(ctx, project3, feature);
@@ -66224,7 +66303,7 @@ function serializedLength(result) {
66224
66303
  var MCP_READ_CEILING_CHARS = 60000;
66225
66304
 
66226
66305
  // src/mcp/server.ts
66227
- import { existsSync as existsSync25, readFileSync as readFileSync17 } from "fs";
66306
+ import { existsSync as existsSync26, readFileSync as readFileSync17 } from "fs";
66228
66307
  import { join as join30, relative as relative4, resolve as resolve11, sep as sep2 } from "path";
66229
66308
  import { StreamableHTTPTransport } from "@hono/mcp";
66230
66309
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -66980,7 +67059,7 @@ function toolReadAdr(ctx, session, input) {
66980
67059
  if (rel === "" || rel.startsWith("..") || rel.split(sep2).includes("..")) {
66981
67060
  throw new InvalidInputError(`adr path escapes ${ADR_DIR_REL}: ${input.relPath}`);
66982
67061
  }
66983
- if (!existsSync25(target))
67062
+ if (!existsSync26(target))
66984
67063
  throw new NotFoundError(`adr not found: ${input.relPath}`);
66985
67064
  return { relPath: `${ADR_DIR_REL}/${name}`, content: readFileSync17(target, "utf8") };
66986
67065
  }
@@ -67010,7 +67089,7 @@ function toolReadFeatureBrief(ctx, session, input) {
67010
67089
  if (!feature)
67011
67090
  throw new NotFoundError(`feature not found: ${input.slug}`);
67012
67091
  const onDisk = join30(session.worktreePath, featureDocsRel(feature.slug), "brief.md");
67013
- const brief = feature.status === "shipped" && existsSync25(onDisk) ? readFileSync17(onDisk, "utf8") : feature.brief;
67092
+ const brief = feature.status === "shipped" && existsSync26(onDisk) ? readFileSync17(onDisk, "utf8") : feature.brief;
67014
67093
  return {
67015
67094
  slug: feature.slug,
67016
67095
  title: feature.title,
@@ -68698,7 +68777,7 @@ var init_stream = __esm(() => {
68698
68777
  });
68699
68778
 
68700
68779
  // src/routes/web.ts
68701
- import { existsSync as existsSync26, statSync as statSync7 } from "fs";
68780
+ import { existsSync as existsSync27, statSync as statSync7 } from "fs";
68702
68781
  import { readFile as readFile5 } from "fs/promises";
68703
68782
  import { extname, join as join31, normalize as normalize2, resolve as resolve13, sep as sep3 } from "path";
68704
68783
  function contentType(path2) {
@@ -68751,7 +68830,7 @@ function mountWebApp(app, distDir) {
68751
68830
  }
68752
68831
  function mountWebAppIfBuilt(app) {
68753
68832
  const dist = resolveWebDist();
68754
- if (existsSync26(join31(dist, "index.html")))
68833
+ if (existsSync27(join31(dist, "index.html")))
68755
68834
  mountWebApp(app, dist);
68756
68835
  }
68757
68836
  var MIME;
@@ -68802,18 +68881,18 @@ var init_version = () => {};
68802
68881
 
68803
68882
  // src/services/install-id.ts
68804
68883
  import { randomUUID as randomUUID3 } from "crypto";
68805
- import { existsSync as existsSync27, mkdirSync as mkdirSync19, readFileSync as readFileSync19, writeFileSync as writeFileSync16 } from "fs";
68884
+ import { existsSync as existsSync28, mkdirSync as mkdirSync20, readFileSync as readFileSync19, writeFileSync as writeFileSync16 } from "fs";
68806
68885
  import { dirname as dirname17 } from "path";
68807
68886
  function getInstallId() {
68808
68887
  const file = installIdPath();
68809
68888
  try {
68810
- if (existsSync27(file)) {
68889
+ if (existsSync28(file)) {
68811
68890
  const existing = readFileSync19(file, "utf8").trim();
68812
68891
  if (UUID_RE.test(existing))
68813
68892
  return existing;
68814
68893
  }
68815
68894
  const id3 = randomUUID3();
68816
- mkdirSync19(dirname17(file), { recursive: true });
68895
+ mkdirSync20(dirname17(file), { recursive: true });
68817
68896
  writeFileSync16(file, `${id3}
68818
68897
  `);
68819
68898
  return id3;
@@ -68984,7 +69063,7 @@ var init_context = __esm(() => {
68984
69063
  });
68985
69064
 
68986
69065
  // src/services/design-crop.ts
68987
- import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync17 } from "fs";
69066
+ import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync17 } from "fs";
68988
69067
  import { join as join35 } from "path";
68989
69068
  function cropMessage(path2, text3) {
68990
69069
  return `[Screenshot: ${path2}] ${text3.replace(/\s*[\r\n]+\s*/g, " ").trim()}`.trimEnd();
@@ -68995,7 +69074,7 @@ function sendDesignCrop(ctx, featureId, png, text3) {
68995
69074
  if (!chat)
68996
69075
  throw new GateError(NO_LIVE_CHAT);
68997
69076
  const dir = designCropsDir(featureId);
68998
- mkdirSync20(dir, { recursive: true });
69077
+ mkdirSync21(dir, { recursive: true });
68999
69078
  const path2 = join35(dir, `${Date.now()}.png`);
69000
69079
  writeFileSync17(path2, png);
69001
69080
  if (!writeToLiveTerminal(chat.id, cropMessage(path2, text3)))
@@ -69193,7 +69272,7 @@ var init_drive_prerequisites = __esm(() => {
69193
69272
  });
69194
69273
 
69195
69274
  // src/services/fsbrowse.ts
69196
- import { existsSync as existsSync28, readdirSync as readdirSync9, statSync as statSync8 } from "fs";
69275
+ import { existsSync as existsSync29, readdirSync as readdirSync9, statSync as statSync8 } from "fs";
69197
69276
  import { homedir as homedir4 } from "os";
69198
69277
  import { basename as basename5, dirname as dirname18, isAbsolute as isAbsolute4, join as join36, resolve as resolve14, sep as sep4 } from "path";
69199
69278
  function expandPath(input, home = homedir4()) {
@@ -69209,7 +69288,7 @@ function expandPath(input, home = homedir4()) {
69209
69288
  }
69210
69289
  function looksLikeRepo(dir) {
69211
69290
  try {
69212
- return existsSync28(join36(dir, ".git"));
69291
+ return existsSync29(join36(dir, ".git"));
69213
69292
  } catch {
69214
69293
  return false;
69215
69294
  }
@@ -69220,20 +69299,20 @@ function listRoots(home = homedir4()) {
69220
69299
  for (let code = 67;code <= 90; code++) {
69221
69300
  const drive = `${String.fromCharCode(code)}:${sep4}`;
69222
69301
  try {
69223
- if (existsSync28(drive))
69302
+ if (existsSync29(drive))
69224
69303
  roots3.push({ label: drive.replace(/\\$/, ""), path: drive, kind: "drive" });
69225
69304
  } catch {}
69226
69305
  }
69227
69306
  } else {
69228
69307
  roots3.push({ label: "/", path: "/", kind: "drive" });
69229
69308
  }
69230
- if (existsSync28(home))
69309
+ if (existsSync29(home))
69231
69310
  roots3.push({ label: "Home", path: home, kind: "home" });
69232
69311
  const seen = new Set(roots3.map(pathKey));
69233
69312
  for (const name of COMMON_DIRS) {
69234
69313
  const candidate = join36(home, name);
69235
69314
  const key = pathKey({ path: candidate });
69236
- if (seen.has(key) || !existsSync28(candidate))
69315
+ if (seen.has(key) || !existsSync29(candidate))
69237
69316
  continue;
69238
69317
  seen.add(key);
69239
69318
  roots3.push({ label: name, path: candidate, kind: "common" });
@@ -69264,7 +69343,7 @@ function browseDir(input, showHidden = false, home = homedir4()) {
69264
69343
  if (!isAbsolute4(target)) {
69265
69344
  throw new InvalidInputError(`path is not absolute: ${target}`);
69266
69345
  }
69267
- if (!existsSync28(target)) {
69346
+ if (!existsSync29(target)) {
69268
69347
  throw new InvalidInputError(`path does not exist: ${target}`);
69269
69348
  }
69270
69349
  let dir = target;
@@ -69329,7 +69408,7 @@ var init_fsbrowse = __esm(() => {
69329
69408
  });
69330
69409
 
69331
69410
  // src/services/projects.ts
69332
- import { existsSync as existsSync29 } from "fs";
69411
+ import { existsSync as existsSync30 } from "fs";
69333
69412
  import { basename as basename6, join as join37 } from "path";
69334
69413
  import { eq as eq20, isNull } from "drizzle-orm";
69335
69414
  function listProjects(ctx) {
@@ -69414,7 +69493,7 @@ async function assertRepoTolerant(ctx, repoPath) {
69414
69493
  } catch (e) {
69415
69494
  if (!isNotImplemented(e))
69416
69495
  throw e;
69417
- if (!existsSync29(join37(repoPath, ".git"))) {
69496
+ if (!existsSync30(join37(repoPath, ".git"))) {
69418
69497
  throw new InvalidInputError(`not a git repository: ${repoPath}`);
69419
69498
  }
69420
69499
  }
@@ -69560,12 +69639,12 @@ var init_settings2 = __esm(() => {
69560
69639
  });
69561
69640
 
69562
69641
  // src/doctor/afk-env.ts
69563
- import { existsSync as existsSync30, readFileSync as readFileSync20 } from "fs";
69642
+ import { existsSync as existsSync31, readFileSync as readFileSync20 } from "fs";
69564
69643
  function envWithAfkCredentials() {
69565
69644
  const merged = { ...process.env };
69566
69645
  try {
69567
69646
  const path2 = envPath();
69568
- if (existsSync30(path2)) {
69647
+ if (existsSync31(path2)) {
69569
69648
  const fromFile = parseEnvFile3(readFileSync20(path2, "utf8"));
69570
69649
  for (const runtime5 of AGENT_RUNTIMES) {
69571
69650
  const key = RUNTIME_SPECS[runtime5].afkKey;