@remixhq/claude-plugin 0.1.24 → 0.1.26
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/.claude-plugin/plugin.json +1 -1
- package/dist/hook-post-collab.cjs +3 -3
- package/dist/hook-post-collab.cjs.map +1 -1
- package/dist/hook-stop-collab.cjs +169 -142
- package/dist/hook-stop-collab.cjs.map +1 -1
- package/dist/hook-user-prompt.cjs +192 -190
- package/dist/hook-user-prompt.cjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.cjs +57 -20
- package/dist/mcp-server.cjs.map +1 -1
- package/package.json +3 -3
- package/skills/submit-change-step/SKILL.md +1 -1
|
@@ -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(
|
|
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 &&
|
|
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,
|
|
58
|
+
function checkStat(stat, path17, options) {
|
|
59
59
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
60
60
|
return false;
|
|
61
61
|
}
|
|
62
|
-
return checkPathExt(
|
|
62
|
+
return checkPathExt(path17, options);
|
|
63
63
|
}
|
|
64
|
-
function isexe(
|
|
65
|
-
fs13.stat(
|
|
66
|
-
cb(er, er ? false : checkStat(stat,
|
|
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(
|
|
70
|
-
return checkStat(fs13.statSync(
|
|
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(
|
|
83
|
-
fs13.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(
|
|
88
|
-
return checkStat(fs13.statSync(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
151
|
+
function sync(path17, options) {
|
|
152
152
|
try {
|
|
153
|
-
return core.sync(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 ?
|
|
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 =
|
|
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 [
|
|
365
|
-
const binary =
|
|
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
|
|
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 =
|
|
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:
|
|
4945
|
-
const pathString = typeof
|
|
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)(
|
|
4947
|
+
(0, import_node_fs4.appendFileSync)(path17, serializedResult);
|
|
4948
4948
|
} else {
|
|
4949
4949
|
outputFiles.add(pathString);
|
|
4950
|
-
(0, import_node_fs4.writeFileSync)(
|
|
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
|
|
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
|
|
10232
|
+
var import_node_crypto3 = require("crypto");
|
|
10216
10233
|
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
10217
|
-
var
|
|
10218
|
-
var
|
|
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
|
|
10223
|
-
var
|
|
10224
|
-
var
|
|
10225
|
-
function
|
|
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 ||
|
|
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
|
|
10247
|
+
return import_node_path8.default.join(stateRoot2(), `${sessionId}.json`);
|
|
10231
10248
|
}
|
|
10232
10249
|
function stateLockPath(sessionId) {
|
|
10233
|
-
return
|
|
10250
|
+
return import_node_path8.default.join(stateRoot2(), `${sessionId}.lock`);
|
|
10234
10251
|
}
|
|
10235
10252
|
function stateLockMetaPath(sessionId) {
|
|
10236
|
-
return
|
|
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(
|
|
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(
|
|
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,
|
|
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
|
|
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.
|
|
10594
|
+
version: "0.1.26",
|
|
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.
|
|
10616
|
-
"@remixhq/mcp": "^0.1.
|
|
10632
|
+
"@remixhq/core": "^0.1.21",
|
|
10633
|
+
"@remixhq/mcp": "^0.1.21"
|
|
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 ||
|
|
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 ||
|
|
10663
|
+
return configured || import_node_path9.default.join(resolveClaudeRoot(), "plugins", "data", resolvePluginDataDirName());
|
|
10647
10664
|
}
|
|
10648
10665
|
function getHookDiagnosticsLogPath() {
|
|
10649
|
-
return
|
|
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,
|
|
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(
|
|
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
|
|
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)(
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
10894
|
-
var
|
|
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
|
|
10911
|
+
function stateRoot4() {
|
|
10900
10912
|
const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
|
|
10901
|
-
return configured ||
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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,10 +11060,10 @@ 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
|
|
11052
|
-
var
|
|
11063
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
11064
|
+
var import_node_crypto5 = require("crypto");
|
|
11053
11065
|
|
|
11054
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
11066
|
+
// node_modules/@remixhq/core/dist/chunk-YENZA6QR.js
|
|
11055
11067
|
async function readJsonSafe(res) {
|
|
11056
11068
|
const ct = res.headers.get("content-type") ?? "";
|
|
11057
11069
|
if (!ct.toLowerCase().includes("application/json")) return null;
|
|
@@ -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(
|
|
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(
|
|
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(
|
|
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(
|
|
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),
|
|
@@ -11332,6 +11344,21 @@ function createApiClient(config, opts) {
|
|
|
11332
11344
|
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
11333
11345
|
return request(`/v1/merge-requests${suffix}`, { method: "GET" });
|
|
11334
11346
|
},
|
|
11347
|
+
listMergeRequestInbox: (params) => {
|
|
11348
|
+
const qs = new URLSearchParams();
|
|
11349
|
+
if (Array.isArray(params?.status)) {
|
|
11350
|
+
for (const status of params.status) qs.append("status", status);
|
|
11351
|
+
} else if (typeof params?.status === "string") {
|
|
11352
|
+
qs.set("status", params.status);
|
|
11353
|
+
}
|
|
11354
|
+
if (params?.kind) qs.set("kind", params.kind);
|
|
11355
|
+
if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
|
|
11356
|
+
if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
|
|
11357
|
+
if (typeof params?.includeReview === "boolean") qs.set("includeReview", String(params.includeReview));
|
|
11358
|
+
if (typeof params?.includeDiffs === "boolean") qs.set("includeDiffs", String(params.includeDiffs));
|
|
11359
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
11360
|
+
return request(`/v1/merge-requests/inbox${suffix}`, { method: "GET" });
|
|
11361
|
+
},
|
|
11335
11362
|
openMergeRequest: (sourceAppId) => request("/v1/merge-requests", { method: "POST", body: JSON.stringify({ sourceAppId }) }),
|
|
11336
11363
|
getMergeRequestReview: (mrId) => request(`/v1/merge-requests/${encodeURIComponent(mrId)}/review`, { method: "GET" }),
|
|
11337
11364
|
updateMergeRequest: (mrId, payload) => request(`/v1/merge-requests/${encodeURIComponent(mrId)}`, { method: "PATCH", body: JSON.stringify(payload) }),
|
|
@@ -11978,8 +12005,8 @@ function getErrorMap() {
|
|
|
11978
12005
|
|
|
11979
12006
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
11980
12007
|
var makeIssue = (params) => {
|
|
11981
|
-
const { data, path:
|
|
11982
|
-
const fullPath = [...
|
|
12008
|
+
const { data, path: path17, errorMaps, issueData } = params;
|
|
12009
|
+
const fullPath = [...path17, ...issueData.path || []];
|
|
11983
12010
|
const fullIssue = {
|
|
11984
12011
|
...issueData,
|
|
11985
12012
|
path: fullPath
|
|
@@ -12095,11 +12122,11 @@ var errorUtil;
|
|
|
12095
12122
|
|
|
12096
12123
|
// node_modules/zod/v3/types.js
|
|
12097
12124
|
var ParseInputLazyPath = class {
|
|
12098
|
-
constructor(parent, value,
|
|
12125
|
+
constructor(parent, value, path17, key) {
|
|
12099
12126
|
this._cachedPath = [];
|
|
12100
12127
|
this.parent = parent;
|
|
12101
12128
|
this.data = value;
|
|
12102
|
-
this._path =
|
|
12129
|
+
this._path = path17;
|
|
12103
12130
|
this._key = key;
|
|
12104
12131
|
}
|
|
12105
12132
|
get path() {
|
|
@@ -24647,8 +24674,8 @@ var IcebergError = class extends Error {
|
|
|
24647
24674
|
return this.status === 419;
|
|
24648
24675
|
}
|
|
24649
24676
|
};
|
|
24650
|
-
function buildUrl(baseUrl,
|
|
24651
|
-
const url = new URL(
|
|
24677
|
+
function buildUrl(baseUrl, path17, query) {
|
|
24678
|
+
const url = new URL(path17, baseUrl);
|
|
24652
24679
|
if (query) {
|
|
24653
24680
|
for (const [key, value] of Object.entries(query)) {
|
|
24654
24681
|
if (value !== void 0) {
|
|
@@ -24678,12 +24705,12 @@ function createFetchClient(options) {
|
|
|
24678
24705
|
return {
|
|
24679
24706
|
async request({
|
|
24680
24707
|
method,
|
|
24681
|
-
path:
|
|
24708
|
+
path: path17,
|
|
24682
24709
|
query,
|
|
24683
24710
|
body,
|
|
24684
24711
|
headers
|
|
24685
24712
|
}) {
|
|
24686
|
-
const url = buildUrl(options.baseUrl,
|
|
24713
|
+
const url = buildUrl(options.baseUrl, path17, query);
|
|
24687
24714
|
const authHeaders = await buildAuthHeaders(options.auth);
|
|
24688
24715
|
const res = await fetchFn(url, {
|
|
24689
24716
|
method,
|
|
@@ -25521,7 +25548,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25521
25548
|
* @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
25549
|
* @param fileBody The body of the file to be stored in the bucket.
|
|
25523
25550
|
*/
|
|
25524
|
-
async uploadOrUpdate(method,
|
|
25551
|
+
async uploadOrUpdate(method, path17, fileBody, fileOptions) {
|
|
25525
25552
|
var _this = this;
|
|
25526
25553
|
return _this.handleOperation(async () => {
|
|
25527
25554
|
let body;
|
|
@@ -25545,7 +25572,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25545
25572
|
if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
|
|
25546
25573
|
}
|
|
25547
25574
|
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(
|
|
25575
|
+
const cleanPath = _this._removeEmptyFolders(path17);
|
|
25549
25576
|
const _path = _this._getFinalPath(cleanPath);
|
|
25550
25577
|
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
25578
|
return {
|
|
@@ -25606,8 +25633,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25606
25633
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25607
25634
|
* - 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
25635
|
*/
|
|
25609
|
-
async upload(
|
|
25610
|
-
return this.uploadOrUpdate("POST",
|
|
25636
|
+
async upload(path17, fileBody, fileOptions) {
|
|
25637
|
+
return this.uploadOrUpdate("POST", path17, fileBody, fileOptions);
|
|
25611
25638
|
}
|
|
25612
25639
|
/**
|
|
25613
25640
|
* Upload a file with a token generated from `createSignedUploadUrl`.
|
|
@@ -25646,9 +25673,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25646
25673
|
* - `objects` table permissions: none
|
|
25647
25674
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25648
25675
|
*/
|
|
25649
|
-
async uploadToSignedUrl(
|
|
25676
|
+
async uploadToSignedUrl(path17, token, fileBody, fileOptions) {
|
|
25650
25677
|
var _this3 = this;
|
|
25651
|
-
const cleanPath = _this3._removeEmptyFolders(
|
|
25678
|
+
const cleanPath = _this3._removeEmptyFolders(path17);
|
|
25652
25679
|
const _path = _this3._getFinalPath(cleanPath);
|
|
25653
25680
|
const url = new URL(_this3.url + `/object/upload/sign/${_path}`);
|
|
25654
25681
|
url.searchParams.set("token", token);
|
|
@@ -25710,10 +25737,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25710
25737
|
* - `objects` table permissions: `insert`
|
|
25711
25738
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25712
25739
|
*/
|
|
25713
|
-
async createSignedUploadUrl(
|
|
25740
|
+
async createSignedUploadUrl(path17, options) {
|
|
25714
25741
|
var _this4 = this;
|
|
25715
25742
|
return _this4.handleOperation(async () => {
|
|
25716
|
-
let _path = _this4._getFinalPath(
|
|
25743
|
+
let _path = _this4._getFinalPath(path17);
|
|
25717
25744
|
const headers = _objectSpread22({}, _this4.headers);
|
|
25718
25745
|
if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
|
|
25719
25746
|
const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
|
|
@@ -25722,7 +25749,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25722
25749
|
if (!token) throw new StorageError("No token returned by API");
|
|
25723
25750
|
return {
|
|
25724
25751
|
signedUrl: url.toString(),
|
|
25725
|
-
path:
|
|
25752
|
+
path: path17,
|
|
25726
25753
|
token
|
|
25727
25754
|
};
|
|
25728
25755
|
});
|
|
@@ -25778,8 +25805,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25778
25805
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25779
25806
|
* - 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
25807
|
*/
|
|
25781
|
-
async update(
|
|
25782
|
-
return this.uploadOrUpdate("PUT",
|
|
25808
|
+
async update(path17, fileBody, fileOptions) {
|
|
25809
|
+
return this.uploadOrUpdate("PUT", path17, fileBody, fileOptions);
|
|
25783
25810
|
}
|
|
25784
25811
|
/**
|
|
25785
25812
|
* Moves an existing file to a new path in the same bucket.
|
|
@@ -25927,10 +25954,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25927
25954
|
* - `objects` table permissions: `select`
|
|
25928
25955
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25929
25956
|
*/
|
|
25930
|
-
async createSignedUrl(
|
|
25957
|
+
async createSignedUrl(path17, expiresIn, options) {
|
|
25931
25958
|
var _this8 = this;
|
|
25932
25959
|
return _this8.handleOperation(async () => {
|
|
25933
|
-
let _path = _this8._getFinalPath(
|
|
25960
|
+
let _path = _this8._getFinalPath(path17);
|
|
25934
25961
|
const hasTransform = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0;
|
|
25935
25962
|
let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, hasTransform ? { transform: options.transform } : {}), { headers: _this8.headers });
|
|
25936
25963
|
const query = new URLSearchParams();
|
|
@@ -26064,13 +26091,13 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26064
26091
|
* - `objects` table permissions: `select`
|
|
26065
26092
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
26066
26093
|
*/
|
|
26067
|
-
download(
|
|
26094
|
+
download(path17, options, parameters) {
|
|
26068
26095
|
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
26096
|
const query = new URLSearchParams();
|
|
26070
26097
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
26071
26098
|
if ((options === null || options === void 0 ? void 0 : options.cacheNonce) != null) query.set("cacheNonce", String(options.cacheNonce));
|
|
26072
26099
|
const queryString = query.toString();
|
|
26073
|
-
const _path = this._getFinalPath(
|
|
26100
|
+
const _path = this._getFinalPath(path17);
|
|
26074
26101
|
const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ""}`, {
|
|
26075
26102
|
headers: this.headers,
|
|
26076
26103
|
noResolveJson: true
|
|
@@ -26100,9 +26127,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26100
26127
|
* }
|
|
26101
26128
|
* ```
|
|
26102
26129
|
*/
|
|
26103
|
-
async info(
|
|
26130
|
+
async info(path17) {
|
|
26104
26131
|
var _this10 = this;
|
|
26105
|
-
const _path = _this10._getFinalPath(
|
|
26132
|
+
const _path = _this10._getFinalPath(path17);
|
|
26106
26133
|
return _this10.handleOperation(async () => {
|
|
26107
26134
|
return recursiveToCamel(await get(_this10.fetch, `${_this10.url}/object/info/${_path}`, { headers: _this10.headers }));
|
|
26108
26135
|
});
|
|
@@ -26122,9 +26149,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26122
26149
|
* .exists('folder/avatar1.png')
|
|
26123
26150
|
* ```
|
|
26124
26151
|
*/
|
|
26125
|
-
async exists(
|
|
26152
|
+
async exists(path17) {
|
|
26126
26153
|
var _this11 = this;
|
|
26127
|
-
const _path = _this11._getFinalPath(
|
|
26154
|
+
const _path = _this11._getFinalPath(path17);
|
|
26128
26155
|
try {
|
|
26129
26156
|
await head(_this11.fetch, `${_this11.url}/object/${_path}`, { headers: _this11.headers });
|
|
26130
26157
|
return {
|
|
@@ -26202,8 +26229,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26202
26229
|
* - `objects` table permissions: none
|
|
26203
26230
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
26204
26231
|
*/
|
|
26205
|
-
getPublicUrl(
|
|
26206
|
-
const _path = this._getFinalPath(
|
|
26232
|
+
getPublicUrl(path17, options) {
|
|
26233
|
+
const _path = this._getFinalPath(path17);
|
|
26207
26234
|
const query = new URLSearchParams();
|
|
26208
26235
|
if (options === null || options === void 0 ? void 0 : options.download) query.set("download", options.download === true ? "" : options.download);
|
|
26209
26236
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
@@ -26340,10 +26367,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26340
26367
|
* - `objects` table permissions: `select`
|
|
26341
26368
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
26342
26369
|
*/
|
|
26343
|
-
async list(
|
|
26370
|
+
async list(path17, options, parameters) {
|
|
26344
26371
|
var _this13 = this;
|
|
26345
26372
|
return _this13.handleOperation(async () => {
|
|
26346
|
-
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix:
|
|
26373
|
+
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path17 || "" });
|
|
26347
26374
|
return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
|
|
26348
26375
|
});
|
|
26349
26376
|
}
|
|
@@ -26407,11 +26434,11 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26407
26434
|
if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
|
|
26408
26435
|
return btoa(data);
|
|
26409
26436
|
}
|
|
26410
|
-
_getFinalPath(
|
|
26411
|
-
return `${this.bucketId}/${
|
|
26437
|
+
_getFinalPath(path17) {
|
|
26438
|
+
return `${this.bucketId}/${path17.replace(/^\/+/, "")}`;
|
|
26412
26439
|
}
|
|
26413
|
-
_removeEmptyFolders(
|
|
26414
|
-
return
|
|
26440
|
+
_removeEmptyFolders(path17) {
|
|
26441
|
+
return path17.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
|
|
26415
26442
|
}
|
|
26416
26443
|
/** Modifies the `query`, appending values the from `transform` */
|
|
26417
26444
|
applyTransformOptsToQuery(query, transform) {
|
|
@@ -35789,11 +35816,11 @@ function isPidAlive(pid) {
|
|
|
35789
35816
|
}
|
|
35790
35817
|
}
|
|
35791
35818
|
function repoLockFileName(repoRoot) {
|
|
35792
|
-
const hash = (0,
|
|
35819
|
+
const hash = (0, import_node_crypto5.createHash)("sha256").update(repoRoot).digest("hex").slice(0, 16);
|
|
35793
35820
|
return `.drainer-${hash}.lock`;
|
|
35794
35821
|
}
|
|
35795
35822
|
function repoLockPath(repoRoot) {
|
|
35796
|
-
return
|
|
35823
|
+
return import_node_path12.default.join(getDeferredTurnDirPath(), repoLockFileName(repoRoot));
|
|
35797
35824
|
}
|
|
35798
35825
|
async function readDrainLockMetadata(lockPath) {
|
|
35799
35826
|
const raw = await import_promises23.default.readFile(lockPath, "utf8").catch(() => null);
|
|
@@ -35815,7 +35842,7 @@ async function writeDrainLockMetadata(lockPath, metadata) {
|
|
|
35815
35842
|
}
|
|
35816
35843
|
async function tryAcquireDrainLock(repoRoot) {
|
|
35817
35844
|
const lockPath = repoLockPath(repoRoot);
|
|
35818
|
-
await import_promises23.default.mkdir(
|
|
35845
|
+
await import_promises23.default.mkdir(import_node_path12.default.dirname(lockPath), { recursive: true });
|
|
35819
35846
|
const existingMeta = await readDrainLockMetadata(lockPath);
|
|
35820
35847
|
if (existingMeta) {
|
|
35821
35848
|
const lockStat = await import_promises23.default.stat(lockPath).catch(() => null);
|
|
@@ -36674,8 +36701,8 @@ function harvestClaudeCodeUsage(input) {
|
|
|
36674
36701
|
// src/usage/claudeCodeSession.ts
|
|
36675
36702
|
var import_node_child_process8 = require("child_process");
|
|
36676
36703
|
var import_node_fs7 = require("fs");
|
|
36677
|
-
var
|
|
36678
|
-
var
|
|
36704
|
+
var import_node_os9 = require("os");
|
|
36705
|
+
var import_node_path13 = require("path");
|
|
36679
36706
|
var CACHE_SCHEMA_VERSION = 1;
|
|
36680
36707
|
var SUCCESS_TTL_MS = 60 * 60 * 1e3;
|
|
36681
36708
|
var FAILURE_TTL_MS = 5 * 60 * 1e3;
|
|
@@ -36704,10 +36731,10 @@ function defaultSpawnClaudeAuthStatus(timeoutMs) {
|
|
|
36704
36731
|
}
|
|
36705
36732
|
function getCollabStateRoot2() {
|
|
36706
36733
|
const configured = process.env.REMIX_COLLAB_STATE_ROOT?.trim();
|
|
36707
|
-
return configured || (0,
|
|
36734
|
+
return configured || (0, import_node_path13.join)((0, import_node_os9.homedir)(), ".remix", "collab-state");
|
|
36708
36735
|
}
|
|
36709
36736
|
function getAuthCachePath() {
|
|
36710
|
-
return (0,
|
|
36737
|
+
return (0, import_node_path13.join)(getCollabStateRoot2(), "claude-auth-cache.json");
|
|
36711
36738
|
}
|
|
36712
36739
|
function getSpawnTimeoutMs() {
|
|
36713
36740
|
const raw = process.env.REMIX_CLAUDE_AUTH_TIMEOUT_MS?.trim();
|
|
@@ -36748,7 +36775,7 @@ function isCacheFresh(record) {
|
|
|
36748
36775
|
function writeAuthCache(record) {
|
|
36749
36776
|
const cachePath = getAuthCachePath();
|
|
36750
36777
|
try {
|
|
36751
|
-
(0, import_node_fs7.mkdirSync)((0,
|
|
36778
|
+
(0, import_node_fs7.mkdirSync)((0, import_node_path13.dirname)(cachePath), { recursive: true });
|
|
36752
36779
|
const tmpPath = `${cachePath}.${process.pid}.${Date.now()}.tmp`;
|
|
36753
36780
|
(0, import_node_fs7.writeFileSync)(tmpPath, JSON.stringify(record), "utf8");
|
|
36754
36781
|
(0, import_node_fs7.renameSync)(tmpPath, cachePath);
|
|
@@ -36806,7 +36833,7 @@ function resolveClaudeCodeSession(hookPayload) {
|
|
|
36806
36833
|
|
|
36807
36834
|
// src/hook-utils.ts
|
|
36808
36835
|
var import_promises25 = __toESM(require("fs/promises"), 1);
|
|
36809
|
-
var
|
|
36836
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
36810
36837
|
async function readJsonStdin() {
|
|
36811
36838
|
const chunks = [];
|
|
36812
36839
|
for await (const chunk of process.stdin) {
|
|
@@ -36868,16 +36895,16 @@ function extractBoolean(input, keys) {
|
|
|
36868
36895
|
}
|
|
36869
36896
|
async function findBoundRepo(startPath) {
|
|
36870
36897
|
if (!startPath) return null;
|
|
36871
|
-
let current =
|
|
36898
|
+
let current = import_node_path14.default.resolve(startPath);
|
|
36872
36899
|
let stats = await import_promises25.default.stat(current).catch(() => null);
|
|
36873
36900
|
if (stats?.isFile()) {
|
|
36874
|
-
current =
|
|
36901
|
+
current = import_node_path14.default.dirname(current);
|
|
36875
36902
|
}
|
|
36876
36903
|
while (true) {
|
|
36877
|
-
const bindingPath =
|
|
36904
|
+
const bindingPath = import_node_path14.default.join(current, ".remix", "config.json");
|
|
36878
36905
|
const bindingStats = await import_promises25.default.stat(bindingPath).catch(() => null);
|
|
36879
36906
|
if (bindingStats?.isFile()) return current;
|
|
36880
|
-
const parent =
|
|
36907
|
+
const parent = import_node_path14.default.dirname(current);
|
|
36881
36908
|
if (parent === current) return null;
|
|
36882
36909
|
current = parent;
|
|
36883
36910
|
}
|