@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.
- 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 +153 -141
- package/dist/hook-stop-collab.cjs.map +1 -1
- package/dist/hook-user-prompt.cjs +176 -189
- 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 +41 -19
- 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 fs11 = require("fs");
|
|
41
|
-
function checkPathExt(
|
|
41
|
+
function checkPathExt(path18, 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 && path18.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, path18, options) {
|
|
59
59
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
60
60
|
return false;
|
|
61
61
|
}
|
|
62
|
-
return checkPathExt(
|
|
62
|
+
return checkPathExt(path18, options);
|
|
63
63
|
}
|
|
64
|
-
function isexe(
|
|
65
|
-
fs11.stat(
|
|
66
|
-
cb(er, er ? false : checkStat(stat,
|
|
64
|
+
function isexe(path18, options, cb) {
|
|
65
|
+
fs11.stat(path18, function(er, stat) {
|
|
66
|
+
cb(er, er ? false : checkStat(stat, path18, options));
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
-
function sync(
|
|
70
|
-
return checkStat(fs11.statSync(
|
|
69
|
+
function sync(path18, options) {
|
|
70
|
+
return checkStat(fs11.statSync(path18), path18, 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 fs11 = require("fs");
|
|
82
|
-
function isexe(
|
|
83
|
-
fs11.stat(
|
|
82
|
+
function isexe(path18, options, cb) {
|
|
83
|
+
fs11.stat(path18, function(er, stat) {
|
|
84
84
|
cb(er, er ? false : checkStat(stat, options));
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
|
-
function sync(
|
|
88
|
-
return checkStat(fs11.statSync(
|
|
87
|
+
function sync(path18, options) {
|
|
88
|
+
return checkStat(fs11.statSync(path18), 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(path18, 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(path18, 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(path18, 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(path18, options) {
|
|
152
152
|
try {
|
|
153
|
-
return core.sync(
|
|
153
|
+
return core.sync(path18, 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 path18 = 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 = path18.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 = path18.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 path18 = 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 ? path18.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 = path18.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 [path18, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
365
|
+
const binary = path18.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 path18 = 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 = path18.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(" ");
|
|
@@ -540,7 +540,7 @@ __export(hook_user_prompt_exports, {
|
|
|
540
540
|
module.exports = __toCommonJS(hook_user_prompt_exports);
|
|
541
541
|
var import_node_child_process8 = require("child_process");
|
|
542
542
|
var import_node_fs7 = require("fs");
|
|
543
|
-
var
|
|
543
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
544
544
|
|
|
545
545
|
// node_modules/@remixhq/core/dist/chunk-7XJGOKEO.js
|
|
546
546
|
var RemixError = class extends Error {
|
|
@@ -4943,13 +4943,13 @@ var logOutputSync = ({ serializedResult, fdNumber, state, verboseInfo, encoding,
|
|
|
4943
4943
|
}
|
|
4944
4944
|
};
|
|
4945
4945
|
var writeToFiles = (serializedResult, stdioItems, outputFiles) => {
|
|
4946
|
-
for (const { path:
|
|
4947
|
-
const pathString = typeof
|
|
4946
|
+
for (const { path: path18, append } of stdioItems.filter(({ type }) => FILE_TYPES.has(type))) {
|
|
4947
|
+
const pathString = typeof path18 === "string" ? path18 : path18.toString();
|
|
4948
4948
|
if (append || outputFiles.has(pathString)) {
|
|
4949
|
-
(0, import_node_fs4.appendFileSync)(
|
|
4949
|
+
(0, import_node_fs4.appendFileSync)(path18, serializedResult);
|
|
4950
4950
|
} else {
|
|
4951
4951
|
outputFiles.add(pathString);
|
|
4952
|
-
(0, import_node_fs4.writeFileSync)(
|
|
4952
|
+
(0, import_node_fs4.writeFileSync)(path18, serializedResult);
|
|
4953
4953
|
}
|
|
4954
4954
|
}
|
|
4955
4955
|
};
|
|
@@ -7668,6 +7668,21 @@ async function writeCollabBinding(repoRoot, binding) {
|
|
|
7668
7668
|
return filePath;
|
|
7669
7669
|
}
|
|
7670
7670
|
|
|
7671
|
+
// src/collab-init-spawn-lock.ts
|
|
7672
|
+
var import_node_crypto = require("crypto");
|
|
7673
|
+
var import_node_os4 = __toESM(require("os"), 1);
|
|
7674
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
7675
|
+
function stateRoot() {
|
|
7676
|
+
const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
|
|
7677
|
+
return configured || import_node_path6.default.join(import_node_os4.default.tmpdir(), "remix-claude-plugin-hooks");
|
|
7678
|
+
}
|
|
7679
|
+
function sha256Hex(value) {
|
|
7680
|
+
return (0, import_node_crypto.createHash)("sha256").update(value).digest("hex");
|
|
7681
|
+
}
|
|
7682
|
+
function collabInitSpawnLockPath(repoRoot) {
|
|
7683
|
+
return import_node_path6.default.join(stateRoot(), "collab-init-spawn-locks", `${sha256Hex(repoRoot)}.json`);
|
|
7684
|
+
}
|
|
7685
|
+
|
|
7671
7686
|
// src/history-routing.ts
|
|
7672
7687
|
var STRONG_MEMORY_FIRST_PATTERNS = [
|
|
7673
7688
|
/\bwhy\b/i,
|
|
@@ -7773,25 +7788,25 @@ function buildPromptRoutingAdvisory(intent) {
|
|
|
7773
7788
|
|
|
7774
7789
|
// src/deferred-turn-queue.ts
|
|
7775
7790
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
7776
|
-
var
|
|
7777
|
-
var
|
|
7791
|
+
var import_node_os5 = __toESM(require("os"), 1);
|
|
7792
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
7778
7793
|
var DEFERRED_TURN_SCHEMA_VERSION = 1;
|
|
7779
7794
|
var DEFERRED_TURN_MAX_ATTEMPTS = 10;
|
|
7780
7795
|
var DEFERRED_TURN_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
7781
7796
|
var DEFERRED_TURN_DIR = "deferred-turns";
|
|
7782
|
-
function
|
|
7797
|
+
function stateRoot2() {
|
|
7783
7798
|
const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
|
|
7784
|
-
return configured ||
|
|
7799
|
+
return configured || import_node_path7.default.join(import_node_os5.default.tmpdir(), "remix-claude-plugin-hooks");
|
|
7785
7800
|
}
|
|
7786
7801
|
function getDeferredTurnDirPath() {
|
|
7787
|
-
return
|
|
7802
|
+
return import_node_path7.default.join(stateRoot2(), DEFERRED_TURN_DIR);
|
|
7788
7803
|
}
|
|
7789
7804
|
function deferredTurnFileName(sessionId, turnId) {
|
|
7790
7805
|
const safe = (s) => s.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
7791
7806
|
return `${safe(sessionId)}-${safe(turnId)}.json`;
|
|
7792
7807
|
}
|
|
7793
7808
|
function getDeferredTurnFilePath(sessionId, turnId) {
|
|
7794
|
-
return
|
|
7809
|
+
return import_node_path7.default.join(getDeferredTurnDirPath(), deferredTurnFileName(sessionId, turnId));
|
|
7795
7810
|
}
|
|
7796
7811
|
async function writeDeferredTurn(record) {
|
|
7797
7812
|
if (record.schemaVersion !== DEFERRED_TURN_SCHEMA_VERSION) {
|
|
@@ -7852,7 +7867,7 @@ async function listDeferredTurnsForRepo(repoRoot) {
|
|
|
7852
7867
|
const entries = [];
|
|
7853
7868
|
for (const entry of dirEntries) {
|
|
7854
7869
|
if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
|
|
7855
|
-
const filePath =
|
|
7870
|
+
const filePath = import_node_path7.default.join(dir, entry.name);
|
|
7856
7871
|
const record = await readDeferredTurnFile(filePath);
|
|
7857
7872
|
if (!record) continue;
|
|
7858
7873
|
if (record.repoRoot !== repoRoot) continue;
|
|
@@ -7876,7 +7891,7 @@ async function pruneStaleDeferredTurns(maxAgeMs = DEFERRED_TURN_TTL_MS) {
|
|
|
7876
7891
|
const now = Date.now();
|
|
7877
7892
|
for (const entry of dirEntries) {
|
|
7878
7893
|
if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
|
|
7879
|
-
const filePath =
|
|
7894
|
+
const filePath = import_node_path7.default.join(dir, entry.name);
|
|
7880
7895
|
const record = await readDeferredTurnFile(filePath);
|
|
7881
7896
|
if (!record) {
|
|
7882
7897
|
const stat = await import_promises14.default.stat(filePath).catch(() => null);
|
|
@@ -7912,8 +7927,8 @@ async function recordDeferredTurnFailedAttempt(filePath) {
|
|
|
7912
7927
|
|
|
7913
7928
|
// src/deferred-turn-drainer.ts
|
|
7914
7929
|
var import_promises23 = __toESM(require("fs/promises"), 1);
|
|
7915
|
-
var
|
|
7916
|
-
var
|
|
7930
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
7931
|
+
var import_node_crypto5 = require("crypto");
|
|
7917
7932
|
|
|
7918
7933
|
// node_modules/@remixhq/core/dist/collab.js
|
|
7919
7934
|
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
@@ -8015,7 +8030,7 @@ function buildBranchMismatchHint(params) {
|
|
|
8015
8030
|
`Switch to ${describeBranch(params.branchName)} or rerun with ${overrideFlag} if this is intentional.`
|
|
8016
8031
|
].join("\n");
|
|
8017
8032
|
}
|
|
8018
|
-
function
|
|
8033
|
+
function sha256Hex2(value) {
|
|
8019
8034
|
return (0, import_crypto.createHash)("sha256").update(value).digest("hex");
|
|
8020
8035
|
}
|
|
8021
8036
|
function getCollabStateRoot() {
|
|
@@ -8029,7 +8044,7 @@ function buildLaneStateKey(params) {
|
|
|
8029
8044
|
const stableSource = repoRoot || "unknown-repo-root";
|
|
8030
8045
|
const fingerprintSource = fingerprint || "unknown-repo-fingerprint";
|
|
8031
8046
|
const laneSource = laneId || "unknown-lane";
|
|
8032
|
-
return
|
|
8047
|
+
return sha256Hex2(`${stableSource}::${fingerprintSource}::${laneSource}`);
|
|
8033
8048
|
}
|
|
8034
8049
|
function getSnapshotsRoot() {
|
|
8035
8050
|
return import_path3.default.join(getCollabStateRoot(), "snapshots");
|
|
@@ -8230,7 +8245,7 @@ async function writeLocalBaseline(baseline) {
|
|
|
8230
8245
|
await writeJsonAtomic(getBaselinePath(baseline), normalized);
|
|
8231
8246
|
return normalized;
|
|
8232
8247
|
}
|
|
8233
|
-
function
|
|
8248
|
+
function sha256Hex22(value) {
|
|
8234
8249
|
return (0, import_crypto2.createHash)("sha256").update(value).digest("hex");
|
|
8235
8250
|
}
|
|
8236
8251
|
function getSnapshotRecordPath(snapshotId) {
|
|
@@ -8281,7 +8296,7 @@ async function persistBlob(blobHash, content) {
|
|
|
8281
8296
|
}
|
|
8282
8297
|
function buildSnapshotHash(files) {
|
|
8283
8298
|
const manifest = files.map((file) => `${file.path} ${file.mode} ${file.blobHash} ${file.size}`).join("\n");
|
|
8284
|
-
return
|
|
8299
|
+
return sha256Hex22(manifest);
|
|
8285
8300
|
}
|
|
8286
8301
|
async function inspectLocalSnapshot(params) {
|
|
8287
8302
|
const repoRoot = params.repoRoot;
|
|
@@ -8292,7 +8307,7 @@ async function inspectLocalSnapshot(params) {
|
|
|
8292
8307
|
const stat = await import_promises17.default.lstat(absolutePath);
|
|
8293
8308
|
if (stat.isSymbolicLink()) {
|
|
8294
8309
|
const linkTarget = await import_promises17.default.readlink(absolutePath);
|
|
8295
|
-
const blobHash2 =
|
|
8310
|
+
const blobHash2 = sha256Hex22(`symlink:${linkTarget}`);
|
|
8296
8311
|
if (params.persistBlobs !== false) {
|
|
8297
8312
|
await persistBlob(blobHash2, linkTarget);
|
|
8298
8313
|
}
|
|
@@ -8305,7 +8320,7 @@ async function inspectLocalSnapshot(params) {
|
|
|
8305
8320
|
continue;
|
|
8306
8321
|
}
|
|
8307
8322
|
const content = await import_promises17.default.readFile(absolutePath);
|
|
8308
|
-
const blobHash =
|
|
8323
|
+
const blobHash = sha256Hex22(content);
|
|
8309
8324
|
if (params.persistBlobs !== false) {
|
|
8310
8325
|
await persistBlob(blobHash, content);
|
|
8311
8326
|
}
|
|
@@ -8409,7 +8424,7 @@ async function diffLocalSnapshots(params) {
|
|
|
8409
8424
|
baseSnapshotId: params.baseSnapshotId,
|
|
8410
8425
|
targetSnapshotId: params.targetSnapshotId,
|
|
8411
8426
|
diff,
|
|
8412
|
-
diffSha256: diff ?
|
|
8427
|
+
diffSha256: diff ? sha256Hex22(diff) : null,
|
|
8413
8428
|
changedPaths,
|
|
8414
8429
|
stats: summarizeUnifiedDiff(diff)
|
|
8415
8430
|
};
|
|
@@ -10420,15 +10435,17 @@ function isFinalizePreflightFailureCode(value) {
|
|
|
10420
10435
|
|
|
10421
10436
|
// src/auto-fix-dispatcher.ts
|
|
10422
10437
|
var import_node_child_process6 = require("child_process");
|
|
10438
|
+
var import_node_crypto4 = require("crypto");
|
|
10423
10439
|
var import_node_fs6 = require("fs");
|
|
10424
|
-
var
|
|
10440
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
10441
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
10425
10442
|
|
|
10426
10443
|
// src/finalize-failure-marker.ts
|
|
10427
10444
|
var import_promises19 = __toESM(require("fs/promises"), 1);
|
|
10428
|
-
var
|
|
10429
|
-
var FINALIZE_FAILURE_MARKER_REL =
|
|
10445
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
10446
|
+
var FINALIZE_FAILURE_MARKER_REL = import_node_path8.default.join(".remix", ".last-finalize-failure.json");
|
|
10430
10447
|
function markerPath(repoRoot) {
|
|
10431
|
-
return
|
|
10448
|
+
return import_node_path8.default.join(repoRoot, FINALIZE_FAILURE_MARKER_REL);
|
|
10432
10449
|
}
|
|
10433
10450
|
async function readFinalizeFailureMarker(repoRoot) {
|
|
10434
10451
|
const raw = await import_promises19.default.readFile(markerPath(repoRoot), "utf8").catch(() => null);
|
|
@@ -10445,7 +10462,7 @@ async function readFinalizeFailureMarker(repoRoot) {
|
|
|
10445
10462
|
}
|
|
10446
10463
|
async function writeFinalizeFailureMarker(marker) {
|
|
10447
10464
|
const filePath = markerPath(marker.repoRoot);
|
|
10448
|
-
await import_promises19.default.mkdir(
|
|
10465
|
+
await import_promises19.default.mkdir(import_node_path8.default.dirname(filePath), { recursive: true });
|
|
10449
10466
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
10450
10467
|
await import_promises19.default.writeFile(tmpPath, JSON.stringify(marker, null, 2), "utf8");
|
|
10451
10468
|
await import_promises19.default.rename(tmpPath, filePath);
|
|
@@ -10471,31 +10488,31 @@ function buildFreshFailureMarker(params) {
|
|
|
10471
10488
|
}
|
|
10472
10489
|
|
|
10473
10490
|
// src/hook-diagnostics.ts
|
|
10474
|
-
var
|
|
10491
|
+
var import_node_crypto3 = require("crypto");
|
|
10475
10492
|
var import_promises21 = __toESM(require("fs/promises"), 1);
|
|
10476
|
-
var
|
|
10477
|
-
var
|
|
10493
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
10494
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
10478
10495
|
|
|
10479
10496
|
// src/hook-state.ts
|
|
10480
10497
|
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
10481
|
-
var
|
|
10482
|
-
var
|
|
10483
|
-
var
|
|
10484
|
-
function
|
|
10498
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
10499
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
10500
|
+
var import_node_crypto2 = require("crypto");
|
|
10501
|
+
function stateRoot3() {
|
|
10485
10502
|
const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
|
|
10486
|
-
return configured ||
|
|
10503
|
+
return configured || import_node_path9.default.join(import_node_os6.default.tmpdir(), "remix-claude-plugin-hooks");
|
|
10487
10504
|
}
|
|
10488
10505
|
function statePath(sessionId) {
|
|
10489
|
-
return
|
|
10506
|
+
return import_node_path9.default.join(stateRoot3(), `${sessionId}.json`);
|
|
10490
10507
|
}
|
|
10491
10508
|
function stateLockPath(sessionId) {
|
|
10492
|
-
return
|
|
10509
|
+
return import_node_path9.default.join(stateRoot3(), `${sessionId}.lock`);
|
|
10493
10510
|
}
|
|
10494
10511
|
function stateLockMetaPath(sessionId) {
|
|
10495
|
-
return
|
|
10512
|
+
return import_node_path9.default.join(stateLockPath(sessionId), "owner.json");
|
|
10496
10513
|
}
|
|
10497
10514
|
async function writeJsonAtomic2(filePath, value) {
|
|
10498
|
-
await import_promises20.default.mkdir(
|
|
10515
|
+
await import_promises20.default.mkdir(import_node_path9.default.dirname(filePath), { recursive: true });
|
|
10499
10516
|
const tmpPath = `${filePath}.tmp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
10500
10517
|
await import_promises20.default.writeFile(tmpPath, JSON.stringify(value, null, 2) + "\n", "utf8");
|
|
10501
10518
|
await import_promises20.default.rename(tmpPath, filePath);
|
|
@@ -10548,11 +10565,11 @@ async function tryRemoveStaleStateLock(sessionId) {
|
|
|
10548
10565
|
async function acquireStateLock(sessionId) {
|
|
10549
10566
|
const lockPath = stateLockPath(sessionId);
|
|
10550
10567
|
const deadline = Date.now() + STATE_LOCK_WAIT_MS;
|
|
10551
|
-
await import_promises20.default.mkdir(
|
|
10568
|
+
await import_promises20.default.mkdir(stateRoot3(), { recursive: true });
|
|
10552
10569
|
while (true) {
|
|
10553
10570
|
try {
|
|
10554
10571
|
await import_promises20.default.mkdir(lockPath);
|
|
10555
|
-
const ownerId = (0,
|
|
10572
|
+
const ownerId = (0, import_node_crypto2.randomUUID)();
|
|
10556
10573
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10557
10574
|
const metadata = {
|
|
10558
10575
|
ownerId,
|
|
@@ -10609,7 +10626,7 @@ async function createPendingTurnState(params) {
|
|
|
10609
10626
|
return withStateLock(params.sessionId, async () => {
|
|
10610
10627
|
const state = {
|
|
10611
10628
|
sessionId: params.sessionId,
|
|
10612
|
-
turnId: (0,
|
|
10629
|
+
turnId: (0, import_node_crypto2.randomUUID)(),
|
|
10613
10630
|
prompt: params.prompt,
|
|
10614
10631
|
initialCwd: params.initialCwd?.trim() || null,
|
|
10615
10632
|
intent: params.intent,
|
|
@@ -10628,7 +10645,7 @@ async function createPendingTurnState(params) {
|
|
|
10628
10645
|
// package.json
|
|
10629
10646
|
var package_default = {
|
|
10630
10647
|
name: "@remixhq/claude-plugin",
|
|
10631
|
-
version: "0.1.
|
|
10648
|
+
version: "0.1.25",
|
|
10632
10649
|
description: "Claude Code plugin for Remix collaboration workflows",
|
|
10633
10650
|
homepage: "https://github.com/RemixDotOne/remix-claude-plugin",
|
|
10634
10651
|
license: "MIT",
|
|
@@ -10666,8 +10683,8 @@ var package_default = {
|
|
|
10666
10683
|
prepack: "npm run build"
|
|
10667
10684
|
},
|
|
10668
10685
|
dependencies: {
|
|
10669
|
-
"@remixhq/core": "^0.1.
|
|
10670
|
-
"@remixhq/mcp": "^0.1.
|
|
10686
|
+
"@remixhq/core": "^0.1.20",
|
|
10687
|
+
"@remixhq/mcp": "^0.1.20"
|
|
10671
10688
|
},
|
|
10672
10689
|
devDependencies: {
|
|
10673
10690
|
"@types/node": "^25.4.0",
|
|
@@ -10690,17 +10707,17 @@ var pluginMetadata = {
|
|
|
10690
10707
|
var MAX_LOG_BYTES = 512 * 1024;
|
|
10691
10708
|
function resolveClaudeRoot() {
|
|
10692
10709
|
const configured = process.env.CLAUDE_CONFIG_DIR?.trim();
|
|
10693
|
-
return configured ||
|
|
10710
|
+
return configured || import_node_path10.default.join(import_node_os7.default.homedir(), ".claude");
|
|
10694
10711
|
}
|
|
10695
10712
|
function resolvePluginDataDirName() {
|
|
10696
10713
|
return `${pluginMetadata.pluginId}-${pluginMetadata.pluginId}`;
|
|
10697
10714
|
}
|
|
10698
10715
|
function getHookDiagnosticsDirPath() {
|
|
10699
10716
|
const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_DIAGNOSTICS_DIR?.trim();
|
|
10700
|
-
return configured ||
|
|
10717
|
+
return configured || import_node_path10.default.join(resolveClaudeRoot(), "plugins", "data", resolvePluginDataDirName());
|
|
10701
10718
|
}
|
|
10702
10719
|
function getHookDiagnosticsLogPath() {
|
|
10703
|
-
return
|
|
10720
|
+
return import_node_path10.default.join(getHookDiagnosticsDirPath(), "hooks.ndjson");
|
|
10704
10721
|
}
|
|
10705
10722
|
function toFieldValue(value) {
|
|
10706
10723
|
if (value === null) return null;
|
|
@@ -10738,13 +10755,13 @@ function summarizeText(value) {
|
|
|
10738
10755
|
return {
|
|
10739
10756
|
present: true,
|
|
10740
10757
|
length: trimmed.length,
|
|
10741
|
-
sha256Prefix: (0,
|
|
10758
|
+
sha256Prefix: (0, import_node_crypto3.createHash)("sha256").update(trimmed).digest("hex").slice(0, 12)
|
|
10742
10759
|
};
|
|
10743
10760
|
}
|
|
10744
10761
|
async function appendHookDiagnosticsEvent(params) {
|
|
10745
10762
|
try {
|
|
10746
10763
|
const logPath = getHookDiagnosticsLogPath();
|
|
10747
|
-
await import_promises21.default.mkdir(
|
|
10764
|
+
await import_promises21.default.mkdir(import_node_path10.default.dirname(logPath), { recursive: true });
|
|
10748
10765
|
await rotateLogIfNeeded(logPath);
|
|
10749
10766
|
const event = {
|
|
10750
10767
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -10791,18 +10808,27 @@ var RECOMMENDED_USER_COMMAND = {
|
|
|
10791
10808
|
pull_required: "remix collab sync",
|
|
10792
10809
|
baseline_missing: "remix collab init"
|
|
10793
10810
|
};
|
|
10794
|
-
var SPAWN_LOCK_REL = (cmdSlug) => import_node_path10.default.join(".remix", `.${cmdSlug}-spawning`);
|
|
10795
|
-
var SPAWN_LOG_REL = (cmdSlug) => import_node_path10.default.join(".remix", `${cmdSlug}.log`);
|
|
10796
10811
|
var SPAWN_THROTTLE_MS = 5 * 60 * 1e3;
|
|
10797
10812
|
function commandSlug(args) {
|
|
10798
10813
|
return args.join("-").replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
10799
10814
|
}
|
|
10815
|
+
function stateRoot4() {
|
|
10816
|
+
const configured = process.env.REMIX_CLAUDE_PLUGIN_HOOK_STATE_ROOT?.trim();
|
|
10817
|
+
return configured || import_node_path11.default.join(import_node_os8.default.tmpdir(), "remix-claude-plugin-hooks");
|
|
10818
|
+
}
|
|
10819
|
+
function sha256Hex3(value) {
|
|
10820
|
+
return (0, import_node_crypto4.createHash)("sha256").update(value).digest("hex");
|
|
10821
|
+
}
|
|
10822
|
+
function spawnLockPath(repoRoot, cmdSlug) {
|
|
10823
|
+
if (cmdSlug === "collab-init") {
|
|
10824
|
+
return collabInitSpawnLockPath(repoRoot);
|
|
10825
|
+
}
|
|
10826
|
+
return import_node_path11.default.join(stateRoot4(), "auto-fix-spawn-locks", sha256Hex3(repoRoot), `${cmdSlug}.lock`);
|
|
10827
|
+
}
|
|
10800
10828
|
function spawnFixDetached(repoRoot, args) {
|
|
10801
10829
|
const slug = commandSlug(args);
|
|
10802
10830
|
const command = `remix ${args.join(" ")}`;
|
|
10803
|
-
const
|
|
10804
|
-
const lockPath = import_node_path10.default.join(repoRoot, SPAWN_LOCK_REL(slug));
|
|
10805
|
-
const logPath = import_node_path10.default.join(repoRoot, SPAWN_LOG_REL(slug));
|
|
10831
|
+
const lockPath = spawnLockPath(repoRoot, slug);
|
|
10806
10832
|
try {
|
|
10807
10833
|
if ((0, import_node_fs6.existsSync)(lockPath)) {
|
|
10808
10834
|
const ageMs = Date.now() - (0, import_node_fs6.statSync)(lockPath).mtimeMs;
|
|
@@ -10813,27 +10839,14 @@ function spawnFixDetached(repoRoot, args) {
|
|
|
10813
10839
|
} catch {
|
|
10814
10840
|
}
|
|
10815
10841
|
try {
|
|
10816
|
-
(0, import_node_fs6.mkdirSync)(
|
|
10842
|
+
(0, import_node_fs6.mkdirSync)(import_node_path11.default.dirname(lockPath), { recursive: true });
|
|
10817
10843
|
} catch {
|
|
10818
10844
|
}
|
|
10819
|
-
let out;
|
|
10820
|
-
let err;
|
|
10821
|
-
try {
|
|
10822
|
-
out = (0, import_node_fs6.openSync)(logPath, "a");
|
|
10823
|
-
err = (0, import_node_fs6.openSync)(logPath, "a");
|
|
10824
|
-
} catch (logErr) {
|
|
10825
|
-
return {
|
|
10826
|
-
kind: "spawn_failed",
|
|
10827
|
-
command,
|
|
10828
|
-
reason: "log_open_failed",
|
|
10829
|
-
message: logErr instanceof Error ? logErr.message : String(logErr)
|
|
10830
|
-
};
|
|
10831
|
-
}
|
|
10832
10845
|
try {
|
|
10833
10846
|
const child = (0, import_node_child_process6.spawn)("remix", [...args], {
|
|
10834
10847
|
cwd: repoRoot,
|
|
10835
10848
|
detached: true,
|
|
10836
|
-
stdio:
|
|
10849
|
+
stdio: "ignore",
|
|
10837
10850
|
env: { ...process.env, REMIX_AUTO_FIX_SPAWN: "1" }
|
|
10838
10851
|
});
|
|
10839
10852
|
child.unref();
|
|
@@ -10842,7 +10855,7 @@ function spawnFixDetached(repoRoot, args) {
|
|
|
10842
10855
|
(0, import_node_fs6.utimesSync)(lockPath, /* @__PURE__ */ new Date(), /* @__PURE__ */ new Date());
|
|
10843
10856
|
} catch {
|
|
10844
10857
|
}
|
|
10845
|
-
return { kind: "spawned", command, pid: child.pid
|
|
10858
|
+
return { kind: "spawned", command, pid: child.pid };
|
|
10846
10859
|
} catch (spawnErr) {
|
|
10847
10860
|
return {
|
|
10848
10861
|
kind: "spawn_failed",
|
|
@@ -10898,7 +10911,6 @@ async function dispatchFinalizeFailure(input) {
|
|
|
10898
10911
|
preflightCode: input.preflightCode,
|
|
10899
10912
|
command: "command" in outcome ? outcome.command : null,
|
|
10900
10913
|
pid: outcome.kind === "spawned" ? outcome.pid ?? null : null,
|
|
10901
|
-
logPath: outcome.kind === "spawned" ? outcome.logPath : null,
|
|
10902
10914
|
recommendedCommand
|
|
10903
10915
|
},
|
|
10904
10916
|
message: outcome.kind === "spawn_failed" ? outcome.message : null
|
|
@@ -10911,7 +10923,7 @@ function mergeOutcomeIntoMarker(existing, outcome) {
|
|
|
10911
10923
|
status: "in_progress",
|
|
10912
10924
|
command: outcome.command,
|
|
10913
10925
|
pid: outcome.pid ?? null,
|
|
10914
|
-
logPath:
|
|
10926
|
+
logPath: null,
|
|
10915
10927
|
attemptedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10916
10928
|
failureMessage: null
|
|
10917
10929
|
};
|
|
@@ -10958,7 +10970,7 @@ function createApiClient(config, opts) {
|
|
|
10958
10970
|
const ms = typeof timeoutMs === "number" && timeoutMs > 0 ? timeoutMs : defaultTimeoutMs;
|
|
10959
10971
|
return ms != null ? AbortSignal.timeout(ms) : void 0;
|
|
10960
10972
|
}
|
|
10961
|
-
async function request(
|
|
10973
|
+
async function request(path18, init, opts2) {
|
|
10962
10974
|
if (!tokenProvider) {
|
|
10963
10975
|
throw new RemixError("API client is missing a token provider.", {
|
|
10964
10976
|
exitCode: 1,
|
|
@@ -10966,7 +10978,7 @@ function createApiClient(config, opts) {
|
|
|
10966
10978
|
});
|
|
10967
10979
|
}
|
|
10968
10980
|
const auth = await tokenProvider();
|
|
10969
|
-
const url = new URL(
|
|
10981
|
+
const url = new URL(path18, config.apiUrl).toString();
|
|
10970
10982
|
const doFetch = async (bearer) => fetch(url, {
|
|
10971
10983
|
...init,
|
|
10972
10984
|
signal: makeTimeoutSignal(opts2?.timeoutMs),
|
|
@@ -10995,7 +11007,7 @@ function createApiClient(config, opts) {
|
|
|
10995
11007
|
const json = await readJsonSafe(res);
|
|
10996
11008
|
return json ?? null;
|
|
10997
11009
|
}
|
|
10998
|
-
async function requestBinary(
|
|
11010
|
+
async function requestBinary(path18, init, opts2) {
|
|
10999
11011
|
if (!tokenProvider) {
|
|
11000
11012
|
throw new RemixError("API client is missing a token provider.", {
|
|
11001
11013
|
exitCode: 1,
|
|
@@ -11003,7 +11015,7 @@ function createApiClient(config, opts) {
|
|
|
11003
11015
|
});
|
|
11004
11016
|
}
|
|
11005
11017
|
const auth = await tokenProvider();
|
|
11006
|
-
const url = new URL(
|
|
11018
|
+
const url = new URL(path18, config.apiUrl).toString();
|
|
11007
11019
|
const doFetch = async (bearer) => fetch(url, {
|
|
11008
11020
|
...init,
|
|
11009
11021
|
signal: makeTimeoutSignal(opts2?.timeoutMs),
|
|
@@ -11866,8 +11878,8 @@ function getErrorMap() {
|
|
|
11866
11878
|
|
|
11867
11879
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
11868
11880
|
var makeIssue = (params) => {
|
|
11869
|
-
const { data, path:
|
|
11870
|
-
const fullPath = [...
|
|
11881
|
+
const { data, path: path18, errorMaps, issueData } = params;
|
|
11882
|
+
const fullPath = [...path18, ...issueData.path || []];
|
|
11871
11883
|
const fullIssue = {
|
|
11872
11884
|
...issueData,
|
|
11873
11885
|
path: fullPath
|
|
@@ -11983,11 +11995,11 @@ var errorUtil;
|
|
|
11983
11995
|
|
|
11984
11996
|
// node_modules/zod/v3/types.js
|
|
11985
11997
|
var ParseInputLazyPath = class {
|
|
11986
|
-
constructor(parent, value,
|
|
11998
|
+
constructor(parent, value, path18, key) {
|
|
11987
11999
|
this._cachedPath = [];
|
|
11988
12000
|
this.parent = parent;
|
|
11989
12001
|
this.data = value;
|
|
11990
|
-
this._path =
|
|
12002
|
+
this._path = path18;
|
|
11991
12003
|
this._key = key;
|
|
11992
12004
|
}
|
|
11993
12005
|
get path() {
|
|
@@ -24535,8 +24547,8 @@ var IcebergError = class extends Error {
|
|
|
24535
24547
|
return this.status === 419;
|
|
24536
24548
|
}
|
|
24537
24549
|
};
|
|
24538
|
-
function buildUrl(baseUrl,
|
|
24539
|
-
const url = new URL(
|
|
24550
|
+
function buildUrl(baseUrl, path18, query) {
|
|
24551
|
+
const url = new URL(path18, baseUrl);
|
|
24540
24552
|
if (query) {
|
|
24541
24553
|
for (const [key, value] of Object.entries(query)) {
|
|
24542
24554
|
if (value !== void 0) {
|
|
@@ -24566,12 +24578,12 @@ function createFetchClient(options) {
|
|
|
24566
24578
|
return {
|
|
24567
24579
|
async request({
|
|
24568
24580
|
method,
|
|
24569
|
-
path:
|
|
24581
|
+
path: path18,
|
|
24570
24582
|
query,
|
|
24571
24583
|
body,
|
|
24572
24584
|
headers
|
|
24573
24585
|
}) {
|
|
24574
|
-
const url = buildUrl(options.baseUrl,
|
|
24586
|
+
const url = buildUrl(options.baseUrl, path18, query);
|
|
24575
24587
|
const authHeaders = await buildAuthHeaders(options.auth);
|
|
24576
24588
|
const res = await fetchFn(url, {
|
|
24577
24589
|
method,
|
|
@@ -25409,7 +25421,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25409
25421
|
* @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.
|
|
25410
25422
|
* @param fileBody The body of the file to be stored in the bucket.
|
|
25411
25423
|
*/
|
|
25412
|
-
async uploadOrUpdate(method,
|
|
25424
|
+
async uploadOrUpdate(method, path18, fileBody, fileOptions) {
|
|
25413
25425
|
var _this = this;
|
|
25414
25426
|
return _this.handleOperation(async () => {
|
|
25415
25427
|
let body;
|
|
@@ -25433,7 +25445,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25433
25445
|
if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
|
|
25434
25446
|
}
|
|
25435
25447
|
if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) for (const [key, value] of Object.entries(fileOptions.headers)) headers = setHeader(headers, key, value);
|
|
25436
|
-
const cleanPath = _this._removeEmptyFolders(
|
|
25448
|
+
const cleanPath = _this._removeEmptyFolders(path18);
|
|
25437
25449
|
const _path = _this._getFinalPath(cleanPath);
|
|
25438
25450
|
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 } : {}));
|
|
25439
25451
|
return {
|
|
@@ -25494,8 +25506,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25494
25506
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25495
25507
|
* - 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.
|
|
25496
25508
|
*/
|
|
25497
|
-
async upload(
|
|
25498
|
-
return this.uploadOrUpdate("POST",
|
|
25509
|
+
async upload(path18, fileBody, fileOptions) {
|
|
25510
|
+
return this.uploadOrUpdate("POST", path18, fileBody, fileOptions);
|
|
25499
25511
|
}
|
|
25500
25512
|
/**
|
|
25501
25513
|
* Upload a file with a token generated from `createSignedUploadUrl`.
|
|
@@ -25534,9 +25546,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25534
25546
|
* - `objects` table permissions: none
|
|
25535
25547
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25536
25548
|
*/
|
|
25537
|
-
async uploadToSignedUrl(
|
|
25549
|
+
async uploadToSignedUrl(path18, token, fileBody, fileOptions) {
|
|
25538
25550
|
var _this3 = this;
|
|
25539
|
-
const cleanPath = _this3._removeEmptyFolders(
|
|
25551
|
+
const cleanPath = _this3._removeEmptyFolders(path18);
|
|
25540
25552
|
const _path = _this3._getFinalPath(cleanPath);
|
|
25541
25553
|
const url = new URL(_this3.url + `/object/upload/sign/${_path}`);
|
|
25542
25554
|
url.searchParams.set("token", token);
|
|
@@ -25598,10 +25610,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25598
25610
|
* - `objects` table permissions: `insert`
|
|
25599
25611
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25600
25612
|
*/
|
|
25601
|
-
async createSignedUploadUrl(
|
|
25613
|
+
async createSignedUploadUrl(path18, options) {
|
|
25602
25614
|
var _this4 = this;
|
|
25603
25615
|
return _this4.handleOperation(async () => {
|
|
25604
|
-
let _path = _this4._getFinalPath(
|
|
25616
|
+
let _path = _this4._getFinalPath(path18);
|
|
25605
25617
|
const headers = _objectSpread22({}, _this4.headers);
|
|
25606
25618
|
if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
|
|
25607
25619
|
const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
|
|
@@ -25610,7 +25622,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25610
25622
|
if (!token) throw new StorageError("No token returned by API");
|
|
25611
25623
|
return {
|
|
25612
25624
|
signedUrl: url.toString(),
|
|
25613
|
-
path:
|
|
25625
|
+
path: path18,
|
|
25614
25626
|
token
|
|
25615
25627
|
};
|
|
25616
25628
|
});
|
|
@@ -25666,8 +25678,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25666
25678
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25667
25679
|
* - 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.
|
|
25668
25680
|
*/
|
|
25669
|
-
async update(
|
|
25670
|
-
return this.uploadOrUpdate("PUT",
|
|
25681
|
+
async update(path18, fileBody, fileOptions) {
|
|
25682
|
+
return this.uploadOrUpdate("PUT", path18, fileBody, fileOptions);
|
|
25671
25683
|
}
|
|
25672
25684
|
/**
|
|
25673
25685
|
* Moves an existing file to a new path in the same bucket.
|
|
@@ -25815,10 +25827,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25815
25827
|
* - `objects` table permissions: `select`
|
|
25816
25828
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25817
25829
|
*/
|
|
25818
|
-
async createSignedUrl(
|
|
25830
|
+
async createSignedUrl(path18, expiresIn, options) {
|
|
25819
25831
|
var _this8 = this;
|
|
25820
25832
|
return _this8.handleOperation(async () => {
|
|
25821
|
-
let _path = _this8._getFinalPath(
|
|
25833
|
+
let _path = _this8._getFinalPath(path18);
|
|
25822
25834
|
const hasTransform = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0;
|
|
25823
25835
|
let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, hasTransform ? { transform: options.transform } : {}), { headers: _this8.headers });
|
|
25824
25836
|
const query = new URLSearchParams();
|
|
@@ -25952,13 +25964,13 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25952
25964
|
* - `objects` table permissions: `select`
|
|
25953
25965
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
25954
25966
|
*/
|
|
25955
|
-
download(
|
|
25967
|
+
download(path18, options, parameters) {
|
|
25956
25968
|
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";
|
|
25957
25969
|
const query = new URLSearchParams();
|
|
25958
25970
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
25959
25971
|
if ((options === null || options === void 0 ? void 0 : options.cacheNonce) != null) query.set("cacheNonce", String(options.cacheNonce));
|
|
25960
25972
|
const queryString = query.toString();
|
|
25961
|
-
const _path = this._getFinalPath(
|
|
25973
|
+
const _path = this._getFinalPath(path18);
|
|
25962
25974
|
const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ""}`, {
|
|
25963
25975
|
headers: this.headers,
|
|
25964
25976
|
noResolveJson: true
|
|
@@ -25988,9 +26000,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
25988
26000
|
* }
|
|
25989
26001
|
* ```
|
|
25990
26002
|
*/
|
|
25991
|
-
async info(
|
|
26003
|
+
async info(path18) {
|
|
25992
26004
|
var _this10 = this;
|
|
25993
|
-
const _path = _this10._getFinalPath(
|
|
26005
|
+
const _path = _this10._getFinalPath(path18);
|
|
25994
26006
|
return _this10.handleOperation(async () => {
|
|
25995
26007
|
return recursiveToCamel(await get(_this10.fetch, `${_this10.url}/object/info/${_path}`, { headers: _this10.headers }));
|
|
25996
26008
|
});
|
|
@@ -26010,9 +26022,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26010
26022
|
* .exists('folder/avatar1.png')
|
|
26011
26023
|
* ```
|
|
26012
26024
|
*/
|
|
26013
|
-
async exists(
|
|
26025
|
+
async exists(path18) {
|
|
26014
26026
|
var _this11 = this;
|
|
26015
|
-
const _path = _this11._getFinalPath(
|
|
26027
|
+
const _path = _this11._getFinalPath(path18);
|
|
26016
26028
|
try {
|
|
26017
26029
|
await head(_this11.fetch, `${_this11.url}/object/${_path}`, { headers: _this11.headers });
|
|
26018
26030
|
return {
|
|
@@ -26090,8 +26102,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26090
26102
|
* - `objects` table permissions: none
|
|
26091
26103
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
26092
26104
|
*/
|
|
26093
|
-
getPublicUrl(
|
|
26094
|
-
const _path = this._getFinalPath(
|
|
26105
|
+
getPublicUrl(path18, options) {
|
|
26106
|
+
const _path = this._getFinalPath(path18);
|
|
26095
26107
|
const query = new URLSearchParams();
|
|
26096
26108
|
if (options === null || options === void 0 ? void 0 : options.download) query.set("download", options.download === true ? "" : options.download);
|
|
26097
26109
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
@@ -26228,10 +26240,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26228
26240
|
* - `objects` table permissions: `select`
|
|
26229
26241
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
26230
26242
|
*/
|
|
26231
|
-
async list(
|
|
26243
|
+
async list(path18, options, parameters) {
|
|
26232
26244
|
var _this13 = this;
|
|
26233
26245
|
return _this13.handleOperation(async () => {
|
|
26234
|
-
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix:
|
|
26246
|
+
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path18 || "" });
|
|
26235
26247
|
return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
|
|
26236
26248
|
});
|
|
26237
26249
|
}
|
|
@@ -26295,11 +26307,11 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
26295
26307
|
if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
|
|
26296
26308
|
return btoa(data);
|
|
26297
26309
|
}
|
|
26298
|
-
_getFinalPath(
|
|
26299
|
-
return `${this.bucketId}/${
|
|
26310
|
+
_getFinalPath(path18) {
|
|
26311
|
+
return `${this.bucketId}/${path18.replace(/^\/+/, "")}`;
|
|
26300
26312
|
}
|
|
26301
|
-
_removeEmptyFolders(
|
|
26302
|
-
return
|
|
26313
|
+
_removeEmptyFolders(path18) {
|
|
26314
|
+
return path18.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
|
|
26303
26315
|
}
|
|
26304
26316
|
/** Modifies the `query`, appending values the from `transform` */
|
|
26305
26317
|
applyTransformOptsToQuery(query, transform) {
|
|
@@ -35677,11 +35689,11 @@ function isPidAlive(pid) {
|
|
|
35677
35689
|
}
|
|
35678
35690
|
}
|
|
35679
35691
|
function repoLockFileName(repoRoot) {
|
|
35680
|
-
const hash = (0,
|
|
35692
|
+
const hash = (0, import_node_crypto5.createHash)("sha256").update(repoRoot).digest("hex").slice(0, 16);
|
|
35681
35693
|
return `.drainer-${hash}.lock`;
|
|
35682
35694
|
}
|
|
35683
35695
|
function repoLockPath(repoRoot) {
|
|
35684
|
-
return
|
|
35696
|
+
return import_node_path12.default.join(getDeferredTurnDirPath(), repoLockFileName(repoRoot));
|
|
35685
35697
|
}
|
|
35686
35698
|
async function readDrainLockMetadata(lockPath) {
|
|
35687
35699
|
const raw = await import_promises23.default.readFile(lockPath, "utf8").catch(() => null);
|
|
@@ -35703,7 +35715,7 @@ async function writeDrainLockMetadata(lockPath, metadata) {
|
|
|
35703
35715
|
}
|
|
35704
35716
|
async function tryAcquireDrainLock(repoRoot) {
|
|
35705
35717
|
const lockPath = repoLockPath(repoRoot);
|
|
35706
|
-
await import_promises23.default.mkdir(
|
|
35718
|
+
await import_promises23.default.mkdir(import_node_path12.default.dirname(lockPath), { recursive: true });
|
|
35707
35719
|
const existingMeta = await readDrainLockMetadata(lockPath);
|
|
35708
35720
|
if (existingMeta) {
|
|
35709
35721
|
const lockStat = await import_promises23.default.stat(lockPath).catch(() => null);
|
|
@@ -36100,7 +36112,7 @@ function spawnDeferredTurnDrainer(repoRoot) {
|
|
|
36100
36112
|
|
|
36101
36113
|
// src/hook-utils.ts
|
|
36102
36114
|
var import_promises24 = __toESM(require("fs/promises"), 1);
|
|
36103
|
-
var
|
|
36115
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
36104
36116
|
async function readJsonStdin() {
|
|
36105
36117
|
const chunks = [];
|
|
36106
36118
|
for await (const chunk of process.stdin) {
|
|
@@ -36126,16 +36138,16 @@ function extractString(input, keys) {
|
|
|
36126
36138
|
}
|
|
36127
36139
|
async function findBoundRepo(startPath) {
|
|
36128
36140
|
if (!startPath) return null;
|
|
36129
|
-
let current =
|
|
36141
|
+
let current = import_node_path13.default.resolve(startPath);
|
|
36130
36142
|
let stats = await import_promises24.default.stat(current).catch(() => null);
|
|
36131
36143
|
if (stats?.isFile()) {
|
|
36132
|
-
current =
|
|
36144
|
+
current = import_node_path13.default.dirname(current);
|
|
36133
36145
|
}
|
|
36134
36146
|
while (true) {
|
|
36135
|
-
const bindingPath =
|
|
36147
|
+
const bindingPath = import_node_path13.default.join(current, ".remix", "config.json");
|
|
36136
36148
|
const bindingStats = await import_promises24.default.stat(bindingPath).catch(() => null);
|
|
36137
36149
|
if (bindingStats?.isFile()) return current;
|
|
36138
|
-
const parent =
|
|
36150
|
+
const parent = import_node_path13.default.dirname(current);
|
|
36139
36151
|
if (parent === current) return null;
|
|
36140
36152
|
current = parent;
|
|
36141
36153
|
}
|
|
@@ -36159,8 +36171,6 @@ function buildRuntimeStatusOverride() {
|
|
|
36159
36171
|
"Use `remix_collab_drain_finalize_queue` only for explicit recovery flows, such as status reporting `await_finalize` before a merge-related operation."
|
|
36160
36172
|
].join("\n");
|
|
36161
36173
|
}
|
|
36162
|
-
var COLLAB_INIT_LOG_REL = import_node_path13.default.join(".remix", "collab-init.log");
|
|
36163
|
-
var COLLAB_INIT_SPAWN_LOCK_REL = import_node_path13.default.join(".remix", ".collab-init-spawning");
|
|
36164
36174
|
var COLLAB_INIT_SPAWN_LOCK_STALE_MS = 90 * 1e3;
|
|
36165
36175
|
function isPidAlive2(pid) {
|
|
36166
36176
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -36171,9 +36181,9 @@ function isPidAlive2(pid) {
|
|
|
36171
36181
|
return false;
|
|
36172
36182
|
}
|
|
36173
36183
|
}
|
|
36174
|
-
function readSpawnLock(
|
|
36184
|
+
function readSpawnLock(spawnLockPath2) {
|
|
36175
36185
|
try {
|
|
36176
|
-
const raw = (0, import_node_fs7.readFileSync)(
|
|
36186
|
+
const raw = (0, import_node_fs7.readFileSync)(spawnLockPath2, "utf8").trim();
|
|
36177
36187
|
if (!raw) return null;
|
|
36178
36188
|
if (raw.startsWith("{")) {
|
|
36179
36189
|
const parsed = JSON.parse(raw);
|
|
@@ -36193,22 +36203,20 @@ function readSpawnLock(spawnLockPath) {
|
|
|
36193
36203
|
}
|
|
36194
36204
|
}
|
|
36195
36205
|
function maybeAutoSpawnBranchInit(repoRoot, branchName) {
|
|
36196
|
-
const
|
|
36197
|
-
const spawnLockPath = import_node_path13.default.join(repoRoot, COLLAB_INIT_SPAWN_LOCK_REL);
|
|
36198
|
-
const logPath = import_node_path13.default.join(repoRoot, COLLAB_INIT_LOG_REL);
|
|
36206
|
+
const spawnLockPath2 = collabInitSpawnLockPath(repoRoot);
|
|
36199
36207
|
try {
|
|
36200
|
-
if ((0, import_node_fs7.existsSync)(
|
|
36201
|
-
const lock = readSpawnLock(
|
|
36208
|
+
if ((0, import_node_fs7.existsSync)(spawnLockPath2)) {
|
|
36209
|
+
const lock = readSpawnLock(spawnLockPath2);
|
|
36202
36210
|
const lockPid = lock?.pid ?? null;
|
|
36203
36211
|
const lockAlive = lockPid !== null && isPidAlive2(lockPid);
|
|
36204
36212
|
const sameBranch = !lock?.branchName || !branchName || lock.branchName === branchName;
|
|
36205
|
-
const ageMs = Date.now() - (0, import_node_fs7.statSync)(
|
|
36213
|
+
const ageMs = Date.now() - (0, import_node_fs7.statSync)(spawnLockPath2).mtimeMs;
|
|
36206
36214
|
if (lockAlive && sameBranch && ageMs < COLLAB_INIT_SPAWN_LOCK_STALE_MS) {
|
|
36207
36215
|
return { spawned: false, reason: "spawn_lock_held" };
|
|
36208
36216
|
}
|
|
36209
36217
|
if (!lockAlive) {
|
|
36210
36218
|
try {
|
|
36211
|
-
(0, import_node_fs7.unlinkSync)(
|
|
36219
|
+
(0, import_node_fs7.unlinkSync)(spawnLockPath2);
|
|
36212
36220
|
} catch {
|
|
36213
36221
|
}
|
|
36214
36222
|
}
|
|
@@ -36216,33 +36224,14 @@ function maybeAutoSpawnBranchInit(repoRoot, branchName) {
|
|
|
36216
36224
|
} catch {
|
|
36217
36225
|
}
|
|
36218
36226
|
try {
|
|
36219
|
-
(0, import_node_fs7.mkdirSync)(
|
|
36227
|
+
(0, import_node_fs7.mkdirSync)(import_node_path14.default.dirname(spawnLockPath2), { recursive: true });
|
|
36220
36228
|
} catch {
|
|
36221
36229
|
}
|
|
36222
|
-
let out;
|
|
36223
|
-
let err;
|
|
36224
36230
|
try {
|
|
36225
|
-
out = (0, import_node_fs7.openSync)(logPath, "a");
|
|
36226
|
-
err = (0, import_node_fs7.openSync)(logPath, "a");
|
|
36227
|
-
} catch (logErr) {
|
|
36228
|
-
return {
|
|
36229
|
-
spawned: false,
|
|
36230
|
-
reason: "log_open_failed",
|
|
36231
|
-
message: logErr instanceof Error ? logErr.message : String(logErr)
|
|
36232
|
-
};
|
|
36233
|
-
}
|
|
36234
|
-
try {
|
|
36235
|
-
(0, import_node_fs7.appendFileSync)(
|
|
36236
|
-
logPath,
|
|
36237
|
-
`
|
|
36238
|
-
[${(/* @__PURE__ */ new Date()).toISOString()}] auto-spawning remix collab init for branch=${branchName ?? "(unknown)"} repo=${repoRoot}
|
|
36239
|
-
`,
|
|
36240
|
-
"utf8"
|
|
36241
|
-
);
|
|
36242
36231
|
const child = (0, import_node_child_process8.spawn)("remix", ["collab", "init"], {
|
|
36243
36232
|
cwd: repoRoot,
|
|
36244
36233
|
detached: true,
|
|
36245
|
-
stdio:
|
|
36234
|
+
stdio: "ignore",
|
|
36246
36235
|
env: { ...process.env, REMIX_COLLAB_INIT_AUTO_SPAWN: "1" }
|
|
36247
36236
|
});
|
|
36248
36237
|
child.unref();
|
|
@@ -36255,12 +36244,12 @@ function maybeAutoSpawnBranchInit(repoRoot, branchName) {
|
|
|
36255
36244
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
36256
36245
|
command: "remix collab init"
|
|
36257
36246
|
};
|
|
36258
|
-
(0, import_node_fs7.writeFileSync)(
|
|
36247
|
+
(0, import_node_fs7.writeFileSync)(spawnLockPath2, `${JSON.stringify(lock, null, 2)}
|
|
36259
36248
|
`, "utf8");
|
|
36260
|
-
(0, import_node_fs7.utimesSync)(
|
|
36249
|
+
(0, import_node_fs7.utimesSync)(spawnLockPath2, /* @__PURE__ */ new Date(), /* @__PURE__ */ new Date());
|
|
36261
36250
|
} catch {
|
|
36262
36251
|
}
|
|
36263
|
-
return { spawned: true, pid: child.pid
|
|
36252
|
+
return { spawned: true, pid: child.pid };
|
|
36264
36253
|
} catch (spawnErr) {
|
|
36265
36254
|
return {
|
|
36266
36255
|
spawned: false,
|
|
@@ -36269,14 +36258,13 @@ function maybeAutoSpawnBranchInit(repoRoot, branchName) {
|
|
|
36269
36258
|
};
|
|
36270
36259
|
}
|
|
36271
36260
|
}
|
|
36272
|
-
function buildBranchInitContextMessage(branch, repoRoot
|
|
36261
|
+
function buildBranchInitContextMessage(branch, repoRoot) {
|
|
36273
36262
|
const branchLabel = branch ? `\`${branch}\`` : "the current branch";
|
|
36274
36263
|
return [
|
|
36275
36264
|
"[Remix recovery in progress]:",
|
|
36276
36265
|
`Remix is initializing recording for ${branchLabel} in ${repoRoot} in the background.`,
|
|
36277
36266
|
"This turn may be recorded retroactively once init finishes (it may appear in the timeline with a small delay).",
|
|
36278
|
-
"Do NOT call any Remix MCP tool to initialize, repair, or sync this branch \u2014 the plugin is handling it automatically."
|
|
36279
|
-
`Init log: ${logPath}`
|
|
36267
|
+
"Do NOT call any Remix MCP tool to initialize, repair, or sync this branch \u2014 the plugin is handling it automatically."
|
|
36280
36268
|
].join("\n");
|
|
36281
36269
|
}
|
|
36282
36270
|
var STALE_MARKER_THRESHOLD_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -36477,7 +36465,7 @@ async function runHookUserPrompt(payload) {
|
|
|
36477
36465
|
const currentBranch = bindingState?.currentBranch ?? null;
|
|
36478
36466
|
const outcome = maybeAutoSpawnBranchInit(boundRepo, currentBranch);
|
|
36479
36467
|
if (outcome.spawned) {
|
|
36480
|
-
advisorySections.push(buildBranchInitContextMessage(currentBranch, boundRepo
|
|
36468
|
+
advisorySections.push(buildBranchInitContextMessage(currentBranch, boundRepo));
|
|
36481
36469
|
await appendHookDiagnosticsEvent({
|
|
36482
36470
|
hook: "UserPromptSubmit",
|
|
36483
36471
|
sessionId,
|
|
@@ -36488,8 +36476,7 @@ async function runHookUserPrompt(payload) {
|
|
|
36488
36476
|
fields: {
|
|
36489
36477
|
currentBranch,
|
|
36490
36478
|
knownBoundBranchCount: knownBoundBranches.length,
|
|
36491
|
-
pid: outcome.pid ?? null
|
|
36492
|
-
logPath: outcome.logPath
|
|
36479
|
+
pid: outcome.pid ?? null
|
|
36493
36480
|
}
|
|
36494
36481
|
});
|
|
36495
36482
|
} else {
|