@remixhq/claude-plugin 0.1.24 → 0.1.25

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.
@@ -38,7 +38,7 @@ var require_windows = __commonJS({
38
38
  module2.exports = isexe;
39
39
  isexe.sync = sync;
40
40
  var fs13 = require("fs");
41
- function checkPathExt(path16, options) {
41
+ function checkPathExt(path17, options) {
42
42
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
43
43
  if (!pathext) {
44
44
  return true;
@@ -49,25 +49,25 @@ var require_windows = __commonJS({
49
49
  }
50
50
  for (var i2 = 0; i2 < pathext.length; i2++) {
51
51
  var p = pathext[i2].toLowerCase();
52
- if (p && path16.substr(-p.length).toLowerCase() === p) {
52
+ if (p && path17.substr(-p.length).toLowerCase() === p) {
53
53
  return true;
54
54
  }
55
55
  }
56
56
  return false;
57
57
  }
58
- function checkStat(stat, path16, options) {
58
+ function checkStat(stat, path17, options) {
59
59
  if (!stat.isSymbolicLink() && !stat.isFile()) {
60
60
  return false;
61
61
  }
62
- return checkPathExt(path16, options);
62
+ return checkPathExt(path17, options);
63
63
  }
64
- function isexe(path16, options, cb) {
65
- fs13.stat(path16, function(er, stat) {
66
- cb(er, er ? false : checkStat(stat, path16, options));
64
+ function isexe(path17, options, cb) {
65
+ fs13.stat(path17, function(er, stat) {
66
+ cb(er, er ? false : checkStat(stat, path17, options));
67
67
  });
68
68
  }
69
- function sync(path16, options) {
70
- return checkStat(fs13.statSync(path16), path16, options);
69
+ function sync(path17, options) {
70
+ return checkStat(fs13.statSync(path17), path17, options);
71
71
  }
72
72
  }
73
73
  });
@@ -79,13 +79,13 @@ var require_mode = __commonJS({
79
79
  module2.exports = isexe;
80
80
  isexe.sync = sync;
81
81
  var fs13 = require("fs");
82
- function isexe(path16, options, cb) {
83
- fs13.stat(path16, function(er, stat) {
82
+ function isexe(path17, options, cb) {
83
+ fs13.stat(path17, function(er, stat) {
84
84
  cb(er, er ? false : checkStat(stat, options));
85
85
  });
86
86
  }
87
- function sync(path16, options) {
88
- return checkStat(fs13.statSync(path16), options);
87
+ function sync(path17, options) {
88
+ return checkStat(fs13.statSync(path17), options);
89
89
  }
90
90
  function checkStat(stat, options) {
91
91
  return stat.isFile() && checkMode(stat, options);
@@ -119,7 +119,7 @@ var require_isexe = __commonJS({
119
119
  }
120
120
  module2.exports = isexe;
121
121
  isexe.sync = sync;
122
- function isexe(path16, options, cb) {
122
+ function isexe(path17, options, cb) {
123
123
  if (typeof options === "function") {
124
124
  cb = options;
125
125
  options = {};
@@ -129,7 +129,7 @@ var require_isexe = __commonJS({
129
129
  throw new TypeError("callback not provided");
130
130
  }
131
131
  return new Promise(function(resolve, reject) {
132
- isexe(path16, options || {}, function(er, is) {
132
+ isexe(path17, options || {}, function(er, is) {
133
133
  if (er) {
134
134
  reject(er);
135
135
  } else {
@@ -138,7 +138,7 @@ var require_isexe = __commonJS({
138
138
  });
139
139
  });
140
140
  }
141
- core(path16, options || {}, function(er, is) {
141
+ core(path17, options || {}, function(er, is) {
142
142
  if (er) {
143
143
  if (er.code === "EACCES" || options && options.ignoreErrors) {
144
144
  er = null;
@@ -148,9 +148,9 @@ var require_isexe = __commonJS({
148
148
  cb(er, is);
149
149
  });
150
150
  }
151
- function sync(path16, options) {
151
+ function sync(path17, options) {
152
152
  try {
153
- return core.sync(path16, options || {});
153
+ return core.sync(path17, options || {});
154
154
  } catch (er) {
155
155
  if (options && options.ignoreErrors || er.code === "EACCES") {
156
156
  return false;
@@ -167,7 +167,7 @@ var require_which = __commonJS({
167
167
  "node_modules/which/which.js"(exports2, module2) {
168
168
  "use strict";
169
169
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
170
- var path16 = require("path");
170
+ var path17 = require("path");
171
171
  var COLON = isWindows ? ";" : ":";
172
172
  var isexe = require_isexe();
173
173
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -205,7 +205,7 @@ var require_which = __commonJS({
205
205
  return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
206
206
  const ppRaw = pathEnv[i2];
207
207
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
208
- const pCmd = path16.join(pathPart, cmd);
208
+ const pCmd = path17.join(pathPart, cmd);
209
209
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
210
210
  resolve(subStep(p, i2, 0));
211
211
  });
@@ -232,7 +232,7 @@ var require_which = __commonJS({
232
232
  for (let i2 = 0; i2 < pathEnv.length; i2++) {
233
233
  const ppRaw = pathEnv[i2];
234
234
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
235
- const pCmd = path16.join(pathPart, cmd);
235
+ const pCmd = path17.join(pathPart, cmd);
236
236
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
237
237
  for (let j = 0; j < pathExt.length; j++) {
238
238
  const cur = p + pathExt[j];
@@ -280,7 +280,7 @@ var require_path_key = __commonJS({
280
280
  var require_resolveCommand = __commonJS({
281
281
  "node_modules/cross-spawn/lib/util/resolveCommand.js"(exports2, module2) {
282
282
  "use strict";
283
- var path16 = require("path");
283
+ var path17 = require("path");
284
284
  var which = require_which();
285
285
  var getPathKey = require_path_key();
286
286
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -298,7 +298,7 @@ var require_resolveCommand = __commonJS({
298
298
  try {
299
299
  resolved = which.sync(parsed.command, {
300
300
  path: env[getPathKey({ env })],
301
- pathExt: withoutPathExt ? path16.delimiter : void 0
301
+ pathExt: withoutPathExt ? path17.delimiter : void 0
302
302
  });
303
303
  } catch (e) {
304
304
  } finally {
@@ -307,7 +307,7 @@ var require_resolveCommand = __commonJS({
307
307
  }
308
308
  }
309
309
  if (resolved) {
310
- resolved = path16.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
310
+ resolved = path17.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
311
311
  }
312
312
  return resolved;
313
313
  }
@@ -361,8 +361,8 @@ var require_shebang_command = __commonJS({
361
361
  if (!match) {
362
362
  return null;
363
363
  }
364
- const [path16, argument] = match[0].replace(/#! ?/, "").split(" ");
365
- const binary = path16.split("/").pop();
364
+ const [path17, argument] = match[0].replace(/#! ?/, "").split(" ");
365
+ const binary = path17.split("/").pop();
366
366
  if (binary === "env") {
367
367
  return argument;
368
368
  }
@@ -397,7 +397,7 @@ var require_readShebang = __commonJS({
397
397
  var require_parse = __commonJS({
398
398
  "node_modules/cross-spawn/lib/parse.js"(exports2, module2) {
399
399
  "use strict";
400
- var path16 = require("path");
400
+ var path17 = require("path");
401
401
  var resolveCommand = require_resolveCommand();
402
402
  var escape = require_escape();
403
403
  var readShebang = require_readShebang();
@@ -422,7 +422,7 @@ var require_parse = __commonJS({
422
422
  const needsShell = !isExecutableRegExp.test(commandFile);
423
423
  if (parsed.options.forceShell || needsShell) {
424
424
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
425
- parsed.command = path16.normalize(parsed.command);
425
+ parsed.command = path17.normalize(parsed.command);
426
426
  parsed.command = escape.command(parsed.command);
427
427
  parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
428
428
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -4941,13 +4941,13 @@ var logOutputSync = ({ serializedResult, fdNumber, state, verboseInfo, encoding,
4941
4941
  }
4942
4942
  };
4943
4943
  var writeToFiles = (serializedResult, stdioItems, outputFiles) => {
4944
- for (const { path: path16, append } of stdioItems.filter(({ type }) => FILE_TYPES.has(type))) {
4945
- const pathString = typeof path16 === "string" ? path16 : path16.toString();
4944
+ for (const { path: path17, append } of stdioItems.filter(({ type }) => FILE_TYPES.has(type))) {
4945
+ const pathString = typeof path17 === "string" ? path17 : path17.toString();
4946
4946
  if (append || outputFiles.has(pathString)) {
4947
- (0, import_node_fs4.appendFileSync)(path16, serializedResult);
4947
+ (0, import_node_fs4.appendFileSync)(path17, serializedResult);
4948
4948
  } else {
4949
4949
  outputFiles.add(pathString);
4950
- (0, import_node_fs4.writeFileSync)(path16, serializedResult);
4950
+ (0, import_node_fs4.writeFileSync)(path17, serializedResult);
4951
4951
  }
4952
4952
  }
4953
4953
  };
@@ -10171,8 +10171,10 @@ function isFinalizePreflightFailureCode(value) {
10171
10171
 
10172
10172
  // src/auto-fix-dispatcher.ts
10173
10173
  var import_node_child_process6 = require("child_process");
10174
+ var import_node_crypto4 = require("crypto");
10174
10175
  var import_node_fs6 = require("fs");
10175
- var import_node_path9 = __toESM(require("path"), 1);
10176
+ var import_node_os7 = __toESM(require("os"), 1);
10177
+ var import_node_path10 = __toESM(require("path"), 1);
10176
10178
 
10177
10179
  // src/finalize-failure-marker.ts
10178
10180
  var import_promises18 = __toESM(require("fs/promises"), 1);
@@ -10211,32 +10213,47 @@ function buildFreshFailureMarker(params) {
10211
10213
  };
10212
10214
  }
10213
10215
 
10216
+ // src/collab-init-spawn-lock.ts
10217
+ var import_node_crypto = require("crypto");
10218
+ var import_node_os4 = __toESM(require("os"), 1);
10219
+ var import_node_path7 = __toESM(require("path"), 1);
10220
+ function stateRoot() {
10221
+ const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
10222
+ return configured || import_node_path7.default.join(import_node_os4.default.tmpdir(), "remix-claude-plugin-hooks");
10223
+ }
10224
+ function sha256Hex3(value) {
10225
+ return (0, import_node_crypto.createHash)("sha256").update(value).digest("hex");
10226
+ }
10227
+ function collabInitSpawnLockPath(repoRoot) {
10228
+ return import_node_path7.default.join(stateRoot(), "collab-init-spawn-locks", `${sha256Hex3(repoRoot)}.json`);
10229
+ }
10230
+
10214
10231
  // src/hook-diagnostics.ts
10215
- var import_node_crypto2 = require("crypto");
10232
+ var import_node_crypto3 = require("crypto");
10216
10233
  var import_promises20 = __toESM(require("fs/promises"), 1);
10217
- var import_node_os5 = __toESM(require("os"), 1);
10218
- var import_node_path8 = __toESM(require("path"), 1);
10234
+ var import_node_os6 = __toESM(require("os"), 1);
10235
+ var import_node_path9 = __toESM(require("path"), 1);
10219
10236
 
10220
10237
  // src/hook-state.ts
10221
10238
  var import_promises19 = __toESM(require("fs/promises"), 1);
10222
- var import_node_os4 = __toESM(require("os"), 1);
10223
- var import_node_path7 = __toESM(require("path"), 1);
10224
- var import_node_crypto = require("crypto");
10225
- function stateRoot() {
10239
+ var import_node_os5 = __toESM(require("os"), 1);
10240
+ var import_node_path8 = __toESM(require("path"), 1);
10241
+ var import_node_crypto2 = require("crypto");
10242
+ function stateRoot2() {
10226
10243
  const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
10227
- return configured || import_node_path7.default.join(import_node_os4.default.tmpdir(), "remix-claude-plugin-hooks");
10244
+ return configured || import_node_path8.default.join(import_node_os5.default.tmpdir(), "remix-claude-plugin-hooks");
10228
10245
  }
10229
10246
  function statePath(sessionId) {
10230
- return import_node_path7.default.join(stateRoot(), `${sessionId}.json`);
10247
+ return import_node_path8.default.join(stateRoot2(), `${sessionId}.json`);
10231
10248
  }
10232
10249
  function stateLockPath(sessionId) {
10233
- return import_node_path7.default.join(stateRoot(), `${sessionId}.lock`);
10250
+ return import_node_path8.default.join(stateRoot2(), `${sessionId}.lock`);
10234
10251
  }
10235
10252
  function stateLockMetaPath(sessionId) {
10236
- return import_node_path7.default.join(stateLockPath(sessionId), "owner.json");
10253
+ return import_node_path8.default.join(stateLockPath(sessionId), "owner.json");
10237
10254
  }
10238
10255
  async function writeJsonAtomic2(filePath, value) {
10239
- await import_promises19.default.mkdir(import_node_path7.default.dirname(filePath), { recursive: true });
10256
+ await import_promises19.default.mkdir(import_node_path8.default.dirname(filePath), { recursive: true });
10240
10257
  const tmpPath = `${filePath}.tmp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
10241
10258
  await import_promises19.default.writeFile(tmpPath, JSON.stringify(value, null, 2) + "\n", "utf8");
10242
10259
  await import_promises19.default.rename(tmpPath, filePath);
@@ -10289,11 +10306,11 @@ async function tryRemoveStaleStateLock(sessionId) {
10289
10306
  async function acquireStateLock(sessionId) {
10290
10307
  const lockPath = stateLockPath(sessionId);
10291
10308
  const deadline = Date.now() + STATE_LOCK_WAIT_MS;
10292
- await import_promises19.default.mkdir(stateRoot(), { recursive: true });
10309
+ await import_promises19.default.mkdir(stateRoot2(), { recursive: true });
10293
10310
  while (true) {
10294
10311
  try {
10295
10312
  await import_promises19.default.mkdir(lockPath);
10296
- const ownerId = (0, import_node_crypto.randomUUID)();
10313
+ const ownerId = (0, import_node_crypto2.randomUUID)();
10297
10314
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
10298
10315
  const metadata = {
10299
10316
  ownerId,
@@ -10524,7 +10541,7 @@ async function markTouchedRepoRecordingFailure(sessionId, repoRoot, params) {
10524
10541
  });
10525
10542
  }
10526
10543
  function lastFinalizedPath(sessionId) {
10527
- return import_node_path7.default.join(stateRoot(), `${sessionId}.last-finalized.json`);
10544
+ return import_node_path8.default.join(stateRoot2(), `${sessionId}.last-finalized.json`);
10528
10545
  }
10529
10546
  async function markLastFinalizedTurn(sessionId, turnId, prompt) {
10530
10547
  const record = {
@@ -10574,7 +10591,7 @@ async function clearPendingTurnState(sessionId) {
10574
10591
  // package.json
10575
10592
  var package_default = {
10576
10593
  name: "@remixhq/claude-plugin",
10577
- version: "0.1.24",
10594
+ version: "0.1.25",
10578
10595
  description: "Claude Code plugin for Remix collaboration workflows",
10579
10596
  homepage: "https://github.com/RemixDotOne/remix-claude-plugin",
10580
10597
  license: "MIT",
@@ -10612,8 +10629,8 @@ var package_default = {
10612
10629
  prepack: "npm run build"
10613
10630
  },
10614
10631
  dependencies: {
10615
- "@remixhq/core": "^0.1.19",
10616
- "@remixhq/mcp": "^0.1.19"
10632
+ "@remixhq/core": "^0.1.20",
10633
+ "@remixhq/mcp": "^0.1.20"
10617
10634
  },
10618
10635
  devDependencies: {
10619
10636
  "@types/node": "^25.4.0",
@@ -10636,17 +10653,17 @@ var pluginMetadata = {
10636
10653
  var MAX_LOG_BYTES = 512 * 1024;
10637
10654
  function resolveClaudeRoot() {
10638
10655
  const configured = process.env.CLAUDE_CONFIG_DIR?.trim();
10639
- return configured || import_node_path8.default.join(import_node_os5.default.homedir(), ".claude");
10656
+ return configured || import_node_path9.default.join(import_node_os6.default.homedir(), ".claude");
10640
10657
  }
10641
10658
  function resolvePluginDataDirName() {
10642
10659
  return `${pluginMetadata.pluginId}-${pluginMetadata.pluginId}`;
10643
10660
  }
10644
10661
  function getHookDiagnosticsDirPath() {
10645
10662
  const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_DIAGNOSTICS_DIR?.trim();
10646
- return configured || import_node_path8.default.join(resolveClaudeRoot(), "plugins", "data", resolvePluginDataDirName());
10663
+ return configured || import_node_path9.default.join(resolveClaudeRoot(), "plugins", "data", resolvePluginDataDirName());
10647
10664
  }
10648
10665
  function getHookDiagnosticsLogPath() {
10649
- return import_node_path8.default.join(getHookDiagnosticsDirPath(), "hooks.ndjson");
10666
+ return import_node_path9.default.join(getHookDiagnosticsDirPath(), "hooks.ndjson");
10650
10667
  }
10651
10668
  function toFieldValue(value) {
10652
10669
  if (value === null) return null;
@@ -10684,13 +10701,13 @@ function summarizeText(value) {
10684
10701
  return {
10685
10702
  present: true,
10686
10703
  length: trimmed.length,
10687
- sha256Prefix: (0, import_node_crypto2.createHash)("sha256").update(trimmed).digest("hex").slice(0, 12)
10704
+ sha256Prefix: (0, import_node_crypto3.createHash)("sha256").update(trimmed).digest("hex").slice(0, 12)
10688
10705
  };
10689
10706
  }
10690
10707
  async function appendHookDiagnosticsEvent(params) {
10691
10708
  try {
10692
10709
  const logPath = getHookDiagnosticsLogPath();
10693
- await import_promises20.default.mkdir(import_node_path8.default.dirname(logPath), { recursive: true });
10710
+ await import_promises20.default.mkdir(import_node_path9.default.dirname(logPath), { recursive: true });
10694
10711
  await rotateLogIfNeeded(logPath);
10695
10712
  const event = {
10696
10713
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -10740,18 +10757,27 @@ var RECOMMENDED_USER_COMMAND = {
10740
10757
  pull_required: "remix collab sync",
10741
10758
  baseline_missing: "remix collab init"
10742
10759
  };
10743
- var SPAWN_LOCK_REL = (cmdSlug) => import_node_path9.default.join(".remix", `.${cmdSlug}-spawning`);
10744
- var SPAWN_LOG_REL = (cmdSlug) => import_node_path9.default.join(".remix", `${cmdSlug}.log`);
10745
10760
  var SPAWN_THROTTLE_MS = 5 * 60 * 1e3;
10746
10761
  function commandSlug(args) {
10747
10762
  return args.join("-").replace(/[^a-zA-Z0-9_-]/g, "_");
10748
10763
  }
10764
+ function stateRoot3() {
10765
+ const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
10766
+ return configured || import_node_path10.default.join(import_node_os7.default.tmpdir(), "remix-claude-plugin-hooks");
10767
+ }
10768
+ function sha256Hex4(value) {
10769
+ return (0, import_node_crypto4.createHash)("sha256").update(value).digest("hex");
10770
+ }
10771
+ function spawnLockPath(repoRoot, cmdSlug) {
10772
+ if (cmdSlug === "collab-init") {
10773
+ return collabInitSpawnLockPath(repoRoot);
10774
+ }
10775
+ return import_node_path10.default.join(stateRoot3(), "auto-fix-spawn-locks", sha256Hex4(repoRoot), `${cmdSlug}.lock`);
10776
+ }
10749
10777
  function spawnFixDetached(repoRoot, args) {
10750
10778
  const slug = commandSlug(args);
10751
10779
  const command = `remix ${args.join(" ")}`;
10752
- const remixDir = import_node_path9.default.join(repoRoot, ".remix");
10753
- const lockPath = import_node_path9.default.join(repoRoot, SPAWN_LOCK_REL(slug));
10754
- const logPath = import_node_path9.default.join(repoRoot, SPAWN_LOG_REL(slug));
10780
+ const lockPath = spawnLockPath(repoRoot, slug);
10755
10781
  try {
10756
10782
  if ((0, import_node_fs6.existsSync)(lockPath)) {
10757
10783
  const ageMs = Date.now() - (0, import_node_fs6.statSync)(lockPath).mtimeMs;
@@ -10762,27 +10788,14 @@ function spawnFixDetached(repoRoot, args) {
10762
10788
  } catch {
10763
10789
  }
10764
10790
  try {
10765
- (0, import_node_fs6.mkdirSync)(remixDir, { recursive: true });
10791
+ (0, import_node_fs6.mkdirSync)(import_node_path10.default.dirname(lockPath), { recursive: true });
10766
10792
  } catch {
10767
10793
  }
10768
- let out;
10769
- let err;
10770
- try {
10771
- out = (0, import_node_fs6.openSync)(logPath, "a");
10772
- err = (0, import_node_fs6.openSync)(logPath, "a");
10773
- } catch (logErr) {
10774
- return {
10775
- kind: "spawn_failed",
10776
- command,
10777
- reason: "log_open_failed",
10778
- message: logErr instanceof Error ? logErr.message : String(logErr)
10779
- };
10780
- }
10781
10794
  try {
10782
10795
  const child = (0, import_node_child_process6.spawn)("remix", [...args], {
10783
10796
  cwd: repoRoot,
10784
10797
  detached: true,
10785
- stdio: ["ignore", out, err],
10798
+ stdio: "ignore",
10786
10799
  env: { ...process.env, REMIX_AUTO_FIX_SPAWN: "1" }
10787
10800
  });
10788
10801
  child.unref();
@@ -10791,7 +10804,7 @@ function spawnFixDetached(repoRoot, args) {
10791
10804
  (0, import_node_fs6.utimesSync)(lockPath, /* @__PURE__ */ new Date(), /* @__PURE__ */ new Date());
10792
10805
  } catch {
10793
10806
  }
10794
- return { kind: "spawned", command, pid: child.pid, logPath };
10807
+ return { kind: "spawned", command, pid: child.pid };
10795
10808
  } catch (spawnErr) {
10796
10809
  return {
10797
10810
  kind: "spawn_failed",
@@ -10847,7 +10860,6 @@ async function dispatchFinalizeFailure(input) {
10847
10860
  preflightCode: input.preflightCode,
10848
10861
  command: "command" in outcome ? outcome.command : null,
10849
10862
  pid: outcome.kind === "spawned" ? outcome.pid ?? null : null,
10850
- logPath: outcome.kind === "spawned" ? outcome.logPath : null,
10851
10863
  recommendedCommand
10852
10864
  },
10853
10865
  message: outcome.kind === "spawn_failed" ? outcome.message : null
@@ -10860,7 +10872,7 @@ function mergeOutcomeIntoMarker(existing, outcome) {
10860
10872
  status: "in_progress",
10861
10873
  command: outcome.command,
10862
10874
  pid: outcome.pid ?? null,
10863
- logPath: outcome.logPath,
10875
+ logPath: null,
10864
10876
  attemptedAt: (/* @__PURE__ */ new Date()).toISOString(),
10865
10877
  failureMessage: null
10866
10878
  };
@@ -10890,25 +10902,25 @@ function mergeOutcomeIntoMarker(existing, outcome) {
10890
10902
 
10891
10903
  // src/deferred-turn-queue.ts
10892
10904
  var import_promises21 = __toESM(require("fs/promises"), 1);
10893
- var import_node_os6 = __toESM(require("os"), 1);
10894
- var import_node_path10 = __toESM(require("path"), 1);
10905
+ var import_node_os8 = __toESM(require("os"), 1);
10906
+ var import_node_path11 = __toESM(require("path"), 1);
10895
10907
  var DEFERRED_TURN_SCHEMA_VERSION = 1;
10896
10908
  var DEFERRED_TURN_MAX_ATTEMPTS = 10;
10897
10909
  var DEFERRED_TURN_TTL_MS = 24 * 60 * 60 * 1e3;
10898
10910
  var DEFERRED_TURN_DIR = "deferred-turns";
10899
- function stateRoot2() {
10911
+ function stateRoot4() {
10900
10912
  const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
10901
- return configured || import_node_path10.default.join(import_node_os6.default.tmpdir(), "remix-claude-plugin-hooks");
10913
+ return configured || import_node_path11.default.join(import_node_os8.default.tmpdir(), "remix-claude-plugin-hooks");
10902
10914
  }
10903
10915
  function getDeferredTurnDirPath() {
10904
- return import_node_path10.default.join(stateRoot2(), DEFERRED_TURN_DIR);
10916
+ return import_node_path11.default.join(stateRoot4(), DEFERRED_TURN_DIR);
10905
10917
  }
10906
10918
  function deferredTurnFileName(sessionId, turnId) {
10907
10919
  const safe = (s) => s.replace(/[^A-Za-z0-9_-]/g, "_");
10908
10920
  return `${safe(sessionId)}-${safe(turnId)}.json`;
10909
10921
  }
10910
10922
  function getDeferredTurnFilePath(sessionId, turnId) {
10911
- return import_node_path10.default.join(getDeferredTurnDirPath(), deferredTurnFileName(sessionId, turnId));
10923
+ return import_node_path11.default.join(getDeferredTurnDirPath(), deferredTurnFileName(sessionId, turnId));
10912
10924
  }
10913
10925
  async function writeDeferredTurn(record) {
10914
10926
  if (record.schemaVersion !== DEFERRED_TURN_SCHEMA_VERSION) {
@@ -10969,7 +10981,7 @@ async function listDeferredTurnsForRepo(repoRoot) {
10969
10981
  const entries = [];
10970
10982
  for (const entry of dirEntries) {
10971
10983
  if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
10972
- const filePath = import_node_path10.default.join(dir, entry.name);
10984
+ const filePath = import_node_path11.default.join(dir, entry.name);
10973
10985
  const record = await readDeferredTurnFile(filePath);
10974
10986
  if (!record) continue;
10975
10987
  if (record.repoRoot !== repoRoot) continue;
@@ -10993,7 +11005,7 @@ async function pruneStaleDeferredTurns(maxAgeMs = DEFERRED_TURN_TTL_MS) {
10993
11005
  const now = Date.now();
10994
11006
  for (const entry of dirEntries) {
10995
11007
  if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
10996
- const filePath = import_node_path10.default.join(dir, entry.name);
11008
+ const filePath = import_node_path11.default.join(dir, entry.name);
10997
11009
  const record = await readDeferredTurnFile(filePath);
10998
11010
  if (!record) {
10999
11011
  const stat = await import_promises21.default.stat(filePath).catch(() => null);
@@ -11048,8 +11060,8 @@ async function recordDeferredTurnFailedAttempt(filePath) {
11048
11060
 
11049
11061
  // src/deferred-turn-drainer.ts
11050
11062
  var import_promises23 = __toESM(require("fs/promises"), 1);
11051
- var import_node_path11 = __toESM(require("path"), 1);
11052
- var import_node_crypto3 = require("crypto");
11063
+ var import_node_path12 = __toESM(require("path"), 1);
11064
+ var import_node_crypto5 = require("crypto");
11053
11065
 
11054
11066
  // node_modules/@remixhq/core/dist/chunk-C2FOZ3O7.js
11055
11067
  async function readJsonSafe(res) {
@@ -11070,7 +11082,7 @@ function createApiClient(config, opts) {
11070
11082
  const ms = typeof timeoutMs === "number" && timeoutMs > 0 ? timeoutMs : defaultTimeoutMs;
11071
11083
  return ms != null ? AbortSignal.timeout(ms) : void 0;
11072
11084
  }
11073
- async function request(path16, init, opts2) {
11085
+ async function request(path17, init, opts2) {
11074
11086
  if (!tokenProvider) {
11075
11087
  throw new RemixError("API client is missing a token provider.", {
11076
11088
  exitCode: 1,
@@ -11078,7 +11090,7 @@ function createApiClient(config, opts) {
11078
11090
  });
11079
11091
  }
11080
11092
  const auth = await tokenProvider();
11081
- const url = new URL(path16, config.apiUrl).toString();
11093
+ const url = new URL(path17, config.apiUrl).toString();
11082
11094
  const doFetch = async (bearer) => fetch(url, {
11083
11095
  ...init,
11084
11096
  signal: makeTimeoutSignal(opts2?.timeoutMs),
@@ -11107,7 +11119,7 @@ function createApiClient(config, opts) {
11107
11119
  const json = await readJsonSafe(res);
11108
11120
  return json ?? null;
11109
11121
  }
11110
- async function requestBinary(path16, init, opts2) {
11122
+ async function requestBinary(path17, init, opts2) {
11111
11123
  if (!tokenProvider) {
11112
11124
  throw new RemixError("API client is missing a token provider.", {
11113
11125
  exitCode: 1,
@@ -11115,7 +11127,7 @@ function createApiClient(config, opts) {
11115
11127
  });
11116
11128
  }
11117
11129
  const auth = await tokenProvider();
11118
- const url = new URL(path16, config.apiUrl).toString();
11130
+ const url = new URL(path17, config.apiUrl).toString();
11119
11131
  const doFetch = async (bearer) => fetch(url, {
11120
11132
  ...init,
11121
11133
  signal: makeTimeoutSignal(opts2?.timeoutMs),
@@ -11978,8 +11990,8 @@ function getErrorMap() {
11978
11990
 
11979
11991
  // node_modules/zod/v3/helpers/parseUtil.js
11980
11992
  var makeIssue = (params) => {
11981
- const { data, path: path16, errorMaps, issueData } = params;
11982
- const fullPath = [...path16, ...issueData.path || []];
11993
+ const { data, path: path17, errorMaps, issueData } = params;
11994
+ const fullPath = [...path17, ...issueData.path || []];
11983
11995
  const fullIssue = {
11984
11996
  ...issueData,
11985
11997
  path: fullPath
@@ -12095,11 +12107,11 @@ var errorUtil;
12095
12107
 
12096
12108
  // node_modules/zod/v3/types.js
12097
12109
  var ParseInputLazyPath = class {
12098
- constructor(parent, value, path16, key) {
12110
+ constructor(parent, value, path17, key) {
12099
12111
  this._cachedPath = [];
12100
12112
  this.parent = parent;
12101
12113
  this.data = value;
12102
- this._path = path16;
12114
+ this._path = path17;
12103
12115
  this._key = key;
12104
12116
  }
12105
12117
  get path() {
@@ -24647,8 +24659,8 @@ var IcebergError = class extends Error {
24647
24659
  return this.status === 419;
24648
24660
  }
24649
24661
  };
24650
- function buildUrl(baseUrl, path16, query) {
24651
- const url = new URL(path16, baseUrl);
24662
+ function buildUrl(baseUrl, path17, query) {
24663
+ const url = new URL(path17, baseUrl);
24652
24664
  if (query) {
24653
24665
  for (const [key, value] of Object.entries(query)) {
24654
24666
  if (value !== void 0) {
@@ -24678,12 +24690,12 @@ function createFetchClient(options) {
24678
24690
  return {
24679
24691
  async request({
24680
24692
  method,
24681
- path: path16,
24693
+ path: path17,
24682
24694
  query,
24683
24695
  body,
24684
24696
  headers
24685
24697
  }) {
24686
- const url = buildUrl(options.baseUrl, path16, query);
24698
+ const url = buildUrl(options.baseUrl, path17, query);
24687
24699
  const authHeaders = await buildAuthHeaders(options.auth);
24688
24700
  const res = await fetchFn(url, {
24689
24701
  method,
@@ -25521,7 +25533,7 @@ var StorageFileApi = class extends BaseApiClient {
25521
25533
  * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.
25522
25534
  * @param fileBody The body of the file to be stored in the bucket.
25523
25535
  */
25524
- async uploadOrUpdate(method, path16, fileBody, fileOptions) {
25536
+ async uploadOrUpdate(method, path17, fileBody, fileOptions) {
25525
25537
  var _this = this;
25526
25538
  return _this.handleOperation(async () => {
25527
25539
  let body;
@@ -25545,7 +25557,7 @@ var StorageFileApi = class extends BaseApiClient {
25545
25557
  if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
25546
25558
  }
25547
25559
  if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) for (const [key, value] of Object.entries(fileOptions.headers)) headers = setHeader(headers, key, value);
25548
- const cleanPath = _this._removeEmptyFolders(path16);
25560
+ const cleanPath = _this._removeEmptyFolders(path17);
25549
25561
  const _path = _this._getFinalPath(cleanPath);
25550
25562
  const data = await (method == "PUT" ? put : post)(_this.fetch, `${_this.url}/object/${_path}`, body, _objectSpread22({ headers }, (options === null || options === void 0 ? void 0 : options.duplex) ? { duplex: options.duplex } : {}));
25551
25563
  return {
@@ -25606,8 +25618,8 @@ var StorageFileApi = class extends BaseApiClient {
25606
25618
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
25607
25619
  * - For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Upload file using `ArrayBuffer` from base64 file data instead, see example below.
25608
25620
  */
25609
- async upload(path16, fileBody, fileOptions) {
25610
- return this.uploadOrUpdate("POST", path16, fileBody, fileOptions);
25621
+ async upload(path17, fileBody, fileOptions) {
25622
+ return this.uploadOrUpdate("POST", path17, fileBody, fileOptions);
25611
25623
  }
25612
25624
  /**
25613
25625
  * Upload a file with a token generated from `createSignedUploadUrl`.
@@ -25646,9 +25658,9 @@ var StorageFileApi = class extends BaseApiClient {
25646
25658
  * - `objects` table permissions: none
25647
25659
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
25648
25660
  */
25649
- async uploadToSignedUrl(path16, token, fileBody, fileOptions) {
25661
+ async uploadToSignedUrl(path17, token, fileBody, fileOptions) {
25650
25662
  var _this3 = this;
25651
- const cleanPath = _this3._removeEmptyFolders(path16);
25663
+ const cleanPath = _this3._removeEmptyFolders(path17);
25652
25664
  const _path = _this3._getFinalPath(cleanPath);
25653
25665
  const url = new URL(_this3.url + `/object/upload/sign/${_path}`);
25654
25666
  url.searchParams.set("token", token);
@@ -25710,10 +25722,10 @@ var StorageFileApi = class extends BaseApiClient {
25710
25722
  * - `objects` table permissions: `insert`
25711
25723
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
25712
25724
  */
25713
- async createSignedUploadUrl(path16, options) {
25725
+ async createSignedUploadUrl(path17, options) {
25714
25726
  var _this4 = this;
25715
25727
  return _this4.handleOperation(async () => {
25716
- let _path = _this4._getFinalPath(path16);
25728
+ let _path = _this4._getFinalPath(path17);
25717
25729
  const headers = _objectSpread22({}, _this4.headers);
25718
25730
  if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
25719
25731
  const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
@@ -25722,7 +25734,7 @@ var StorageFileApi = class extends BaseApiClient {
25722
25734
  if (!token) throw new StorageError("No token returned by API");
25723
25735
  return {
25724
25736
  signedUrl: url.toString(),
25725
- path: path16,
25737
+ path: path17,
25726
25738
  token
25727
25739
  };
25728
25740
  });
@@ -25778,8 +25790,8 @@ var StorageFileApi = class extends BaseApiClient {
25778
25790
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
25779
25791
  * - For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Update file using `ArrayBuffer` from base64 file data instead, see example below.
25780
25792
  */
25781
- async update(path16, fileBody, fileOptions) {
25782
- return this.uploadOrUpdate("PUT", path16, fileBody, fileOptions);
25793
+ async update(path17, fileBody, fileOptions) {
25794
+ return this.uploadOrUpdate("PUT", path17, fileBody, fileOptions);
25783
25795
  }
25784
25796
  /**
25785
25797
  * Moves an existing file to a new path in the same bucket.
@@ -25927,10 +25939,10 @@ var StorageFileApi = class extends BaseApiClient {
25927
25939
  * - `objects` table permissions: `select`
25928
25940
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
25929
25941
  */
25930
- async createSignedUrl(path16, expiresIn, options) {
25942
+ async createSignedUrl(path17, expiresIn, options) {
25931
25943
  var _this8 = this;
25932
25944
  return _this8.handleOperation(async () => {
25933
- let _path = _this8._getFinalPath(path16);
25945
+ let _path = _this8._getFinalPath(path17);
25934
25946
  const hasTransform = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0;
25935
25947
  let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, hasTransform ? { transform: options.transform } : {}), { headers: _this8.headers });
25936
25948
  const query = new URLSearchParams();
@@ -26064,13 +26076,13 @@ var StorageFileApi = class extends BaseApiClient {
26064
26076
  * - `objects` table permissions: `select`
26065
26077
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
26066
26078
  */
26067
- download(path16, options, parameters) {
26079
+ download(path17, options, parameters) {
26068
26080
  const renderPath = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0 ? "render/image/authenticated" : "object";
26069
26081
  const query = new URLSearchParams();
26070
26082
  if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
26071
26083
  if ((options === null || options === void 0 ? void 0 : options.cacheNonce) != null) query.set("cacheNonce", String(options.cacheNonce));
26072
26084
  const queryString = query.toString();
26073
- const _path = this._getFinalPath(path16);
26085
+ const _path = this._getFinalPath(path17);
26074
26086
  const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ""}`, {
26075
26087
  headers: this.headers,
26076
26088
  noResolveJson: true
@@ -26100,9 +26112,9 @@ var StorageFileApi = class extends BaseApiClient {
26100
26112
  * }
26101
26113
  * ```
26102
26114
  */
26103
- async info(path16) {
26115
+ async info(path17) {
26104
26116
  var _this10 = this;
26105
- const _path = _this10._getFinalPath(path16);
26117
+ const _path = _this10._getFinalPath(path17);
26106
26118
  return _this10.handleOperation(async () => {
26107
26119
  return recursiveToCamel(await get(_this10.fetch, `${_this10.url}/object/info/${_path}`, { headers: _this10.headers }));
26108
26120
  });
@@ -26122,9 +26134,9 @@ var StorageFileApi = class extends BaseApiClient {
26122
26134
  * .exists('folder/avatar1.png')
26123
26135
  * ```
26124
26136
  */
26125
- async exists(path16) {
26137
+ async exists(path17) {
26126
26138
  var _this11 = this;
26127
- const _path = _this11._getFinalPath(path16);
26139
+ const _path = _this11._getFinalPath(path17);
26128
26140
  try {
26129
26141
  await head(_this11.fetch, `${_this11.url}/object/${_path}`, { headers: _this11.headers });
26130
26142
  return {
@@ -26202,8 +26214,8 @@ var StorageFileApi = class extends BaseApiClient {
26202
26214
  * - `objects` table permissions: none
26203
26215
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
26204
26216
  */
26205
- getPublicUrl(path16, options) {
26206
- const _path = this._getFinalPath(path16);
26217
+ getPublicUrl(path17, options) {
26218
+ const _path = this._getFinalPath(path17);
26207
26219
  const query = new URLSearchParams();
26208
26220
  if (options === null || options === void 0 ? void 0 : options.download) query.set("download", options.download === true ? "" : options.download);
26209
26221
  if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
@@ -26340,10 +26352,10 @@ var StorageFileApi = class extends BaseApiClient {
26340
26352
  * - `objects` table permissions: `select`
26341
26353
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
26342
26354
  */
26343
- async list(path16, options, parameters) {
26355
+ async list(path17, options, parameters) {
26344
26356
  var _this13 = this;
26345
26357
  return _this13.handleOperation(async () => {
26346
- const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path16 || "" });
26358
+ const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path17 || "" });
26347
26359
  return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
26348
26360
  });
26349
26361
  }
@@ -26407,11 +26419,11 @@ var StorageFileApi = class extends BaseApiClient {
26407
26419
  if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
26408
26420
  return btoa(data);
26409
26421
  }
26410
- _getFinalPath(path16) {
26411
- return `${this.bucketId}/${path16.replace(/^\/+/, "")}`;
26422
+ _getFinalPath(path17) {
26423
+ return `${this.bucketId}/${path17.replace(/^\/+/, "")}`;
26412
26424
  }
26413
- _removeEmptyFolders(path16) {
26414
- return path16.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
26425
+ _removeEmptyFolders(path17) {
26426
+ return path17.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
26415
26427
  }
26416
26428
  /** Modifies the `query`, appending values the from `transform` */
26417
26429
  applyTransformOptsToQuery(query, transform) {
@@ -35789,11 +35801,11 @@ function isPidAlive(pid) {
35789
35801
  }
35790
35802
  }
35791
35803
  function repoLockFileName(repoRoot) {
35792
- const hash = (0, import_node_crypto3.createHash)("sha256").update(repoRoot).digest("hex").slice(0, 16);
35804
+ const hash = (0, import_node_crypto5.createHash)("sha256").update(repoRoot).digest("hex").slice(0, 16);
35793
35805
  return `.drainer-${hash}.lock`;
35794
35806
  }
35795
35807
  function repoLockPath(repoRoot) {
35796
- return import_node_path11.default.join(getDeferredTurnDirPath(), repoLockFileName(repoRoot));
35808
+ return import_node_path12.default.join(getDeferredTurnDirPath(), repoLockFileName(repoRoot));
35797
35809
  }
35798
35810
  async function readDrainLockMetadata(lockPath) {
35799
35811
  const raw = await import_promises23.default.readFile(lockPath, "utf8").catch(() => null);
@@ -35815,7 +35827,7 @@ async function writeDrainLockMetadata(lockPath, metadata) {
35815
35827
  }
35816
35828
  async function tryAcquireDrainLock(repoRoot) {
35817
35829
  const lockPath = repoLockPath(repoRoot);
35818
- await import_promises23.default.mkdir(import_node_path11.default.dirname(lockPath), { recursive: true });
35830
+ await import_promises23.default.mkdir(import_node_path12.default.dirname(lockPath), { recursive: true });
35819
35831
  const existingMeta = await readDrainLockMetadata(lockPath);
35820
35832
  if (existingMeta) {
35821
35833
  const lockStat = await import_promises23.default.stat(lockPath).catch(() => null);
@@ -36674,8 +36686,8 @@ function harvestClaudeCodeUsage(input) {
36674
36686
  // src/usage/claudeCodeSession.ts
36675
36687
  var import_node_child_process8 = require("child_process");
36676
36688
  var import_node_fs7 = require("fs");
36677
- var import_node_os7 = require("os");
36678
- var import_node_path12 = require("path");
36689
+ var import_node_os9 = require("os");
36690
+ var import_node_path13 = require("path");
36679
36691
  var CACHE_SCHEMA_VERSION = 1;
36680
36692
  var SUCCESS_TTL_MS = 60 * 60 * 1e3;
36681
36693
  var FAILURE_TTL_MS = 5 * 60 * 1e3;
@@ -36704,10 +36716,10 @@ function defaultSpawnClaudeAuthStatus(timeoutMs) {
36704
36716
  }
36705
36717
  function getCollabStateRoot2() {
36706
36718
  const configured = process.env.REMIX_COLLAB_STATE_ROOT?.trim();
36707
- return configured || (0, import_node_path12.join)((0, import_node_os7.homedir)(), ".remix", "collab-state");
36719
+ return configured || (0, import_node_path13.join)((0, import_node_os9.homedir)(), ".remix", "collab-state");
36708
36720
  }
36709
36721
  function getAuthCachePath() {
36710
- return (0, import_node_path12.join)(getCollabStateRoot2(), "claude-auth-cache.json");
36722
+ return (0, import_node_path13.join)(getCollabStateRoot2(), "claude-auth-cache.json");
36711
36723
  }
36712
36724
  function getSpawnTimeoutMs() {
36713
36725
  const raw = process.env.REMIX_CLAUDE_AUTH_TIMEOUT_MS?.trim();
@@ -36748,7 +36760,7 @@ function isCacheFresh(record) {
36748
36760
  function writeAuthCache(record) {
36749
36761
  const cachePath = getAuthCachePath();
36750
36762
  try {
36751
- (0, import_node_fs7.mkdirSync)((0, import_node_path12.dirname)(cachePath), { recursive: true });
36763
+ (0, import_node_fs7.mkdirSync)((0, import_node_path13.dirname)(cachePath), { recursive: true });
36752
36764
  const tmpPath = `${cachePath}.${process.pid}.${Date.now()}.tmp`;
36753
36765
  (0, import_node_fs7.writeFileSync)(tmpPath, JSON.stringify(record), "utf8");
36754
36766
  (0, import_node_fs7.renameSync)(tmpPath, cachePath);
@@ -36806,7 +36818,7 @@ function resolveClaudeCodeSession(hookPayload) {
36806
36818
 
36807
36819
  // src/hook-utils.ts
36808
36820
  var import_promises25 = __toESM(require("fs/promises"), 1);
36809
- var import_node_path13 = __toESM(require("path"), 1);
36821
+ var import_node_path14 = __toESM(require("path"), 1);
36810
36822
  async function readJsonStdin() {
36811
36823
  const chunks = [];
36812
36824
  for await (const chunk of process.stdin) {
@@ -36868,16 +36880,16 @@ function extractBoolean(input, keys) {
36868
36880
  }
36869
36881
  async function findBoundRepo(startPath) {
36870
36882
  if (!startPath) return null;
36871
- let current = import_node_path13.default.resolve(startPath);
36883
+ let current = import_node_path14.default.resolve(startPath);
36872
36884
  let stats = await import_promises25.default.stat(current).catch(() => null);
36873
36885
  if (stats?.isFile()) {
36874
- current = import_node_path13.default.dirname(current);
36886
+ current = import_node_path14.default.dirname(current);
36875
36887
  }
36876
36888
  while (true) {
36877
- const bindingPath = import_node_path13.default.join(current, ".remix", "config.json");
36889
+ const bindingPath = import_node_path14.default.join(current, ".remix", "config.json");
36878
36890
  const bindingStats = await import_promises25.default.stat(bindingPath).catch(() => null);
36879
36891
  if (bindingStats?.isFile()) return current;
36880
- const parent = import_node_path13.default.dirname(current);
36892
+ const parent = import_node_path14.default.dirname(current);
36881
36893
  if (parent === current) return null;
36882
36894
  current = parent;
36883
36895
  }