@remixhq/claude-plugin 0.1.21 → 0.1.23
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/agents/remix-collab.md +1 -1
- package/dist/hook-post-collab.cjs +6 -6
- package/dist/hook-post-collab.cjs.map +1 -1
- package/dist/hook-pre-git.cjs +2 -2
- package/dist/hook-pre-git.cjs.map +1 -1
- package/dist/hook-stop-collab.cjs +2252 -858
- package/dist/hook-stop-collab.cjs.map +1 -1
- package/dist/hook-user-prompt.cjs +28588 -312
- package/dist/hook-user-prompt.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.cjs +386 -493
- package/dist/mcp-server.cjs.map +1 -1
- package/package.json +4 -4
- package/skills/init-or-remix/SKILL.md +5 -3
- package/skills/safe-collab-workflow/SKILL.md +15 -8
- package/skills/submit-change-step/SKILL.md +13 -11
- package/skills/sync-and-reconcile/SKILL.md +1 -1
package/dist/mcp-server.cjs
CHANGED
|
@@ -36,8 +36,8 @@ var require_windows = __commonJS({
|
|
|
36
36
|
"use strict";
|
|
37
37
|
module2.exports = isexe;
|
|
38
38
|
isexe.sync = sync;
|
|
39
|
-
var
|
|
40
|
-
function checkPathExt(
|
|
39
|
+
var fs16 = require("fs");
|
|
40
|
+
function checkPathExt(path16, options) {
|
|
41
41
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
42
42
|
if (!pathext) {
|
|
43
43
|
return true;
|
|
@@ -48,25 +48,25 @@ var require_windows = __commonJS({
|
|
|
48
48
|
}
|
|
49
49
|
for (var i2 = 0; i2 < pathext.length; i2++) {
|
|
50
50
|
var p = pathext[i2].toLowerCase();
|
|
51
|
-
if (p &&
|
|
51
|
+
if (p && path16.substr(-p.length).toLowerCase() === p) {
|
|
52
52
|
return true;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
return false;
|
|
56
56
|
}
|
|
57
|
-
function checkStat(stat,
|
|
57
|
+
function checkStat(stat, path16, options) {
|
|
58
58
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
59
59
|
return false;
|
|
60
60
|
}
|
|
61
|
-
return checkPathExt(
|
|
61
|
+
return checkPathExt(path16, options);
|
|
62
62
|
}
|
|
63
|
-
function isexe(
|
|
64
|
-
|
|
65
|
-
cb(er, er ? false : checkStat(stat,
|
|
63
|
+
function isexe(path16, options, cb) {
|
|
64
|
+
fs16.stat(path16, function(er, stat) {
|
|
65
|
+
cb(er, er ? false : checkStat(stat, path16, options));
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
|
-
function sync(
|
|
69
|
-
return checkStat(
|
|
68
|
+
function sync(path16, options) {
|
|
69
|
+
return checkStat(fs16.statSync(path16), path16, options);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
});
|
|
@@ -77,14 +77,14 @@ var require_mode = __commonJS({
|
|
|
77
77
|
"use strict";
|
|
78
78
|
module2.exports = isexe;
|
|
79
79
|
isexe.sync = sync;
|
|
80
|
-
var
|
|
81
|
-
function isexe(
|
|
82
|
-
|
|
80
|
+
var fs16 = require("fs");
|
|
81
|
+
function isexe(path16, options, cb) {
|
|
82
|
+
fs16.stat(path16, function(er, stat) {
|
|
83
83
|
cb(er, er ? false : checkStat(stat, options));
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
function sync(
|
|
87
|
-
return checkStat(
|
|
86
|
+
function sync(path16, options) {
|
|
87
|
+
return checkStat(fs16.statSync(path16), options);
|
|
88
88
|
}
|
|
89
89
|
function checkStat(stat, options) {
|
|
90
90
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -109,7 +109,7 @@ var require_mode = __commonJS({
|
|
|
109
109
|
var require_isexe = __commonJS({
|
|
110
110
|
"node_modules/isexe/index.js"(exports2, module2) {
|
|
111
111
|
"use strict";
|
|
112
|
-
var
|
|
112
|
+
var fs16 = require("fs");
|
|
113
113
|
var core;
|
|
114
114
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
115
115
|
core = require_windows();
|
|
@@ -118,7 +118,7 @@ var require_isexe = __commonJS({
|
|
|
118
118
|
}
|
|
119
119
|
module2.exports = isexe;
|
|
120
120
|
isexe.sync = sync;
|
|
121
|
-
function isexe(
|
|
121
|
+
function isexe(path16, options, cb) {
|
|
122
122
|
if (typeof options === "function") {
|
|
123
123
|
cb = options;
|
|
124
124
|
options = {};
|
|
@@ -128,7 +128,7 @@ var require_isexe = __commonJS({
|
|
|
128
128
|
throw new TypeError("callback not provided");
|
|
129
129
|
}
|
|
130
130
|
return new Promise(function(resolve, reject) {
|
|
131
|
-
isexe(
|
|
131
|
+
isexe(path16, options || {}, function(er, is) {
|
|
132
132
|
if (er) {
|
|
133
133
|
reject(er);
|
|
134
134
|
} else {
|
|
@@ -137,7 +137,7 @@ var require_isexe = __commonJS({
|
|
|
137
137
|
});
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
|
-
core(
|
|
140
|
+
core(path16, options || {}, function(er, is) {
|
|
141
141
|
if (er) {
|
|
142
142
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
143
143
|
er = null;
|
|
@@ -147,9 +147,9 @@ var require_isexe = __commonJS({
|
|
|
147
147
|
cb(er, is);
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
|
-
function sync(
|
|
150
|
+
function sync(path16, options) {
|
|
151
151
|
try {
|
|
152
|
-
return core.sync(
|
|
152
|
+
return core.sync(path16, options || {});
|
|
153
153
|
} catch (er) {
|
|
154
154
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
155
155
|
return false;
|
|
@@ -166,7 +166,7 @@ var require_which = __commonJS({
|
|
|
166
166
|
"node_modules/which/which.js"(exports2, module2) {
|
|
167
167
|
"use strict";
|
|
168
168
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
169
|
-
var
|
|
169
|
+
var path16 = require("path");
|
|
170
170
|
var COLON = isWindows ? ";" : ":";
|
|
171
171
|
var isexe = require_isexe();
|
|
172
172
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -204,7 +204,7 @@ var require_which = __commonJS({
|
|
|
204
204
|
return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
205
205
|
const ppRaw = pathEnv[i2];
|
|
206
206
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
207
|
-
const pCmd =
|
|
207
|
+
const pCmd = path16.join(pathPart, cmd);
|
|
208
208
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
209
209
|
resolve(subStep(p, i2, 0));
|
|
210
210
|
});
|
|
@@ -231,7 +231,7 @@ var require_which = __commonJS({
|
|
|
231
231
|
for (let i2 = 0; i2 < pathEnv.length; i2++) {
|
|
232
232
|
const ppRaw = pathEnv[i2];
|
|
233
233
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
234
|
-
const pCmd =
|
|
234
|
+
const pCmd = path16.join(pathPart, cmd);
|
|
235
235
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
236
236
|
for (let j = 0; j < pathExt.length; j++) {
|
|
237
237
|
const cur = p + pathExt[j];
|
|
@@ -279,7 +279,7 @@ var require_path_key = __commonJS({
|
|
|
279
279
|
var require_resolveCommand = __commonJS({
|
|
280
280
|
"node_modules/cross-spawn/lib/util/resolveCommand.js"(exports2, module2) {
|
|
281
281
|
"use strict";
|
|
282
|
-
var
|
|
282
|
+
var path16 = require("path");
|
|
283
283
|
var which = require_which();
|
|
284
284
|
var getPathKey = require_path_key();
|
|
285
285
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -297,7 +297,7 @@ var require_resolveCommand = __commonJS({
|
|
|
297
297
|
try {
|
|
298
298
|
resolved = which.sync(parsed.command, {
|
|
299
299
|
path: env[getPathKey({ env })],
|
|
300
|
-
pathExt: withoutPathExt ?
|
|
300
|
+
pathExt: withoutPathExt ? path16.delimiter : void 0
|
|
301
301
|
});
|
|
302
302
|
} catch (e) {
|
|
303
303
|
} finally {
|
|
@@ -306,7 +306,7 @@ var require_resolveCommand = __commonJS({
|
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
if (resolved) {
|
|
309
|
-
resolved =
|
|
309
|
+
resolved = path16.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
310
310
|
}
|
|
311
311
|
return resolved;
|
|
312
312
|
}
|
|
@@ -360,8 +360,8 @@ var require_shebang_command = __commonJS({
|
|
|
360
360
|
if (!match) {
|
|
361
361
|
return null;
|
|
362
362
|
}
|
|
363
|
-
const [
|
|
364
|
-
const binary =
|
|
363
|
+
const [path16, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
364
|
+
const binary = path16.split("/").pop();
|
|
365
365
|
if (binary === "env") {
|
|
366
366
|
return argument;
|
|
367
367
|
}
|
|
@@ -374,16 +374,16 @@ var require_shebang_command = __commonJS({
|
|
|
374
374
|
var require_readShebang = __commonJS({
|
|
375
375
|
"node_modules/cross-spawn/lib/util/readShebang.js"(exports2, module2) {
|
|
376
376
|
"use strict";
|
|
377
|
-
var
|
|
377
|
+
var fs16 = require("fs");
|
|
378
378
|
var shebangCommand = require_shebang_command();
|
|
379
379
|
function readShebang(command) {
|
|
380
380
|
const size = 150;
|
|
381
381
|
const buffer = Buffer.alloc(size);
|
|
382
382
|
let fd;
|
|
383
383
|
try {
|
|
384
|
-
fd =
|
|
385
|
-
|
|
386
|
-
|
|
384
|
+
fd = fs16.openSync(command, "r");
|
|
385
|
+
fs16.readSync(fd, buffer, 0, size, 0);
|
|
386
|
+
fs16.closeSync(fd);
|
|
387
387
|
} catch (e) {
|
|
388
388
|
}
|
|
389
389
|
return shebangCommand(buffer.toString());
|
|
@@ -396,7 +396,7 @@ var require_readShebang = __commonJS({
|
|
|
396
396
|
var require_parse = __commonJS({
|
|
397
397
|
"node_modules/cross-spawn/lib/parse.js"(exports2, module2) {
|
|
398
398
|
"use strict";
|
|
399
|
-
var
|
|
399
|
+
var path16 = require("path");
|
|
400
400
|
var resolveCommand = require_resolveCommand();
|
|
401
401
|
var escape2 = require_escape();
|
|
402
402
|
var readShebang = require_readShebang();
|
|
@@ -421,7 +421,7 @@ var require_parse = __commonJS({
|
|
|
421
421
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
422
422
|
if (parsed.options.forceShell || needsShell) {
|
|
423
423
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
424
|
-
parsed.command =
|
|
424
|
+
parsed.command = path16.normalize(parsed.command);
|
|
425
425
|
parsed.command = escape2.command(parsed.command);
|
|
426
426
|
parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
|
|
427
427
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
@@ -3724,8 +3724,8 @@ var require_utils = __commonJS({
|
|
|
3724
3724
|
}
|
|
3725
3725
|
return ind;
|
|
3726
3726
|
}
|
|
3727
|
-
function removeDotSegments(
|
|
3728
|
-
let input =
|
|
3727
|
+
function removeDotSegments(path16) {
|
|
3728
|
+
let input = path16;
|
|
3729
3729
|
const output = [];
|
|
3730
3730
|
let nextSlash = -1;
|
|
3731
3731
|
let len = 0;
|
|
@@ -3924,8 +3924,8 @@ var require_schemes = __commonJS({
|
|
|
3924
3924
|
wsComponent.secure = void 0;
|
|
3925
3925
|
}
|
|
3926
3926
|
if (wsComponent.resourceName) {
|
|
3927
|
-
const [
|
|
3928
|
-
wsComponent.path =
|
|
3927
|
+
const [path16, query] = wsComponent.resourceName.split("?");
|
|
3928
|
+
wsComponent.path = path16 && path16 !== "/" ? path16 : void 0;
|
|
3929
3929
|
wsComponent.query = query;
|
|
3930
3930
|
wsComponent.resourceName = void 0;
|
|
3931
3931
|
}
|
|
@@ -7287,12 +7287,12 @@ var require_dist = __commonJS({
|
|
|
7287
7287
|
throw new Error(`Unknown format "${name}"`);
|
|
7288
7288
|
return f;
|
|
7289
7289
|
};
|
|
7290
|
-
function addFormats(ajv, list,
|
|
7290
|
+
function addFormats(ajv, list, fs16, exportName) {
|
|
7291
7291
|
var _a;
|
|
7292
7292
|
var _b;
|
|
7293
7293
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
7294
7294
|
for (const f of list)
|
|
7295
|
-
ajv.addFormat(f,
|
|
7295
|
+
ajv.addFormat(f, fs16[f]);
|
|
7296
7296
|
}
|
|
7297
7297
|
module2.exports = exports2 = formatsPlugin;
|
|
7298
7298
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -7498,10 +7498,10 @@ function assignProp(target, prop, value) {
|
|
|
7498
7498
|
configurable: true
|
|
7499
7499
|
});
|
|
7500
7500
|
}
|
|
7501
|
-
function getElementAtPath(obj,
|
|
7502
|
-
if (!
|
|
7501
|
+
function getElementAtPath(obj, path16) {
|
|
7502
|
+
if (!path16)
|
|
7503
7503
|
return obj;
|
|
7504
|
-
return
|
|
7504
|
+
return path16.reduce((acc, key) => acc?.[key], obj);
|
|
7505
7505
|
}
|
|
7506
7506
|
function promiseAllObject(promisesObj) {
|
|
7507
7507
|
const keys = Object.keys(promisesObj);
|
|
@@ -7821,11 +7821,11 @@ function aborted(x, startIndex = 0) {
|
|
|
7821
7821
|
}
|
|
7822
7822
|
return false;
|
|
7823
7823
|
}
|
|
7824
|
-
function prefixIssues(
|
|
7824
|
+
function prefixIssues(path16, issues) {
|
|
7825
7825
|
return issues.map((iss) => {
|
|
7826
7826
|
var _a;
|
|
7827
7827
|
(_a = iss).path ?? (_a.path = []);
|
|
7828
|
-
iss.path.unshift(
|
|
7828
|
+
iss.path.unshift(path16);
|
|
7829
7829
|
return iss;
|
|
7830
7830
|
});
|
|
7831
7831
|
}
|
|
@@ -13430,21 +13430,27 @@ var REMIX_ERROR_CODES = {
|
|
|
13430
13430
|
PREFERRED_BRANCH_MISMATCH: "PREFERRED_BRANCH_MISMATCH"
|
|
13431
13431
|
};
|
|
13432
13432
|
|
|
13433
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
13433
|
+
// node_modules/@remixhq/core/dist/chunk-7XJGOKEO.js
|
|
13434
13434
|
var RemixError = class extends Error {
|
|
13435
13435
|
code;
|
|
13436
13436
|
exitCode;
|
|
13437
13437
|
hint;
|
|
13438
|
+
// HTTP status code when this error originates from an API response.
|
|
13439
|
+
// null for non-HTTP errors (validation, local IO, programming bugs).
|
|
13440
|
+
// Callers use this to distinguish transient (5xx) from permanent (4xx)
|
|
13441
|
+
// API failures without resorting to error-message string matching.
|
|
13442
|
+
statusCode;
|
|
13438
13443
|
constructor(message, opts) {
|
|
13439
13444
|
super(message);
|
|
13440
13445
|
this.name = "RemixError";
|
|
13441
13446
|
this.code = opts?.code ?? null;
|
|
13442
13447
|
this.exitCode = opts?.exitCode ?? 1;
|
|
13443
13448
|
this.hint = opts?.hint ?? null;
|
|
13449
|
+
this.statusCode = opts?.statusCode ?? null;
|
|
13444
13450
|
}
|
|
13445
13451
|
};
|
|
13446
13452
|
|
|
13447
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
13453
|
+
// node_modules/@remixhq/core/dist/chunk-S4ECO35X.js
|
|
13448
13454
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
13449
13455
|
var import_crypto = require("crypto");
|
|
13450
13456
|
var import_os = __toESM(require("os"), 1);
|
|
@@ -17831,13 +17837,13 @@ var logOutputSync = ({ serializedResult, fdNumber, state, verboseInfo, encoding,
|
|
|
17831
17837
|
}
|
|
17832
17838
|
};
|
|
17833
17839
|
var writeToFiles = (serializedResult, stdioItems, outputFiles) => {
|
|
17834
|
-
for (const { path:
|
|
17835
|
-
const pathString = typeof
|
|
17840
|
+
for (const { path: path16, append } of stdioItems.filter(({ type }) => FILE_TYPES.has(type))) {
|
|
17841
|
+
const pathString = typeof path16 === "string" ? path16 : path16.toString();
|
|
17836
17842
|
if (append || outputFiles.has(pathString)) {
|
|
17837
|
-
(0, import_node_fs4.appendFileSync)(
|
|
17843
|
+
(0, import_node_fs4.appendFileSync)(path16, serializedResult);
|
|
17838
17844
|
} else {
|
|
17839
17845
|
outputFiles.add(pathString);
|
|
17840
|
-
(0, import_node_fs4.writeFileSync)(
|
|
17846
|
+
(0, import_node_fs4.writeFileSync)(path16, serializedResult);
|
|
17841
17847
|
}
|
|
17842
17848
|
}
|
|
17843
17849
|
};
|
|
@@ -20225,7 +20231,7 @@ var {
|
|
|
20225
20231
|
getCancelSignal: getCancelSignal2
|
|
20226
20232
|
} = getIpcExport();
|
|
20227
20233
|
|
|
20228
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
20234
|
+
// node_modules/@remixhq/core/dist/chunk-S4ECO35X.js
|
|
20229
20235
|
var GIT_REMOTE_PROTOCOL_RE = /^(https?|ssh):\/\//i;
|
|
20230
20236
|
var SCP_LIKE_GIT_REMOTE_RE = /^(?<user>[^@\s]+)@(?<host>[^:\s]+):(?<path>[^\\\s]+)$/;
|
|
20231
20237
|
var CANONICAL_GIT_REMOTE_RE = /^(?<host>(?:localhost|[a-z0-9.-]+))\/(?<path>[^\\\s]+)$/i;
|
|
@@ -20691,7 +20697,7 @@ function summarizeUnifiedDiff(diff) {
|
|
|
20691
20697
|
return { changedFilesCount, insertions, deletions };
|
|
20692
20698
|
}
|
|
20693
20699
|
|
|
20694
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
20700
|
+
// node_modules/@remixhq/core/dist/chunk-DBVN42RF.js
|
|
20695
20701
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
20696
20702
|
var import_path2 = __toESM(require("path"), 1);
|
|
20697
20703
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
@@ -21044,14 +21050,11 @@ var import_crypto8 = __toESM(require("crypto"), 1);
|
|
|
21044
21050
|
var import_fs = __toESM(require("fs"), 1);
|
|
21045
21051
|
var import_fs2 = __toESM(require("fs"), 1);
|
|
21046
21052
|
var import_stream3 = require("stream");
|
|
21047
|
-
var import_crypto9 = require("crypto");
|
|
21048
21053
|
var import_promises23 = __toESM(require("fs/promises"), 1);
|
|
21054
|
+
var import_os6 = __toESM(require("os"), 1);
|
|
21049
21055
|
var import_path12 = __toESM(require("path"), 1);
|
|
21050
21056
|
var import_promises24 = __toESM(require("fs/promises"), 1);
|
|
21051
|
-
var import_os6 = __toESM(require("os"), 1);
|
|
21052
21057
|
var import_path13 = __toESM(require("path"), 1);
|
|
21053
|
-
var import_promises25 = __toESM(require("fs/promises"), 1);
|
|
21054
|
-
var import_path14 = __toESM(require("path"), 1);
|
|
21055
21058
|
var APP_DELTA_CACHE_TTL_MS = 5e3;
|
|
21056
21059
|
var appDeltaCache = /* @__PURE__ */ new Map();
|
|
21057
21060
|
var cacheClock = () => Date.now();
|
|
@@ -21060,6 +21063,8 @@ function buildAppDeltaCacheKey(appId, payload) {
|
|
|
21060
21063
|
appId,
|
|
21061
21064
|
payload.baseHeadHash,
|
|
21062
21065
|
payload.targetHeadHash ?? "",
|
|
21066
|
+
payload.baseRevisionId ?? "",
|
|
21067
|
+
payload.targetRevisionId ?? "",
|
|
21063
21068
|
payload.localSnapshotHash ?? "",
|
|
21064
21069
|
payload.repoFingerprint ?? "",
|
|
21065
21070
|
payload.remoteUrl ?? "",
|
|
@@ -21188,9 +21193,6 @@ function getAsyncJobDir(jobId) {
|
|
|
21188
21193
|
function getAsyncJobFilePath(jobId) {
|
|
21189
21194
|
return import_path5.default.join(getAsyncJobDir(jobId), "job.json");
|
|
21190
21195
|
}
|
|
21191
|
-
function getAsyncJobBundlePath(jobId) {
|
|
21192
|
-
return import_path5.default.join(getAsyncJobDir(jobId), "bundle.bundle");
|
|
21193
|
-
}
|
|
21194
21196
|
function getLogsRoot() {
|
|
21195
21197
|
return import_path5.default.join(getCollabStateRoot(), "logs");
|
|
21196
21198
|
}
|
|
@@ -21459,11 +21461,11 @@ async function readLocalBaseline(params) {
|
|
|
21459
21461
|
const raw = await import_promises16.default.readFile(getBaselinePath(params), "utf8");
|
|
21460
21462
|
const parsed = JSON.parse(raw);
|
|
21461
21463
|
if (!parsed || typeof parsed !== "object") return null;
|
|
21462
|
-
if (parsed.schemaVersion
|
|
21464
|
+
if (![1, 2].includes(Number(parsed.schemaVersion)) || typeof parsed.key !== "string" || typeof parsed.repoRoot !== "string") {
|
|
21463
21465
|
return null;
|
|
21464
21466
|
}
|
|
21465
21467
|
return {
|
|
21466
|
-
schemaVersion: 1,
|
|
21468
|
+
schemaVersion: Number(parsed.schemaVersion) === 2 ? 2 : 1,
|
|
21467
21469
|
key: parsed.key,
|
|
21468
21470
|
repoRoot: parsed.repoRoot,
|
|
21469
21471
|
repoFingerprint: parsed.repoFingerprint ?? null,
|
|
@@ -21472,6 +21474,8 @@ async function readLocalBaseline(params) {
|
|
|
21472
21474
|
branchName: parsed.branchName ?? null,
|
|
21473
21475
|
lastSnapshotId: parsed.lastSnapshotId ?? null,
|
|
21474
21476
|
lastSnapshotHash: parsed.lastSnapshotHash ?? null,
|
|
21477
|
+
lastServerRevisionId: parsed.lastServerRevisionId ?? null,
|
|
21478
|
+
lastServerTreeHash: parsed.lastServerTreeHash ?? null,
|
|
21475
21479
|
lastServerHeadHash: parsed.lastServerHeadHash ?? null,
|
|
21476
21480
|
lastSeenLocalCommitHash: parsed.lastSeenLocalCommitHash ?? null,
|
|
21477
21481
|
updatedAt: String(parsed.updatedAt ?? "")
|
|
@@ -21483,7 +21487,7 @@ async function readLocalBaseline(params) {
|
|
|
21483
21487
|
async function writeLocalBaseline(baseline) {
|
|
21484
21488
|
const key = buildLaneStateKey(baseline);
|
|
21485
21489
|
const normalized = {
|
|
21486
|
-
schemaVersion:
|
|
21490
|
+
schemaVersion: 2,
|
|
21487
21491
|
key,
|
|
21488
21492
|
repoRoot: baseline.repoRoot,
|
|
21489
21493
|
repoFingerprint: baseline.repoFingerprint ?? null,
|
|
@@ -21492,6 +21496,8 @@ async function writeLocalBaseline(baseline) {
|
|
|
21492
21496
|
branchName: baseline.branchName ?? null,
|
|
21493
21497
|
lastSnapshotId: baseline.lastSnapshotId ?? null,
|
|
21494
21498
|
lastSnapshotHash: baseline.lastSnapshotHash ?? null,
|
|
21499
|
+
lastServerRevisionId: baseline.lastServerRevisionId ?? null,
|
|
21500
|
+
lastServerTreeHash: baseline.lastServerTreeHash ?? null,
|
|
21495
21501
|
lastServerHeadHash: baseline.lastServerHeadHash ?? null,
|
|
21496
21502
|
lastSeenLocalCommitHash: baseline.lastSeenLocalCommitHash ?? null,
|
|
21497
21503
|
updatedAt: baseline.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -21833,6 +21839,7 @@ function normalizeJob2(input) {
|
|
|
21833
21839
|
prompt: input.prompt,
|
|
21834
21840
|
assistantResponse: input.assistantResponse,
|
|
21835
21841
|
baselineSnapshotId: input.baselineSnapshotId ?? null,
|
|
21842
|
+
baselineServerRevisionId: input.baselineServerRevisionId ?? null,
|
|
21836
21843
|
baselineServerHeadHash: input.baselineServerHeadHash ?? null,
|
|
21837
21844
|
currentSnapshotId: input.currentSnapshotId,
|
|
21838
21845
|
capturedAt: input.capturedAt ?? now,
|
|
@@ -21862,6 +21869,7 @@ async function readPendingFinalizeJob(jobId) {
|
|
|
21862
21869
|
prompt: String(parsed.prompt ?? ""),
|
|
21863
21870
|
assistantResponse: String(parsed.assistantResponse ?? ""),
|
|
21864
21871
|
baselineSnapshotId: parsed.baselineSnapshotId ?? null,
|
|
21872
|
+
baselineServerRevisionId: parsed.baselineServerRevisionId ?? null,
|
|
21865
21873
|
baselineServerHeadHash: parsed.baselineServerHeadHash ?? null,
|
|
21866
21874
|
currentSnapshotId: String(parsed.currentSnapshotId ?? ""),
|
|
21867
21875
|
capturedAt: parsed.capturedAt,
|
|
@@ -22588,6 +22596,8 @@ function buildBaseState() {
|
|
|
22588
22596
|
branchName: null,
|
|
22589
22597
|
localCommitHash: null,
|
|
22590
22598
|
currentSnapshotHash: null,
|
|
22599
|
+
currentServerRevisionId: null,
|
|
22600
|
+
currentServerTreeHash: null,
|
|
22591
22601
|
currentServerHeadHash: null,
|
|
22592
22602
|
currentServerHeadCommitId: null,
|
|
22593
22603
|
worktreeClean: false,
|
|
@@ -22621,6 +22631,8 @@ function buildBaseState() {
|
|
|
22621
22631
|
baseline: {
|
|
22622
22632
|
lastSnapshotId: null,
|
|
22623
22633
|
lastSnapshotHash: null,
|
|
22634
|
+
lastServerRevisionId: null,
|
|
22635
|
+
lastServerTreeHash: null,
|
|
22624
22636
|
lastServerHeadHash: null,
|
|
22625
22637
|
lastSeenLocalCommitHash: null
|
|
22626
22638
|
}
|
|
@@ -22747,6 +22759,8 @@ async function collabDetectRepoState(params) {
|
|
|
22747
22759
|
summarizeAsyncJobs({ repoRoot, branchName: binding.branchName ?? null })
|
|
22748
22760
|
]);
|
|
22749
22761
|
const appHead = unwrapResponseObject(headResp, "app head");
|
|
22762
|
+
detected.currentServerRevisionId = appHead.headRevisionId ?? null;
|
|
22763
|
+
detected.currentServerTreeHash = appHead.treeHash ?? null;
|
|
22750
22764
|
detected.currentServerHeadHash = appHead.headCommitHash;
|
|
22751
22765
|
detected.currentServerHeadCommitId = appHead.headCommitId;
|
|
22752
22766
|
detected.currentSnapshotHash = inspection.snapshotHash;
|
|
@@ -22755,6 +22769,8 @@ async function collabDetectRepoState(params) {
|
|
|
22755
22769
|
detected.baseline = {
|
|
22756
22770
|
lastSnapshotId: baseline?.lastSnapshotId ?? null,
|
|
22757
22771
|
lastSnapshotHash: baseline?.lastSnapshotHash ?? null,
|
|
22772
|
+
lastServerRevisionId: baseline?.lastServerRevisionId ?? null,
|
|
22773
|
+
lastServerTreeHash: baseline?.lastServerTreeHash ?? null,
|
|
22758
22774
|
lastServerHeadHash: baseline?.lastServerHeadHash ?? null,
|
|
22759
22775
|
lastSeenLocalCommitHash: baseline?.lastSeenLocalCommitHash ?? null
|
|
22760
22776
|
};
|
|
@@ -22764,6 +22780,7 @@ async function collabDetectRepoState(params) {
|
|
|
22764
22780
|
const bootstrapResp = await params.api.getAppDelta(binding.currentAppId, {
|
|
22765
22781
|
baseHeadHash: localCommitHash,
|
|
22766
22782
|
targetHeadHash: appHead.headCommitHash,
|
|
22783
|
+
targetRevisionId: appHead.headRevisionId,
|
|
22767
22784
|
repoFingerprint: binding.repoFingerprint ?? void 0,
|
|
22768
22785
|
remoteUrl: binding.remoteUrl ?? void 0,
|
|
22769
22786
|
defaultBranch: binding.defaultBranch ?? void 0
|
|
@@ -22786,7 +22803,7 @@ async function collabDetectRepoState(params) {
|
|
|
22786
22803
|
}
|
|
22787
22804
|
}
|
|
22788
22805
|
detected.repoState = "external_local_base_changed";
|
|
22789
|
-
detected.hint = "No local Remix baseline exists for this lane yet. Run `remix collab
|
|
22806
|
+
detected.hint = "No local Remix revision baseline exists for this lane yet. Run `remix collab init` or sync this lane to seed the baseline.";
|
|
22790
22807
|
return detected;
|
|
22791
22808
|
}
|
|
22792
22809
|
const localHeadMovedSinceBaseline = Boolean(baseline.lastSeenLocalCommitHash) && localCommitHash !== baseline.lastSeenLocalCommitHash;
|
|
@@ -22805,7 +22822,30 @@ async function collabDetectRepoState(params) {
|
|
|
22805
22822
|
return detected;
|
|
22806
22823
|
}
|
|
22807
22824
|
const localChanged = inspection.snapshotHash !== baseline.lastSnapshotHash;
|
|
22808
|
-
const
|
|
22825
|
+
const serverHeadChanged = appHead.headCommitHash !== baseline.lastServerHeadHash;
|
|
22826
|
+
const revisionChanged = Boolean(
|
|
22827
|
+
baseline.lastServerRevisionId && (appHead.headRevisionId ?? null) !== baseline.lastServerRevisionId
|
|
22828
|
+
);
|
|
22829
|
+
const equivalentRevisionDrift = revisionChanged && !serverHeadChanged;
|
|
22830
|
+
if (equivalentRevisionDrift) {
|
|
22831
|
+
await writeLocalBaseline({
|
|
22832
|
+
repoRoot,
|
|
22833
|
+
repoFingerprint: binding.repoFingerprint,
|
|
22834
|
+
laneId: binding.laneId,
|
|
22835
|
+
currentAppId: binding.currentAppId,
|
|
22836
|
+
branchName: binding.branchName,
|
|
22837
|
+
lastSnapshotId: baseline.lastSnapshotId,
|
|
22838
|
+
lastSnapshotHash: baseline.lastSnapshotHash,
|
|
22839
|
+
lastServerRevisionId: appHead.headRevisionId ?? null,
|
|
22840
|
+
lastServerTreeHash: appHead.treeHash ?? baseline.lastServerTreeHash ?? null,
|
|
22841
|
+
lastServerHeadHash: appHead.headCommitHash,
|
|
22842
|
+
lastSeenLocalCommitHash: baseline.lastSeenLocalCommitHash
|
|
22843
|
+
});
|
|
22844
|
+
detected.baseline.lastServerRevisionId = appHead.headRevisionId ?? null;
|
|
22845
|
+
detected.baseline.lastServerTreeHash = appHead.treeHash ?? baseline.lastServerTreeHash ?? null;
|
|
22846
|
+
detected.baseline.lastServerHeadHash = appHead.headCommitHash;
|
|
22847
|
+
}
|
|
22848
|
+
const serverChanged = serverHeadChanged;
|
|
22809
22849
|
if (!localChanged && !serverChanged) {
|
|
22810
22850
|
detected.repoState = "idle";
|
|
22811
22851
|
return detected;
|
|
@@ -23229,6 +23269,7 @@ function buildWorkspaceMetadata(params) {
|
|
|
23229
23269
|
recordingMode: "boundary_delta",
|
|
23230
23270
|
baselineSnapshotId: params.baselineSnapshotId,
|
|
23231
23271
|
currentSnapshotId: params.currentSnapshotId,
|
|
23272
|
+
baselineServerRevisionId: params.baselineServerRevisionId ?? null,
|
|
23232
23273
|
baselineServerHeadHash: params.baselineServerHeadHash,
|
|
23233
23274
|
currentSnapshotHash: params.currentSnapshotHash,
|
|
23234
23275
|
localCommitHash: params.localCommitHash,
|
|
@@ -23307,12 +23348,12 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23307
23348
|
throw buildFinalizeCliError({
|
|
23308
23349
|
message: "Local baseline is missing for this queued finalize job.",
|
|
23309
23350
|
exitCode: 2,
|
|
23310
|
-
hint: "Run `remix collab
|
|
23351
|
+
hint: "Run `remix collab init` to seed this checkout's revision baseline.",
|
|
23311
23352
|
disposition: "terminal",
|
|
23312
23353
|
reason: "baseline_missing"
|
|
23313
23354
|
});
|
|
23314
23355
|
}
|
|
23315
|
-
const baselineDrifted = baseline.lastSnapshotId !== job.baselineSnapshotId || baseline.lastServerHeadHash !== job.baselineServerHeadHash;
|
|
23356
|
+
const baselineDrifted = baseline.lastSnapshotId !== job.baselineSnapshotId || (job.baselineServerRevisionId ? baseline.lastServerRevisionId !== job.baselineServerRevisionId : false) || baseline.lastServerHeadHash !== job.baselineServerHeadHash;
|
|
23316
23357
|
const appHead = unwrapResponseObject(appHeadResp, "app head");
|
|
23317
23358
|
const remoteUrl = readMetadataString(job, "remoteUrl");
|
|
23318
23359
|
const defaultBranch = readMetadataString(job, "defaultBranch");
|
|
@@ -23335,12 +23376,13 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23335
23376
|
throw buildFinalizeCliError({
|
|
23336
23377
|
message: "Finalize queue baseline drifted before this job was processed.",
|
|
23337
23378
|
exitCode: 1,
|
|
23338
|
-
hint: "Process queued finalize jobs in capture order, or
|
|
23379
|
+
hint: "Process queued finalize jobs in capture order, or run `remix collab init` to refresh the revision baseline before retrying.",
|
|
23339
23380
|
disposition: "terminal",
|
|
23340
23381
|
reason: "baseline_drifted"
|
|
23341
23382
|
});
|
|
23342
23383
|
}
|
|
23343
|
-
|
|
23384
|
+
const serverStillAtBaseline = job.baselineServerRevisionId ? appHead.headRevisionId === job.baselineServerRevisionId : appHead.headCommitHash === job.baselineServerHeadHash;
|
|
23385
|
+
if (!serverStillAtBaseline) {
|
|
23344
23386
|
throw buildFinalizeCliError({
|
|
23345
23387
|
message: "Server lane changed before a no-diff turn could be recorded.",
|
|
23346
23388
|
exitCode: 2,
|
|
@@ -23362,6 +23404,7 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23362
23404
|
defaultBranch,
|
|
23363
23405
|
baselineSnapshotId: job.baselineSnapshotId,
|
|
23364
23406
|
currentSnapshotId: job.currentSnapshotId,
|
|
23407
|
+
baselineServerRevisionId: job.baselineServerRevisionId,
|
|
23365
23408
|
baselineServerHeadHash: job.baselineServerHeadHash,
|
|
23366
23409
|
currentSnapshotHash: snapshot.snapshotHash,
|
|
23367
23410
|
localCommitHash: snapshot.localCommitHash,
|
|
@@ -23382,6 +23425,8 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23382
23425
|
branchName: job.branchName,
|
|
23383
23426
|
lastSnapshotId: snapshot.id,
|
|
23384
23427
|
lastSnapshotHash: snapshot.snapshotHash,
|
|
23428
|
+
lastServerRevisionId: appHead.headRevisionId ?? null,
|
|
23429
|
+
lastServerTreeHash: appHead.treeHash ?? null,
|
|
23385
23430
|
lastServerHeadHash: appHead.headCommitHash,
|
|
23386
23431
|
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
23387
23432
|
});
|
|
@@ -23402,14 +23447,14 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23402
23447
|
};
|
|
23403
23448
|
}
|
|
23404
23449
|
const localBaselineAdvanced = baseline.lastSnapshotId !== job.baselineSnapshotId;
|
|
23405
|
-
const serverHeadAdvanced = appHead.headCommitHash !== job.baselineServerHeadHash;
|
|
23450
|
+
const serverHeadAdvanced = job.baselineServerRevisionId ? appHead.headRevisionId !== job.baselineServerRevisionId : appHead.headCommitHash !== job.baselineServerHeadHash;
|
|
23406
23451
|
if (baselineDrifted) {
|
|
23407
23452
|
const consistentAdvance = localBaselineAdvanced && serverHeadAdvanced;
|
|
23408
23453
|
if (!consistentAdvance) {
|
|
23409
23454
|
throw buildFinalizeCliError({
|
|
23410
23455
|
message: `Finalize queue baseline advanced inconsistently before this job was processed (localBaselineAdvanced=${localBaselineAdvanced}, serverHeadAdvanced=${serverHeadAdvanced}, jobBaselineSnapshotId=${job.baselineSnapshotId ?? "null"}, liveBaselineSnapshotId=${baseline.lastSnapshotId ?? "null"}, jobBaselineServerHeadHash=${job.baselineServerHeadHash ?? "null"}, liveBaselineServerHeadHash=${baseline.lastServerHeadHash ?? "null"}, currentAppHeadHash=${appHead.headCommitHash}). This indicates local Remix state diverged from the backend in a way that should not be reachable in normal operation; please report this as a bug.`,
|
|
23411
23456
|
exitCode: 1,
|
|
23412
|
-
hint: "Run `remix collab status` to inspect, then
|
|
23457
|
+
hint: "Run `remix collab status` to inspect, then sync or reconcile before retrying.",
|
|
23413
23458
|
disposition: "terminal",
|
|
23414
23459
|
reason: "baseline_drifted"
|
|
23415
23460
|
});
|
|
@@ -23417,6 +23462,7 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23417
23462
|
}
|
|
23418
23463
|
let submissionDiff = diffResult.diff;
|
|
23419
23464
|
let submissionBaseHeadHash = job.baselineServerHeadHash;
|
|
23465
|
+
let submissionBaseRevisionId = job.baselineServerRevisionId;
|
|
23420
23466
|
let replayedFromBaseHash = null;
|
|
23421
23467
|
if (!submissionBaseHeadHash) {
|
|
23422
23468
|
throw buildFinalizeCliError({
|
|
@@ -23434,7 +23480,9 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23434
23480
|
assistantResponse: job.assistantResponse,
|
|
23435
23481
|
diff: diffResult.diff,
|
|
23436
23482
|
baseCommitHash: submissionBaseHeadHash,
|
|
23483
|
+
baseRevisionId: job.baselineServerRevisionId,
|
|
23437
23484
|
targetHeadCommitHash: appHead.headCommitHash,
|
|
23485
|
+
targetRevisionId: appHead.headRevisionId,
|
|
23438
23486
|
expectedPaths: diffResult.changedPaths,
|
|
23439
23487
|
actor,
|
|
23440
23488
|
workspaceMetadata: buildWorkspaceMetadata({
|
|
@@ -23444,6 +23492,7 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23444
23492
|
defaultBranch,
|
|
23445
23493
|
baselineSnapshotId: job.baselineSnapshotId,
|
|
23446
23494
|
currentSnapshotId: job.currentSnapshotId,
|
|
23495
|
+
baselineServerRevisionId: job.baselineServerRevisionId,
|
|
23447
23496
|
baselineServerHeadHash: job.baselineServerHeadHash,
|
|
23448
23497
|
currentSnapshotHash: snapshot.snapshotHash,
|
|
23449
23498
|
localCommitHash: snapshot.localCommitHash,
|
|
@@ -23469,6 +23518,7 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23469
23518
|
submissionDiff = replayDiff.diff;
|
|
23470
23519
|
replayedFromBaseHash = submissionBaseHeadHash;
|
|
23471
23520
|
submissionBaseHeadHash = appHead.headCommitHash;
|
|
23521
|
+
submissionBaseRevisionId = appHead.headRevisionId;
|
|
23472
23522
|
} catch (error2) {
|
|
23473
23523
|
if (error2 instanceof RemixError && error2.finalizeDisposition === void 0) {
|
|
23474
23524
|
const detail = error2.hint ? `${error2.message} (${error2.hint})` : error2.message;
|
|
@@ -23490,6 +23540,7 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23490
23540
|
assistantResponse: job.assistantResponse,
|
|
23491
23541
|
diff: submissionDiff,
|
|
23492
23542
|
baseCommitHash: submissionBaseHeadHash,
|
|
23543
|
+
baseRevisionId: submissionBaseRevisionId,
|
|
23493
23544
|
headCommitHash: submissionBaseHeadHash,
|
|
23494
23545
|
changedFilesCount: diffResult.stats.changedFilesCount,
|
|
23495
23546
|
insertions: diffResult.stats.insertions,
|
|
@@ -23502,6 +23553,7 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23502
23553
|
defaultBranch,
|
|
23503
23554
|
baselineSnapshotId: job.baselineSnapshotId,
|
|
23504
23555
|
currentSnapshotId: job.currentSnapshotId,
|
|
23556
|
+
baselineServerRevisionId: job.baselineServerRevisionId,
|
|
23505
23557
|
baselineServerHeadHash: job.baselineServerHeadHash,
|
|
23506
23558
|
currentSnapshotHash: snapshot.snapshotHash,
|
|
23507
23559
|
localCommitHash: snapshot.localCommitHash,
|
|
@@ -23523,11 +23575,28 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23523
23575
|
throw buildFinalizeCliError({
|
|
23524
23576
|
message: "Backend returned a succeeded change step without a head commit hash.",
|
|
23525
23577
|
exitCode: 1,
|
|
23526
|
-
hint: "This is a backend invariant violation; retry will not help.
|
|
23578
|
+
hint: "This is a backend invariant violation; retry will not help. Run `remix collab status` before trying again.",
|
|
23527
23579
|
disposition: "terminal",
|
|
23528
23580
|
reason: "missing_head_commit_hash"
|
|
23529
23581
|
});
|
|
23530
23582
|
}
|
|
23583
|
+
let nextServerRevisionId = typeof changeStep.resultRevisionId === "string" ? changeStep.resultRevisionId.trim() : "";
|
|
23584
|
+
let nextServerTreeHash = null;
|
|
23585
|
+
if (!nextServerRevisionId) {
|
|
23586
|
+
const freshHeadResp = await params.api.getAppHead(job.currentAppId);
|
|
23587
|
+
const freshHead = unwrapResponseObject(freshHeadResp, "app head");
|
|
23588
|
+
if (freshHead.headCommitHash !== nextServerHeadHash || !freshHead.headRevisionId) {
|
|
23589
|
+
throw buildFinalizeCliError({
|
|
23590
|
+
message: "Backend returned a succeeded change step without a matching result revision.",
|
|
23591
|
+
exitCode: 1,
|
|
23592
|
+
hint: "The local baseline was not advanced because the post-step revision could not be verified. Restart the backend/CLI and retry after checking `remix collab status`.",
|
|
23593
|
+
disposition: "terminal",
|
|
23594
|
+
reason: "missing_result_revision_id"
|
|
23595
|
+
});
|
|
23596
|
+
}
|
|
23597
|
+
nextServerRevisionId = freshHead.headRevisionId;
|
|
23598
|
+
nextServerTreeHash = freshHead.treeHash ?? null;
|
|
23599
|
+
}
|
|
23531
23600
|
await writeLocalBaseline({
|
|
23532
23601
|
repoRoot: job.repoRoot,
|
|
23533
23602
|
repoFingerprint: job.repoFingerprint,
|
|
@@ -23536,6 +23605,8 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23536
23605
|
branchName: job.branchName,
|
|
23537
23606
|
lastSnapshotId: snapshot.id,
|
|
23538
23607
|
lastSnapshotHash: snapshot.snapshotHash,
|
|
23608
|
+
lastServerRevisionId: nextServerRevisionId,
|
|
23609
|
+
lastServerTreeHash: nextServerTreeHash,
|
|
23539
23610
|
lastServerHeadHash: nextServerHeadHash,
|
|
23540
23611
|
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
23541
23612
|
});
|
|
@@ -23596,9 +23667,10 @@ var FINALIZE_PREFLIGHT_FAILURE_CODES = [
|
|
|
23596
23667
|
// Server has commits we don't. Fix: `remix collab sync` (safe to
|
|
23597
23668
|
// auto-run for fast-forward; non-FF refused by the command itself).
|
|
23598
23669
|
"pull_required",
|
|
23599
|
-
//
|
|
23600
|
-
|
|
23601
|
-
|
|
23670
|
+
// Both local and server changed. Fix: inspect and apply reconcile.
|
|
23671
|
+
"reconcile_required",
|
|
23672
|
+
// Local revision baseline is missing. Fix: `remix collab init` or sync.
|
|
23673
|
+
"baseline_missing"
|
|
23602
23674
|
];
|
|
23603
23675
|
var CODE_SET = new Set(FINALIZE_PREFLIGHT_FAILURE_CODES);
|
|
23604
23676
|
var DEFAULT_ACQUIRE_TIMEOUT_MS = 15e3;
|
|
@@ -23818,7 +23890,7 @@ async function ensureWorkspaceMatchesBaseline(params) {
|
|
|
23818
23890
|
if (!baseline?.lastSnapshotHash || !baseline.lastServerHeadHash) {
|
|
23819
23891
|
throw new RemixError("Local Remix baseline is missing for this lane.", {
|
|
23820
23892
|
exitCode: 2,
|
|
23821
|
-
hint: "Run `remix collab
|
|
23893
|
+
hint: "Run `remix collab init` or sync from a checkout with a valid revision baseline before applying server changes."
|
|
23822
23894
|
});
|
|
23823
23895
|
}
|
|
23824
23896
|
const inspection = await inspectLocalSnapshot({
|
|
@@ -23890,11 +23962,12 @@ async function collabSync(params) {
|
|
|
23890
23962
|
const repoSnapshot = await captureRepoSnapshot(repoRoot, { includeWorkspaceDiffHash: true });
|
|
23891
23963
|
const bootstrapFromLocalHead = !detected.baseline.lastSnapshotHash || !detected.baseline.lastServerHeadHash;
|
|
23892
23964
|
let baselineServerHeadHash;
|
|
23965
|
+
let baselineServerRevisionId = null;
|
|
23893
23966
|
if (bootstrapFromLocalHead) {
|
|
23894
23967
|
if (!headCommitHash) {
|
|
23895
23968
|
throw new RemixError("Failed to resolve local HEAD commit for the initial sync bootstrap.", {
|
|
23896
23969
|
exitCode: 1,
|
|
23897
|
-
hint: "Retry after Git HEAD is available, or run `remix collab
|
|
23970
|
+
hint: "Retry after Git HEAD is available, or run `remix collab init` to seed this checkout's revision baseline."
|
|
23898
23971
|
});
|
|
23899
23972
|
}
|
|
23900
23973
|
baselineServerHeadHash = headCommitHash;
|
|
@@ -23909,13 +23982,15 @@ async function collabSync(params) {
|
|
|
23909
23982
|
if (!baseline.lastServerHeadHash) {
|
|
23910
23983
|
throw new RemixError("Local Remix baseline is missing the last acknowledged server head.", {
|
|
23911
23984
|
exitCode: 2,
|
|
23912
|
-
hint: "Run `remix collab
|
|
23985
|
+
hint: "Run `remix collab init` or sync from a checkout with a valid revision baseline before pulling server changes."
|
|
23913
23986
|
});
|
|
23914
23987
|
}
|
|
23915
23988
|
baselineServerHeadHash = baseline.lastServerHeadHash;
|
|
23989
|
+
baselineServerRevisionId = baseline.lastServerRevisionId;
|
|
23916
23990
|
}
|
|
23917
23991
|
const deltaResp = await params.api.getAppDelta(binding.currentAppId, {
|
|
23918
23992
|
baseHeadHash: baselineServerHeadHash,
|
|
23993
|
+
baseRevisionId: baselineServerRevisionId,
|
|
23919
23994
|
repoFingerprint: binding.repoFingerprint ?? void 0,
|
|
23920
23995
|
remoteUrl: binding.remoteUrl ?? void 0,
|
|
23921
23996
|
defaultBranch: binding.defaultBranch ?? void 0
|
|
@@ -23939,13 +24014,54 @@ async function collabSync(params) {
|
|
|
23939
24014
|
applied: false,
|
|
23940
24015
|
dryRun: params.dryRun
|
|
23941
24016
|
};
|
|
23942
|
-
if (params.dryRun
|
|
24017
|
+
if (params.dryRun) {
|
|
23943
24018
|
return previewResult;
|
|
23944
24019
|
}
|
|
24020
|
+
if (delta.status === "up_to_date") {
|
|
24021
|
+
if (!bootstrapFromLocalHead) {
|
|
24022
|
+
return previewResult;
|
|
24023
|
+
}
|
|
24024
|
+
return withRepoMutationLock(
|
|
24025
|
+
{
|
|
24026
|
+
cwd: repoRoot,
|
|
24027
|
+
operation: "collabSync"
|
|
24028
|
+
},
|
|
24029
|
+
async ({ repoRoot: lockedRepoRoot, warnings }) => {
|
|
24030
|
+
await assertRepoSnapshotUnchanged(lockedRepoRoot, repoSnapshot, {
|
|
24031
|
+
operation: "`remix collab sync`",
|
|
24032
|
+
recoveryHint: "The repository changed before the first local Remix baseline could be created. Review the local changes and rerun `remix collab sync`."
|
|
24033
|
+
});
|
|
24034
|
+
const snapshot = await captureLocalSnapshot({
|
|
24035
|
+
repoRoot: lockedRepoRoot,
|
|
24036
|
+
repoFingerprint: binding.repoFingerprint,
|
|
24037
|
+
laneId: binding.laneId,
|
|
24038
|
+
branchName: binding.branchName
|
|
24039
|
+
});
|
|
24040
|
+
await writeLocalBaseline({
|
|
24041
|
+
repoRoot: lockedRepoRoot,
|
|
24042
|
+
repoFingerprint: binding.repoFingerprint,
|
|
24043
|
+
laneId: binding.laneId,
|
|
24044
|
+
currentAppId: binding.currentAppId,
|
|
24045
|
+
branchName: binding.branchName,
|
|
24046
|
+
lastSnapshotId: snapshot.id,
|
|
24047
|
+
lastSnapshotHash: snapshot.snapshotHash,
|
|
24048
|
+
lastServerRevisionId: delta.targetRevisionId ?? null,
|
|
24049
|
+
lastServerTreeHash: delta.targetTreeHash ?? null,
|
|
24050
|
+
lastServerHeadHash: delta.targetHeadHash,
|
|
24051
|
+
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
24052
|
+
});
|
|
24053
|
+
return {
|
|
24054
|
+
...previewResult,
|
|
24055
|
+
localCommitHash: snapshot.localCommitHash,
|
|
24056
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
24057
|
+
};
|
|
24058
|
+
}
|
|
24059
|
+
);
|
|
24060
|
+
}
|
|
23945
24061
|
if (delta.status === "base_unknown") {
|
|
23946
24062
|
throw new RemixError("Direct pull is unavailable because Remix can no longer diff from the last acknowledged server head.", {
|
|
23947
24063
|
exitCode: 2,
|
|
23948
|
-
hint: "Run `remix collab reconcile --dry-run` to inspect recovery options before retrying. If this checkout has no local Remix baseline yet for this lane, `remix collab
|
|
24064
|
+
hint: "Run `remix collab reconcile --dry-run` to inspect recovery options before retrying. If this checkout has no local Remix baseline yet for this lane, run `remix collab init` to seed one."
|
|
23949
24065
|
});
|
|
23950
24066
|
}
|
|
23951
24067
|
if (delta.status !== "delta_ready") {
|
|
@@ -23989,6 +24105,8 @@ async function collabSync(params) {
|
|
|
23989
24105
|
branchName: binding.branchName,
|
|
23990
24106
|
lastSnapshotId: snapshot.id,
|
|
23991
24107
|
lastSnapshotHash: snapshot.snapshotHash,
|
|
24108
|
+
lastServerRevisionId: delta.targetRevisionId ?? null,
|
|
24109
|
+
lastServerTreeHash: delta.targetTreeHash ?? null,
|
|
23992
24110
|
lastServerHeadHash: delta.targetHeadHash,
|
|
23993
24111
|
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
23994
24112
|
});
|
|
@@ -24274,6 +24392,8 @@ async function collabCheckout(params) {
|
|
|
24274
24392
|
branchName: branchNameForBaseline,
|
|
24275
24393
|
lastSnapshotId: snapshot.id,
|
|
24276
24394
|
lastSnapshotHash: snapshot.snapshotHash,
|
|
24395
|
+
lastServerRevisionId: appHead.headRevisionId ?? null,
|
|
24396
|
+
lastServerTreeHash: appHead.treeHash ?? null,
|
|
24277
24397
|
lastServerHeadHash: appHead.headCommitHash,
|
|
24278
24398
|
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
24279
24399
|
});
|
|
@@ -24648,6 +24768,8 @@ async function trySeedEquivalentBranchBaseline(params) {
|
|
|
24648
24768
|
branchName: params.branchName,
|
|
24649
24769
|
lastSnapshotId: snapshot.id,
|
|
24650
24770
|
lastSnapshotHash: snapshot.snapshotHash,
|
|
24771
|
+
lastServerRevisionId: params.appHeadRevisionId,
|
|
24772
|
+
lastServerTreeHash: params.appTreeHash,
|
|
24651
24773
|
lastServerHeadHash: params.appHeadHash,
|
|
24652
24774
|
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
24653
24775
|
});
|
|
@@ -24659,11 +24781,11 @@ async function resolveInitBaselineStatus(params) {
|
|
|
24659
24781
|
laneId: params.laneId,
|
|
24660
24782
|
repoRoot: params.repoRoot
|
|
24661
24783
|
});
|
|
24662
|
-
if (baseline?.lastSnapshotHash && baseline.lastServerHeadHash) {
|
|
24784
|
+
if (baseline?.lastSnapshotHash && (baseline.lastServerRevisionId || baseline.lastServerHeadHash)) {
|
|
24663
24785
|
return "existing";
|
|
24664
24786
|
}
|
|
24665
24787
|
const localHeadCommitHash = await getHeadCommitHash(params.repoRoot);
|
|
24666
|
-
if (!localHeadCommitHash) return "
|
|
24788
|
+
if (!localHeadCommitHash) return "baseline_missing";
|
|
24667
24789
|
const appHead = unwrapResponseObject(
|
|
24668
24790
|
await params.api.getAppHead(params.currentAppId),
|
|
24669
24791
|
"app head"
|
|
@@ -24690,6 +24812,7 @@ async function resolveInitBaselineStatus(params) {
|
|
|
24690
24812
|
const deltaResp = await params.api.getAppDelta(params.currentAppId, {
|
|
24691
24813
|
baseHeadHash: localHeadCommitHash,
|
|
24692
24814
|
targetHeadHash: appHead.headCommitHash,
|
|
24815
|
+
targetRevisionId: appHead.headRevisionId,
|
|
24693
24816
|
localSnapshotHash,
|
|
24694
24817
|
repoFingerprint: params.repoFingerprint,
|
|
24695
24818
|
remoteUrl: params.remoteUrl ?? void 0,
|
|
@@ -24719,7 +24842,9 @@ async function resolveInitBaselineStatus(params) {
|
|
|
24719
24842
|
upstreamAppId: params.upstreamAppId ?? null,
|
|
24720
24843
|
branchName: params.branchName,
|
|
24721
24844
|
defaultBranch: params.defaultBranch,
|
|
24722
|
-
appHeadHash: appHead.headCommitHash
|
|
24845
|
+
appHeadHash: appHead.headCommitHash,
|
|
24846
|
+
appHeadRevisionId: appHead.headRevisionId ?? null,
|
|
24847
|
+
appTreeHash: appHead.treeHash ?? null
|
|
24723
24848
|
});
|
|
24724
24849
|
if (equivalentBaseline) {
|
|
24725
24850
|
return equivalentBaseline;
|
|
@@ -24727,7 +24852,7 @@ async function resolveInitBaselineStatus(params) {
|
|
|
24727
24852
|
}
|
|
24728
24853
|
} catch {
|
|
24729
24854
|
}
|
|
24730
|
-
return "
|
|
24855
|
+
return "baseline_missing";
|
|
24731
24856
|
}
|
|
24732
24857
|
async function seedImportedInitBaseline(params) {
|
|
24733
24858
|
const appHead = unwrapResponseObject(
|
|
@@ -24748,6 +24873,8 @@ async function seedImportedInitBaseline(params) {
|
|
|
24748
24873
|
branchName: params.branchName,
|
|
24749
24874
|
lastSnapshotId: snapshot.id,
|
|
24750
24875
|
lastSnapshotHash: snapshot.snapshotHash,
|
|
24876
|
+
lastServerRevisionId: appHead.headRevisionId ?? null,
|
|
24877
|
+
lastServerTreeHash: appHead.treeHash ?? null,
|
|
24751
24878
|
lastServerHeadHash: appHead.headCommitHash,
|
|
24752
24879
|
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
24753
24880
|
});
|
|
@@ -24761,7 +24888,6 @@ async function collabInit(params) {
|
|
|
24761
24888
|
},
|
|
24762
24889
|
async ({ repoRoot, warnings }) => {
|
|
24763
24890
|
await ensureGitInfoExcludeEntries(repoRoot, [".remix/"]);
|
|
24764
|
-
await ensureCleanWorktree(repoRoot, "`remix collab init`");
|
|
24765
24891
|
if (params.path?.trim()) {
|
|
24766
24892
|
throw new RemixError("`remix collab init --path` is not supported.", {
|
|
24767
24893
|
exitCode: 2,
|
|
@@ -24769,6 +24895,10 @@ async function collabInit(params) {
|
|
|
24769
24895
|
});
|
|
24770
24896
|
}
|
|
24771
24897
|
const localBindingState = await readCollabBindingState(repoRoot, { persist: true });
|
|
24898
|
+
const hasExistingBinding = localBindingState != null && Object.keys(localBindingState.branchBindings ?? {}).length > 0;
|
|
24899
|
+
if (params.forceNew || !hasExistingBinding) {
|
|
24900
|
+
await ensureCleanWorktree(repoRoot, "`remix collab init`");
|
|
24901
|
+
}
|
|
24772
24902
|
const persistedRemoteUrl = normalizeGitRemote(localBindingState?.remoteUrl ?? null);
|
|
24773
24903
|
const currentBranch = await getCurrentBranch(repoRoot);
|
|
24774
24904
|
const defaultBranch = localBindingState?.defaultBranch ?? await getDefaultBranch(repoRoot) ?? currentBranch;
|
|
@@ -25285,7 +25415,7 @@ async function collabInit(params) {
|
|
|
25285
25415
|
operation: "`remix collab init`",
|
|
25286
25416
|
recoveryHint: "The repository changed before the Remix binding was written. Review the local changes and rerun `remix collab init`."
|
|
25287
25417
|
});
|
|
25288
|
-
const bindingMode2 =
|
|
25418
|
+
const bindingMode2 = defaultBranch && branchName !== defaultBranch ? "lane" : "explicit_root";
|
|
25289
25419
|
let bindingPath2;
|
|
25290
25420
|
if (params.forceNew && defaultBranch && canonicalLane2) {
|
|
25291
25421
|
const canonicalBinding = branchBindingFromLane(canonicalLane2, "explicit_root", {
|
|
@@ -25327,7 +25457,15 @@ async function collabInit(params) {
|
|
|
25327
25457
|
defaultBranch: canonicalLane2.defaultBranch ?? defaultBranch,
|
|
25328
25458
|
laneId: canonicalLane2.laneId ?? null,
|
|
25329
25459
|
branchName: defaultBranch,
|
|
25330
|
-
|
|
25460
|
+
// This branch is reached only when the CURRENT branch is
|
|
25461
|
+
// not the default branch — so the binding being written
|
|
25462
|
+
// here is for the DEFAULT branch (the canonical/main app).
|
|
25463
|
+
// It must always be `explicit_root` regardless of
|
|
25464
|
+
// `forceNew`; the previous `forceNew ? ... : "lane"`
|
|
25465
|
+
// produced a `lane`-marked default-branch binding for
|
|
25466
|
+
// every plain init, which silently disabled the
|
|
25467
|
+
// history-import auto-spawn.
|
|
25468
|
+
bindingMode: "explicit_root"
|
|
25331
25469
|
});
|
|
25332
25470
|
}
|
|
25333
25471
|
bindingPath2 = await writeCollabBinding(repoRoot, {
|
|
@@ -25479,7 +25617,7 @@ async function collabInit(params) {
|
|
|
25479
25617
|
operation: "`remix collab init`",
|
|
25480
25618
|
recoveryHint: "The repository changed before the Remix binding was written. Review the local changes and rerun `remix collab init`."
|
|
25481
25619
|
});
|
|
25482
|
-
const bindingMode =
|
|
25620
|
+
const bindingMode = defaultBranch && branchName !== defaultBranch ? "lane" : "explicit_root";
|
|
25483
25621
|
let bindingPath;
|
|
25484
25622
|
if (params.forceNew && defaultBranch && canonicalLane) {
|
|
25485
25623
|
const canonicalBinding = branchBindingFromLane(canonicalLane, "explicit_root", {
|
|
@@ -25521,7 +25659,12 @@ async function collabInit(params) {
|
|
|
25521
25659
|
defaultBranch: canonicalLane.defaultBranch ?? defaultBranch,
|
|
25522
25660
|
laneId: canonicalLane.laneId ?? null,
|
|
25523
25661
|
branchName: defaultBranch,
|
|
25524
|
-
|
|
25662
|
+
// Same reasoning as the queued-path default-branch write
|
|
25663
|
+
// above: this is the canonical/main-app binding for the
|
|
25664
|
+
// default branch and must be `explicit_root`, otherwise the
|
|
25665
|
+
// history-import auto-spawn (gated on explicit_root) will
|
|
25666
|
+
// silently no-op for every plain init.
|
|
25667
|
+
bindingMode: "explicit_root"
|
|
25525
25668
|
});
|
|
25526
25669
|
}
|
|
25527
25670
|
bindingPath = await writeCollabBinding(repoRoot, {
|
|
@@ -25607,248 +25750,6 @@ function hasPendingFinalize(summary) {
|
|
|
25607
25750
|
function buildPendingFinalizeHint() {
|
|
25608
25751
|
return "Drain or await the local finalize queue first, then retry after the queued Remix turn finishes recording remotely.";
|
|
25609
25752
|
}
|
|
25610
|
-
async function collabReAnchor(params) {
|
|
25611
|
-
const repoRoot = await findGitRoot(params.cwd);
|
|
25612
|
-
const binding = await ensureActiveLaneBinding({
|
|
25613
|
-
repoRoot,
|
|
25614
|
-
api: params.api,
|
|
25615
|
-
operation: "`remix collab re-anchor`"
|
|
25616
|
-
});
|
|
25617
|
-
if (!binding) {
|
|
25618
|
-
throw new RemixError("Repository is not bound to Remix.", {
|
|
25619
|
-
exitCode: 2,
|
|
25620
|
-
hint: "Run `remix collab init` first."
|
|
25621
|
-
});
|
|
25622
|
-
}
|
|
25623
|
-
const detected = await collabDetectRepoState({
|
|
25624
|
-
api: params.api,
|
|
25625
|
-
cwd: repoRoot,
|
|
25626
|
-
allowBranchMismatch: params.allowBranchMismatch
|
|
25627
|
-
});
|
|
25628
|
-
if (detected.status === "metadata_conflict" || detected.status === "branch_mismatch") {
|
|
25629
|
-
throw new RemixError("Repository must be realigned before seeding a fresh local Remix baseline.", {
|
|
25630
|
-
exitCode: 2,
|
|
25631
|
-
hint: detected.hint
|
|
25632
|
-
});
|
|
25633
|
-
}
|
|
25634
|
-
if (detected.status !== "ready" || !detected.binding) {
|
|
25635
|
-
throw new RemixError(detected.hint || "Repository is not ready for re-anchor.", {
|
|
25636
|
-
exitCode: 2,
|
|
25637
|
-
hint: detected.hint
|
|
25638
|
-
});
|
|
25639
|
-
}
|
|
25640
|
-
if (detected.repoState === "server_only_changed") {
|
|
25641
|
-
throw new RemixError("This checkout is already on a server-known base and only needs a local pull.", {
|
|
25642
|
-
exitCode: 2,
|
|
25643
|
-
hint: "Run `remix collab sync` instead of `remix collab re-anchor`."
|
|
25644
|
-
});
|
|
25645
|
-
}
|
|
25646
|
-
if (detected.repoState === "both_changed") {
|
|
25647
|
-
throw new RemixError("Both the local workspace and the server lane changed since the last agreed baseline.", {
|
|
25648
|
-
exitCode: 2,
|
|
25649
|
-
hint: "Run `remix collab reconcile` to replay the local boundary onto the newer server head."
|
|
25650
|
-
});
|
|
25651
|
-
}
|
|
25652
|
-
if (detected.repoState === "local_only_changed") {
|
|
25653
|
-
if (hasPendingFinalize(detected.pendingFinalize)) {
|
|
25654
|
-
throw new RemixError("Re-anchor is not needed while queued Remix turn recording is still processing.", {
|
|
25655
|
-
exitCode: 2,
|
|
25656
|
-
hint: buildPendingFinalizeHint()
|
|
25657
|
-
});
|
|
25658
|
-
}
|
|
25659
|
-
throw new RemixError("Re-anchor is not the right command for local content changes.", {
|
|
25660
|
-
exitCode: 2,
|
|
25661
|
-
hint: "Remix is source-blind: any local content change since the last recorded turn \u2014 including manual commits, pulls, merges, and rebases \u2014 is recorded with `remix collab finalize-turn`. Use `remix collab re-anchor` only when no local Remix baseline exists yet for this lane (status reports `re_anchor`)."
|
|
25662
|
-
});
|
|
25663
|
-
}
|
|
25664
|
-
if (detected.repoState === "idle") {
|
|
25665
|
-
throw new RemixError("This checkout is already aligned with Remix.", {
|
|
25666
|
-
exitCode: 2,
|
|
25667
|
-
hint: "No re-anchor step is needed. Re-anchor only applies when no local Remix baseline exists yet for this lane."
|
|
25668
|
-
});
|
|
25669
|
-
}
|
|
25670
|
-
await ensureCleanWorktree(repoRoot, "`remix collab re-anchor`");
|
|
25671
|
-
const branch = await requireCurrentBranch(repoRoot);
|
|
25672
|
-
const headCommitHash = await getHeadCommitHash(repoRoot);
|
|
25673
|
-
if (!headCommitHash) {
|
|
25674
|
-
throw new RemixError("Failed to resolve local HEAD commit.", { exitCode: 1 });
|
|
25675
|
-
}
|
|
25676
|
-
if (params.asyncSubmit && !params.dryRun) {
|
|
25677
|
-
const pending = await findPendingAsyncJob({
|
|
25678
|
-
repoRoot,
|
|
25679
|
-
branchName: binding.branchName ?? branch,
|
|
25680
|
-
kind: "re_anchor"
|
|
25681
|
-
});
|
|
25682
|
-
if (pending) {
|
|
25683
|
-
return {
|
|
25684
|
-
status: "queued",
|
|
25685
|
-
queued: true,
|
|
25686
|
-
jobId: pending.id,
|
|
25687
|
-
repoRoot,
|
|
25688
|
-
branch,
|
|
25689
|
-
currentAppId: binding.currentAppId,
|
|
25690
|
-
dryRun: false,
|
|
25691
|
-
applied: false
|
|
25692
|
-
};
|
|
25693
|
-
}
|
|
25694
|
-
}
|
|
25695
|
-
const preflightResp = await params.api.preflightAppReconcile(binding.currentAppId, {
|
|
25696
|
-
localHeadCommitHash: headCommitHash,
|
|
25697
|
-
repoFingerprint: binding.repoFingerprint ?? void 0,
|
|
25698
|
-
remoteUrl: binding.remoteUrl ?? void 0,
|
|
25699
|
-
defaultBranch: binding.defaultBranch ?? void 0
|
|
25700
|
-
});
|
|
25701
|
-
const preflight = unwrapResponseObject(preflightResp, "reconcile preflight");
|
|
25702
|
-
if (preflight.status === "metadata_conflict") {
|
|
25703
|
-
throw new RemixError("Local repository metadata conflicts with the bound Remix app.", {
|
|
25704
|
-
exitCode: 2,
|
|
25705
|
-
hint: preflight.warnings.join("\n") || "Run the command from the correct bound repository."
|
|
25706
|
-
});
|
|
25707
|
-
}
|
|
25708
|
-
const preview = {
|
|
25709
|
-
status: preflight.status === "up_to_date" ? "reanchored" : "re_anchor_required",
|
|
25710
|
-
repoRoot,
|
|
25711
|
-
branch,
|
|
25712
|
-
currentAppId: binding.currentAppId,
|
|
25713
|
-
localHeadCommitHash: headCommitHash,
|
|
25714
|
-
targetHeadCommitHash: preflight.targetHeadCommitHash,
|
|
25715
|
-
targetHeadCommitId: preflight.targetHeadCommitId,
|
|
25716
|
-
warnings: preflight.warnings,
|
|
25717
|
-
applied: false,
|
|
25718
|
-
dryRun: params.dryRun === true
|
|
25719
|
-
};
|
|
25720
|
-
if (params.dryRun) {
|
|
25721
|
-
return preview;
|
|
25722
|
-
}
|
|
25723
|
-
let anchoredServerHeadHash = preflight.targetHeadCommitHash;
|
|
25724
|
-
if (params.asyncSubmit && preflight.status === "ready_to_reconcile") {
|
|
25725
|
-
const failed = await findFailedAsyncJob({
|
|
25726
|
-
repoRoot,
|
|
25727
|
-
branchName: binding.branchName ?? branch,
|
|
25728
|
-
kind: "re_anchor"
|
|
25729
|
-
});
|
|
25730
|
-
if (failed) {
|
|
25731
|
-
await deleteAsyncJob(failed.id);
|
|
25732
|
-
}
|
|
25733
|
-
const { bundlePath: tmpBundlePath, headCommitHash: bundledHeadCommitHash } = await createGitBundle(
|
|
25734
|
-
repoRoot,
|
|
25735
|
-
"re-anchor.bundle"
|
|
25736
|
-
);
|
|
25737
|
-
const tmpBundleDir = import_path12.default.dirname(tmpBundlePath);
|
|
25738
|
-
try {
|
|
25739
|
-
const jobId = (0, import_crypto9.randomUUID)();
|
|
25740
|
-
const durableBundlePath = getAsyncJobBundlePath(jobId);
|
|
25741
|
-
await import_promises23.default.mkdir(getAsyncJobDir(jobId), { recursive: true });
|
|
25742
|
-
try {
|
|
25743
|
-
await import_promises23.default.rename(tmpBundlePath, durableBundlePath);
|
|
25744
|
-
} catch (error2) {
|
|
25745
|
-
if (error2?.code !== "EXDEV") throw error2;
|
|
25746
|
-
await import_promises23.default.copyFile(tmpBundlePath, durableBundlePath);
|
|
25747
|
-
await import_promises23.default.unlink(tmpBundlePath).catch(() => void 0);
|
|
25748
|
-
}
|
|
25749
|
-
const bundleSha = await sha256FileHex(durableBundlePath);
|
|
25750
|
-
const job = await enqueueAsyncJob({
|
|
25751
|
-
id: jobId,
|
|
25752
|
-
kind: "re_anchor",
|
|
25753
|
-
status: "queued",
|
|
25754
|
-
repoRoot,
|
|
25755
|
-
repoFingerprint: binding.repoFingerprint,
|
|
25756
|
-
branchName: binding.branchName ?? branch,
|
|
25757
|
-
laneId: binding.laneId,
|
|
25758
|
-
retryCount: 0,
|
|
25759
|
-
error: null,
|
|
25760
|
-
idempotencyKey: null,
|
|
25761
|
-
payload: {
|
|
25762
|
-
bundlePath: durableBundlePath,
|
|
25763
|
-
bundleSha256: bundleSha,
|
|
25764
|
-
localHeadCommitHash: bundledHeadCommitHash,
|
|
25765
|
-
targetHeadCommitHash: preflight.targetHeadCommitHash,
|
|
25766
|
-
appId: binding.currentAppId
|
|
25767
|
-
}
|
|
25768
|
-
});
|
|
25769
|
-
await logDrainerEvent(job.id, "submitted", { kind: "re_anchor" });
|
|
25770
|
-
return {
|
|
25771
|
-
status: "queued",
|
|
25772
|
-
queued: true,
|
|
25773
|
-
jobId: job.id,
|
|
25774
|
-
repoRoot,
|
|
25775
|
-
branch,
|
|
25776
|
-
currentAppId: binding.currentAppId,
|
|
25777
|
-
localHeadCommitHash: bundledHeadCommitHash,
|
|
25778
|
-
targetHeadCommitHash: preflight.targetHeadCommitHash,
|
|
25779
|
-
warnings: preflight.warnings,
|
|
25780
|
-
dryRun: false,
|
|
25781
|
-
applied: false
|
|
25782
|
-
};
|
|
25783
|
-
} finally {
|
|
25784
|
-
await import_promises23.default.rm(tmpBundleDir, { recursive: true, force: true }).catch(() => void 0);
|
|
25785
|
-
}
|
|
25786
|
-
}
|
|
25787
|
-
if (preflight.status === "ready_to_reconcile") {
|
|
25788
|
-
const { bundlePath, headCommitHash: bundledHeadCommitHash } = await createGitBundle(repoRoot, "re-anchor.bundle");
|
|
25789
|
-
const bundleTempDir = import_path12.default.dirname(bundlePath);
|
|
25790
|
-
try {
|
|
25791
|
-
const bundleStat = await import_promises23.default.stat(bundlePath);
|
|
25792
|
-
const checksumSha256 = await sha256FileHex(bundlePath);
|
|
25793
|
-
const presignResp = await params.api.presignImportUploadFirstParty({
|
|
25794
|
-
file: {
|
|
25795
|
-
name: import_path12.default.basename(bundlePath),
|
|
25796
|
-
mimeType: "application/x-git-bundle",
|
|
25797
|
-
size: bundleStat.size,
|
|
25798
|
-
checksumSha256
|
|
25799
|
-
}
|
|
25800
|
-
});
|
|
25801
|
-
const uploadTarget = unwrapResponseObject(presignResp, "import upload target");
|
|
25802
|
-
await uploadPresigned({
|
|
25803
|
-
uploadUrl: String(uploadTarget.uploadUrl),
|
|
25804
|
-
filePath: bundlePath,
|
|
25805
|
-
headers: uploadTarget.headers ?? {}
|
|
25806
|
-
});
|
|
25807
|
-
const startResp = await params.api.startAppReconcile(binding.currentAppId, {
|
|
25808
|
-
uploadId: String(uploadTarget.uploadId),
|
|
25809
|
-
localHeadCommitHash: bundledHeadCommitHash,
|
|
25810
|
-
repoFingerprint: binding.repoFingerprint ?? void 0,
|
|
25811
|
-
remoteUrl: binding.remoteUrl ?? void 0,
|
|
25812
|
-
defaultBranch: binding.defaultBranch ?? void 0,
|
|
25813
|
-
idempotencyKey: buildDeterministicIdempotencyKey({
|
|
25814
|
-
kind: "collab_re_anchor_v1",
|
|
25815
|
-
appId: binding.currentAppId,
|
|
25816
|
-
localHeadCommitHash: bundledHeadCommitHash,
|
|
25817
|
-
targetHeadCommitHash: preflight.targetHeadCommitHash
|
|
25818
|
-
})
|
|
25819
|
-
});
|
|
25820
|
-
const started = unwrapResponseObject(startResp, "reconcile");
|
|
25821
|
-
const reconcile2 = await pollReconcile(params.api, binding.currentAppId, started.id);
|
|
25822
|
-
anchoredServerHeadHash = reconcile2.reconciledHeadCommitHash ?? reconcile2.targetHeadCommitHash ?? preflight.targetHeadCommitHash;
|
|
25823
|
-
} finally {
|
|
25824
|
-
await import_promises23.default.rm(bundleTempDir, { recursive: true, force: true });
|
|
25825
|
-
}
|
|
25826
|
-
}
|
|
25827
|
-
const snapshot = await captureLocalSnapshot({
|
|
25828
|
-
repoRoot,
|
|
25829
|
-
repoFingerprint: binding.repoFingerprint,
|
|
25830
|
-
laneId: binding.laneId,
|
|
25831
|
-
branchName: binding.branchName
|
|
25832
|
-
});
|
|
25833
|
-
await writeLocalBaseline({
|
|
25834
|
-
repoRoot,
|
|
25835
|
-
repoFingerprint: binding.repoFingerprint,
|
|
25836
|
-
laneId: binding.laneId,
|
|
25837
|
-
currentAppId: binding.currentAppId,
|
|
25838
|
-
branchName: binding.branchName,
|
|
25839
|
-
lastSnapshotId: snapshot.id,
|
|
25840
|
-
lastSnapshotHash: snapshot.snapshotHash,
|
|
25841
|
-
lastServerHeadHash: anchoredServerHeadHash,
|
|
25842
|
-
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
25843
|
-
});
|
|
25844
|
-
return {
|
|
25845
|
-
...preview,
|
|
25846
|
-
status: "reanchored",
|
|
25847
|
-
targetHeadCommitHash: anchoredServerHeadHash,
|
|
25848
|
-
applied: true,
|
|
25849
|
-
dryRun: false
|
|
25850
|
-
};
|
|
25851
|
-
}
|
|
25852
25753
|
async function reconcileBothChanged(params) {
|
|
25853
25754
|
const repoRoot = await findGitRoot(params.cwd);
|
|
25854
25755
|
const binding = await ensureActiveLaneBinding({
|
|
@@ -25871,7 +25772,7 @@ async function reconcileBothChanged(params) {
|
|
|
25871
25772
|
if (!baseline?.lastSnapshotId || !baseline.lastServerHeadHash) {
|
|
25872
25773
|
throw new RemixError("Local Remix baseline is missing for this lane.", {
|
|
25873
25774
|
exitCode: 2,
|
|
25874
|
-
hint: "Run `remix collab
|
|
25775
|
+
hint: "Run `remix collab init` or sync from a checkout with a valid revision baseline first."
|
|
25875
25776
|
});
|
|
25876
25777
|
}
|
|
25877
25778
|
const currentSnapshot = await captureLocalSnapshot({
|
|
@@ -25894,6 +25795,7 @@ async function reconcileBothChanged(params) {
|
|
|
25894
25795
|
params.api.getAppHead(binding.currentAppId),
|
|
25895
25796
|
params.api.getAppDelta(binding.currentAppId, {
|
|
25896
25797
|
baseHeadHash: baseline.lastServerHeadHash,
|
|
25798
|
+
baseRevisionId: baseline.lastServerRevisionId,
|
|
25897
25799
|
repoFingerprint: binding.repoFingerprint ?? void 0,
|
|
25898
25800
|
remoteUrl: binding.remoteUrl ?? void 0,
|
|
25899
25801
|
defaultBranch: binding.defaultBranch ?? void 0
|
|
@@ -25911,7 +25813,7 @@ async function reconcileBothChanged(params) {
|
|
|
25911
25813
|
if (delta.status === "base_unknown") {
|
|
25912
25814
|
throw new RemixError("Reconcile cannot pull the newer server state from the last acknowledged baseline.", {
|
|
25913
25815
|
exitCode: 2,
|
|
25914
|
-
hint: "Run `remix collab
|
|
25816
|
+
hint: "Run `remix collab init` to seed a fresh revision baseline for this checkout before retrying."
|
|
25915
25817
|
});
|
|
25916
25818
|
}
|
|
25917
25819
|
if (delta.status !== "delta_ready" && delta.status !== "up_to_date") {
|
|
@@ -25942,7 +25844,9 @@ async function reconcileBothChanged(params) {
|
|
|
25942
25844
|
assistantResponse: "Replay the local boundary delta onto the latest server head without recording a new change step.",
|
|
25943
25845
|
diff: diffResult.diff,
|
|
25944
25846
|
baseCommitHash: baseline.lastServerHeadHash,
|
|
25847
|
+
baseRevisionId: baseline.lastServerRevisionId,
|
|
25945
25848
|
targetHeadCommitHash: appHead.headCommitHash,
|
|
25849
|
+
targetRevisionId: appHead.headRevisionId,
|
|
25946
25850
|
expectedPaths: diffResult.changedPaths,
|
|
25947
25851
|
workspaceMetadata: {
|
|
25948
25852
|
recordingMode: "boundary_delta",
|
|
@@ -25950,6 +25854,7 @@ async function reconcileBothChanged(params) {
|
|
|
25950
25854
|
branch,
|
|
25951
25855
|
baselineSnapshotId: baseline.lastSnapshotId,
|
|
25952
25856
|
currentSnapshotId: currentSnapshot.id,
|
|
25857
|
+
baselineServerRevisionId: baseline.lastServerRevisionId,
|
|
25953
25858
|
baselineServerHeadHash: baseline.lastServerHeadHash,
|
|
25954
25859
|
currentSnapshotHash: currentSnapshot.snapshotHash,
|
|
25955
25860
|
localCommitHash: currentSnapshot.localCommitHash,
|
|
@@ -25968,12 +25873,12 @@ async function reconcileBothChanged(params) {
|
|
|
25968
25873
|
const replay = await pollChangeStepReplay(params.api, binding.currentAppId, String(replayStart.id));
|
|
25969
25874
|
const replayDiffResp = await params.api.getChangeStepReplayDiff(binding.currentAppId, replay.id);
|
|
25970
25875
|
const replayDiff = unwrapResponseObject(replayDiffResp, "change step replay diff");
|
|
25971
|
-
const tempRoot = await
|
|
25876
|
+
const tempRoot = await import_promises23.default.mkdtemp(import_path12.default.join(import_os6.default.tmpdir(), "remix-reconcile-"));
|
|
25972
25877
|
let serverHeadSnapshot = null;
|
|
25973
25878
|
let mergedSnapshot = null;
|
|
25974
25879
|
try {
|
|
25975
|
-
const tempRepoRoot =
|
|
25976
|
-
await
|
|
25880
|
+
const tempRepoRoot = import_path12.default.join(tempRoot, "repo");
|
|
25881
|
+
await import_promises23.default.mkdir(tempRepoRoot, { recursive: true });
|
|
25977
25882
|
await execa("git", ["init"], { cwd: tempRepoRoot, stderr: "ignore" });
|
|
25978
25883
|
await materializeLocalSnapshot(baseline.lastSnapshotId, tempRepoRoot);
|
|
25979
25884
|
if (delta.status === "delta_ready" && delta.diff.trim()) {
|
|
@@ -25995,7 +25900,7 @@ async function reconcileBothChanged(params) {
|
|
|
25995
25900
|
branchName: binding.branchName
|
|
25996
25901
|
});
|
|
25997
25902
|
} finally {
|
|
25998
|
-
await
|
|
25903
|
+
await import_promises23.default.rm(tempRoot, { recursive: true, force: true }).catch(() => void 0);
|
|
25999
25904
|
}
|
|
26000
25905
|
if (!serverHeadSnapshot || !mergedSnapshot) {
|
|
26001
25906
|
throw new RemixError("Failed to materialize the reconciled local workspace.", { exitCode: 1 });
|
|
@@ -26032,6 +25937,8 @@ async function reconcileBothChanged(params) {
|
|
|
26032
25937
|
branchName: binding.branchName,
|
|
26033
25938
|
lastSnapshotId: serverHeadSnapshot.id,
|
|
26034
25939
|
lastSnapshotHash: serverHeadSnapshot.snapshotHash,
|
|
25940
|
+
lastServerRevisionId: appHead.headRevisionId ?? null,
|
|
25941
|
+
lastServerTreeHash: appHead.treeHash ?? null,
|
|
26035
25942
|
lastServerHeadHash: appHead.headCommitHash,
|
|
26036
25943
|
lastSeenLocalCommitHash: restoredSnapshot.localCommitHash
|
|
26037
25944
|
});
|
|
@@ -26067,7 +25974,10 @@ async function collabReconcile(params) {
|
|
|
26067
25974
|
return reconcileBothChanged(params);
|
|
26068
25975
|
}
|
|
26069
25976
|
if (detected.repoState === "external_local_base_changed") {
|
|
26070
|
-
|
|
25977
|
+
throw new RemixError("This checkout needs a local Remix revision baseline before reconciliation.", {
|
|
25978
|
+
exitCode: 2,
|
|
25979
|
+
hint: detected.hint || "Run `remix collab init` or `remix collab sync` to seed the baseline."
|
|
25980
|
+
});
|
|
26071
25981
|
}
|
|
26072
25982
|
if (detected.repoState === "local_only_changed") {
|
|
26073
25983
|
if (hasPendingFinalize(detected.pendingFinalize)) {
|
|
@@ -26174,6 +26084,8 @@ async function collabRemix(params) {
|
|
|
26174
26084
|
branchName: branchNameForBaseline,
|
|
26175
26085
|
lastSnapshotId: snapshot.id,
|
|
26176
26086
|
lastSnapshotHash: snapshot.snapshotHash,
|
|
26087
|
+
lastServerRevisionId: appHead.headRevisionId ?? null,
|
|
26088
|
+
lastServerTreeHash: appHead.treeHash ?? null,
|
|
26177
26089
|
lastServerHeadHash: appHead.headCommitHash,
|
|
26178
26090
|
lastSeenLocalCommitHash: snapshot.localCommitHash
|
|
26179
26091
|
});
|
|
@@ -26294,11 +26206,15 @@ function createBaseStatus() {
|
|
|
26294
26206
|
baseline: {
|
|
26295
26207
|
lastSnapshotId: null,
|
|
26296
26208
|
lastSnapshotHash: null,
|
|
26209
|
+
lastServerRevisionId: null,
|
|
26210
|
+
lastServerTreeHash: null,
|
|
26297
26211
|
lastServerHeadHash: null,
|
|
26298
26212
|
lastSeenLocalCommitHash: null
|
|
26299
26213
|
},
|
|
26300
26214
|
current: {
|
|
26301
26215
|
snapshotHash: null,
|
|
26216
|
+
serverRevisionId: null,
|
|
26217
|
+
serverTreeHash: null,
|
|
26302
26218
|
serverHeadHash: null,
|
|
26303
26219
|
serverHeadCommitId: null,
|
|
26304
26220
|
localCommitHash: null
|
|
@@ -26385,6 +26301,8 @@ async function collabStatus(params) {
|
|
|
26385
26301
|
status.alignment.baseline = detected.baseline;
|
|
26386
26302
|
status.alignment.current = {
|
|
26387
26303
|
snapshotHash: detected.currentSnapshotHash,
|
|
26304
|
+
serverRevisionId: detected.currentServerRevisionId,
|
|
26305
|
+
serverTreeHash: detected.currentServerTreeHash,
|
|
26388
26306
|
serverHeadHash: detected.currentServerHeadHash,
|
|
26389
26307
|
serverHeadCommitId: detected.currentServerHeadCommitId,
|
|
26390
26308
|
localCommitHash: detected.localCommitHash
|
|
@@ -26448,7 +26366,7 @@ async function collabStatus(params) {
|
|
|
26448
26366
|
status.reconcile.canApply = !status.repo.branchMismatch;
|
|
26449
26367
|
status.recommendedAction = "reconcile";
|
|
26450
26368
|
} else if (detected.repoState === "external_local_base_changed") {
|
|
26451
|
-
status.recommendedAction = "
|
|
26369
|
+
status.recommendedAction = "init";
|
|
26452
26370
|
addBlockedReason(status.sync, "baseline_missing");
|
|
26453
26371
|
addBlockedReason(status.reconcile, "baseline_missing");
|
|
26454
26372
|
} else if (detected.repoState === "local_only_changed") {
|
|
@@ -26701,10 +26619,10 @@ async function processInitJob(job, api) {
|
|
|
26701
26619
|
try {
|
|
26702
26620
|
await updateAsyncJob(job.id, { status: "submitting", error: null });
|
|
26703
26621
|
await logDrainerEvent(job.id, "claimed", { kind: "init" });
|
|
26704
|
-
const bundleStat = await
|
|
26622
|
+
const bundleStat = await import_promises24.default.stat(job.payload.bundlePath);
|
|
26705
26623
|
const presignResp = await api.presignImportUploadFirstParty({
|
|
26706
26624
|
file: {
|
|
26707
|
-
name:
|
|
26625
|
+
name: import_path13.default.basename(job.payload.bundlePath),
|
|
26708
26626
|
mimeType: "application/x-git-bundle",
|
|
26709
26627
|
size: bundleStat.size,
|
|
26710
26628
|
checksumSha256: job.payload.bundleSha256
|
|
@@ -26721,7 +26639,7 @@ async function processInitJob(job, api) {
|
|
|
26721
26639
|
await updateAsyncJob(job.id, { status: "server_processing" });
|
|
26722
26640
|
const importResp = await api.importFromUploadFirstParty({
|
|
26723
26641
|
uploadId: String(presign.uploadId),
|
|
26724
|
-
appName: job.payload.appName?.trim() ||
|
|
26642
|
+
appName: job.payload.appName?.trim() || import_path13.default.basename(job.repoRoot),
|
|
26725
26643
|
platform: "generic",
|
|
26726
26644
|
isPublic: false,
|
|
26727
26645
|
branch: job.payload.defaultBranch && job.branchName && job.branchName !== job.payload.defaultBranch ? job.payload.defaultBranch : job.branchName ?? void 0,
|
|
@@ -26796,7 +26714,7 @@ async function processInitJob(job, api) {
|
|
|
26796
26714
|
boundProjectId = String(readyApp.projectId ?? boundProjectId);
|
|
26797
26715
|
boundThreadId = readyApp.threadId ? String(readyApp.threadId) : boundThreadId;
|
|
26798
26716
|
}
|
|
26799
|
-
const bindingMode =
|
|
26717
|
+
const bindingMode = defaultBranch && branchName !== defaultBranch ? "lane" : "explicit_root";
|
|
26800
26718
|
if (job.payload.forceNew && defaultBranch && canonicalLane) {
|
|
26801
26719
|
const canonicalBinding = branchBindingFromLane(canonicalLane, "explicit_root", {
|
|
26802
26720
|
projectId: canonicalLane.projectId ?? boundProjectId,
|
|
@@ -26835,7 +26753,12 @@ async function processInitJob(job, api) {
|
|
|
26835
26753
|
defaultBranch: canonicalLane.defaultBranch ?? defaultBranch,
|
|
26836
26754
|
laneId: canonicalLane.laneId ?? null,
|
|
26837
26755
|
branchName: defaultBranch,
|
|
26838
|
-
|
|
26756
|
+
// This branch is reached only when the current branch is NOT
|
|
26757
|
+
// the default branch — so the binding being written here is
|
|
26758
|
+
// for the DEFAULT branch (the canonical/main app). It must
|
|
26759
|
+
// always be `explicit_root` so the history-import auto-spawn
|
|
26760
|
+
// can fire on first-ever inits (see autoSpawnHistoryImport.ts).
|
|
26761
|
+
bindingMode: "explicit_root"
|
|
26839
26762
|
});
|
|
26840
26763
|
}
|
|
26841
26764
|
await writeCollabBinding(repoRoot, {
|
|
@@ -26910,7 +26833,7 @@ async function processInitPostJob(job, api) {
|
|
|
26910
26833
|
if (outcome.status === "failed") {
|
|
26911
26834
|
const bindingPath = getCollabBindingPath(job.repoRoot);
|
|
26912
26835
|
try {
|
|
26913
|
-
await
|
|
26836
|
+
await import_promises24.default.unlink(bindingPath);
|
|
26914
26837
|
await logDrainerEvent(job.id, "binding_cleared", {
|
|
26915
26838
|
kind: "init_post",
|
|
26916
26839
|
appId: job.payload.appId,
|
|
@@ -26951,10 +26874,10 @@ async function processReAnchorJob(job, api) {
|
|
|
26951
26874
|
}
|
|
26952
26875
|
let anchoredServerHeadHash = preflight.targetHeadCommitHash;
|
|
26953
26876
|
if (preflight.status === "ready_to_reconcile") {
|
|
26954
|
-
const bundleStat = await
|
|
26877
|
+
const bundleStat = await import_promises24.default.stat(job.payload.bundlePath);
|
|
26955
26878
|
const presignResp = await api.presignImportUploadFirstParty({
|
|
26956
26879
|
file: {
|
|
26957
|
-
name:
|
|
26880
|
+
name: import_path13.default.basename(job.payload.bundlePath),
|
|
26958
26881
|
mimeType: "application/x-git-bundle",
|
|
26959
26882
|
size: bundleStat.size,
|
|
26960
26883
|
checksumSha256: job.payload.bundleSha256
|
|
@@ -27058,9 +26981,9 @@ async function collabReAnchorProcess(jobId, opts) {
|
|
|
27058
26981
|
}
|
|
27059
26982
|
async function acquireDrainerPidLock() {
|
|
27060
26983
|
const pidPath = getDrainerPidPath();
|
|
27061
|
-
await
|
|
26984
|
+
await import_promises24.default.mkdir(import_path13.default.dirname(pidPath), { recursive: true });
|
|
27062
26985
|
try {
|
|
27063
|
-
const existing = await
|
|
26986
|
+
const existing = await import_promises24.default.readFile(pidPath, "utf8").catch(() => "");
|
|
27064
26987
|
const existingPid = parseInt(existing.trim(), 10);
|
|
27065
26988
|
if (Number.isFinite(existingPid) && existingPid > 0 && existingPid !== process.pid) {
|
|
27066
26989
|
try {
|
|
@@ -27070,13 +26993,13 @@ async function acquireDrainerPidLock() {
|
|
|
27070
26993
|
if (error2?.code !== "ESRCH") return null;
|
|
27071
26994
|
}
|
|
27072
26995
|
}
|
|
27073
|
-
await
|
|
26996
|
+
await import_promises24.default.writeFile(pidPath, String(process.pid), "utf8");
|
|
27074
26997
|
return {
|
|
27075
26998
|
release: async () => {
|
|
27076
26999
|
try {
|
|
27077
|
-
const current = (await
|
|
27000
|
+
const current = (await import_promises24.default.readFile(pidPath, "utf8")).trim();
|
|
27078
27001
|
if (current === String(process.pid)) {
|
|
27079
|
-
await
|
|
27002
|
+
await import_promises24.default.unlink(pidPath).catch(() => void 0);
|
|
27080
27003
|
}
|
|
27081
27004
|
} catch {
|
|
27082
27005
|
}
|
|
@@ -27591,8 +27514,8 @@ function getErrorMap() {
|
|
|
27591
27514
|
|
|
27592
27515
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
27593
27516
|
var makeIssue = (params) => {
|
|
27594
|
-
const { data, path:
|
|
27595
|
-
const fullPath = [...
|
|
27517
|
+
const { data, path: path16, errorMaps, issueData } = params;
|
|
27518
|
+
const fullPath = [...path16, ...issueData.path || []];
|
|
27596
27519
|
const fullIssue = {
|
|
27597
27520
|
...issueData,
|
|
27598
27521
|
path: fullPath
|
|
@@ -27708,11 +27631,11 @@ var errorUtil;
|
|
|
27708
27631
|
|
|
27709
27632
|
// node_modules/zod/v3/types.js
|
|
27710
27633
|
var ParseInputLazyPath = class {
|
|
27711
|
-
constructor(parent, value,
|
|
27634
|
+
constructor(parent, value, path16, key) {
|
|
27712
27635
|
this._cachedPath = [];
|
|
27713
27636
|
this.parent = parent;
|
|
27714
27637
|
this.data = value;
|
|
27715
|
-
this._path =
|
|
27638
|
+
this._path = path16;
|
|
27716
27639
|
this._key = key;
|
|
27717
27640
|
}
|
|
27718
27641
|
get path() {
|
|
@@ -35204,7 +35127,7 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
35204
35127
|
}
|
|
35205
35128
|
};
|
|
35206
35129
|
|
|
35207
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
35130
|
+
// node_modules/@remixhq/core/dist/chunk-RCNOSZP6.js
|
|
35208
35131
|
async function readJsonSafe(res) {
|
|
35209
35132
|
const ct = res.headers.get("content-type") ?? "";
|
|
35210
35133
|
if (!ct.toLowerCase().includes("application/json")) return null;
|
|
@@ -35217,8 +35140,13 @@ async function readJsonSafe(res) {
|
|
|
35217
35140
|
function createApiClient(config2, opts) {
|
|
35218
35141
|
const apiKey = (opts?.apiKey ?? "").trim();
|
|
35219
35142
|
const tokenProvider = opts?.tokenProvider;
|
|
35143
|
+
const defaultTimeoutMs = typeof opts?.defaultRequestTimeoutMs === "number" && opts.defaultRequestTimeoutMs > 0 ? opts.defaultRequestTimeoutMs : null;
|
|
35220
35144
|
const CLIENT_KEY_HEADER = "x-comerge-api-key";
|
|
35221
|
-
|
|
35145
|
+
function makeTimeoutSignal(timeoutMs) {
|
|
35146
|
+
const ms = typeof timeoutMs === "number" && timeoutMs > 0 ? timeoutMs : defaultTimeoutMs;
|
|
35147
|
+
return ms != null ? AbortSignal.timeout(ms) : void 0;
|
|
35148
|
+
}
|
|
35149
|
+
async function request(path16, init, opts2) {
|
|
35222
35150
|
if (!tokenProvider) {
|
|
35223
35151
|
throw new RemixError("API client is missing a token provider.", {
|
|
35224
35152
|
exitCode: 1,
|
|
@@ -35226,9 +35154,10 @@ function createApiClient(config2, opts) {
|
|
|
35226
35154
|
});
|
|
35227
35155
|
}
|
|
35228
35156
|
const auth = await tokenProvider();
|
|
35229
|
-
const url = new URL(
|
|
35157
|
+
const url = new URL(path16, config2.apiUrl).toString();
|
|
35230
35158
|
const doFetch = async (bearer) => fetch(url, {
|
|
35231
35159
|
...init,
|
|
35160
|
+
signal: makeTimeoutSignal(opts2?.timeoutMs),
|
|
35232
35161
|
headers: {
|
|
35233
35162
|
Accept: "application/json",
|
|
35234
35163
|
"Content-Type": "application/json",
|
|
@@ -35245,12 +35174,16 @@ function createApiClient(config2, opts) {
|
|
|
35245
35174
|
if (!res.ok) {
|
|
35246
35175
|
const body = await readJsonSafe(res);
|
|
35247
35176
|
const msg = (body && typeof body === "object" && body && "message" in body && typeof body.message === "string" ? body.message : null) ?? `Request failed (status ${res.status})`;
|
|
35248
|
-
throw new RemixError(msg, {
|
|
35177
|
+
throw new RemixError(msg, {
|
|
35178
|
+
exitCode: 1,
|
|
35179
|
+
hint: body ? JSON.stringify(body, null, 2) : null,
|
|
35180
|
+
statusCode: res.status
|
|
35181
|
+
});
|
|
35249
35182
|
}
|
|
35250
35183
|
const json = await readJsonSafe(res);
|
|
35251
35184
|
return json ?? null;
|
|
35252
35185
|
}
|
|
35253
|
-
async function requestBinary(
|
|
35186
|
+
async function requestBinary(path16, init, opts2) {
|
|
35254
35187
|
if (!tokenProvider) {
|
|
35255
35188
|
throw new RemixError("API client is missing a token provider.", {
|
|
35256
35189
|
exitCode: 1,
|
|
@@ -35258,9 +35191,10 @@ function createApiClient(config2, opts) {
|
|
|
35258
35191
|
});
|
|
35259
35192
|
}
|
|
35260
35193
|
const auth = await tokenProvider();
|
|
35261
|
-
const url = new URL(
|
|
35194
|
+
const url = new URL(path16, config2.apiUrl).toString();
|
|
35262
35195
|
const doFetch = async (bearer) => fetch(url, {
|
|
35263
35196
|
...init,
|
|
35197
|
+
signal: makeTimeoutSignal(opts2?.timeoutMs),
|
|
35264
35198
|
headers: {
|
|
35265
35199
|
Accept: "*/*",
|
|
35266
35200
|
...init?.headers ?? {},
|
|
@@ -35276,7 +35210,11 @@ function createApiClient(config2, opts) {
|
|
|
35276
35210
|
if (!res.ok) {
|
|
35277
35211
|
const body = await readJsonSafe(res);
|
|
35278
35212
|
const msg = (body && typeof body === "object" && body && "message" in body && typeof body.message === "string" ? body.message : null) ?? `Request failed (status ${res.status})`;
|
|
35279
|
-
throw new RemixError(msg, {
|
|
35213
|
+
throw new RemixError(msg, {
|
|
35214
|
+
exitCode: 1,
|
|
35215
|
+
hint: body ? JSON.stringify(body, null, 2) : null,
|
|
35216
|
+
statusCode: res.status
|
|
35217
|
+
});
|
|
35280
35218
|
}
|
|
35281
35219
|
const contentDisposition = res.headers.get("content-disposition") ?? "";
|
|
35282
35220
|
const fileNameMatch = contentDisposition.match(/filename=\"([^\"]+)\"/i);
|
|
@@ -35630,10 +35568,10 @@ function createApiClient(config2, opts) {
|
|
|
35630
35568
|
};
|
|
35631
35569
|
}
|
|
35632
35570
|
|
|
35633
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
35634
|
-
var
|
|
35571
|
+
// node_modules/@remixhq/core/dist/chunk-XETDXVGM.js
|
|
35572
|
+
var import_promises25 = __toESM(require("fs/promises"), 1);
|
|
35635
35573
|
var import_os7 = __toESM(require("os"), 1);
|
|
35636
|
-
var
|
|
35574
|
+
var import_path14 = __toESM(require("path"), 1);
|
|
35637
35575
|
|
|
35638
35576
|
// node_modules/tslib/tslib.es6.mjs
|
|
35639
35577
|
function __rest(s, e) {
|
|
@@ -44736,8 +44674,8 @@ var IcebergError = class extends Error {
|
|
|
44736
44674
|
return this.status === 419;
|
|
44737
44675
|
}
|
|
44738
44676
|
};
|
|
44739
|
-
function buildUrl(baseUrl,
|
|
44740
|
-
const url = new URL(
|
|
44677
|
+
function buildUrl(baseUrl, path16, query) {
|
|
44678
|
+
const url = new URL(path16, baseUrl);
|
|
44741
44679
|
if (query) {
|
|
44742
44680
|
for (const [key, value] of Object.entries(query)) {
|
|
44743
44681
|
if (value !== void 0) {
|
|
@@ -44767,12 +44705,12 @@ function createFetchClient(options) {
|
|
|
44767
44705
|
return {
|
|
44768
44706
|
async request({
|
|
44769
44707
|
method,
|
|
44770
|
-
path:
|
|
44708
|
+
path: path16,
|
|
44771
44709
|
query,
|
|
44772
44710
|
body,
|
|
44773
44711
|
headers
|
|
44774
44712
|
}) {
|
|
44775
|
-
const url = buildUrl(options.baseUrl,
|
|
44713
|
+
const url = buildUrl(options.baseUrl, path16, query);
|
|
44776
44714
|
const authHeaders = await buildAuthHeaders(options.auth);
|
|
44777
44715
|
const res = await fetchFn(url, {
|
|
44778
44716
|
method,
|
|
@@ -45610,7 +45548,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
45610
45548
|
* @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.
|
|
45611
45549
|
* @param fileBody The body of the file to be stored in the bucket.
|
|
45612
45550
|
*/
|
|
45613
|
-
async uploadOrUpdate(method,
|
|
45551
|
+
async uploadOrUpdate(method, path16, fileBody, fileOptions) {
|
|
45614
45552
|
var _this = this;
|
|
45615
45553
|
return _this.handleOperation(async () => {
|
|
45616
45554
|
let body;
|
|
@@ -45634,7 +45572,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
45634
45572
|
if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
|
|
45635
45573
|
}
|
|
45636
45574
|
if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) for (const [key, value] of Object.entries(fileOptions.headers)) headers = setHeader(headers, key, value);
|
|
45637
|
-
const cleanPath = _this._removeEmptyFolders(
|
|
45575
|
+
const cleanPath = _this._removeEmptyFolders(path16);
|
|
45638
45576
|
const _path = _this._getFinalPath(cleanPath);
|
|
45639
45577
|
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 } : {}));
|
|
45640
45578
|
return {
|
|
@@ -45695,8 +45633,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
45695
45633
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
45696
45634
|
* - 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.
|
|
45697
45635
|
*/
|
|
45698
|
-
async upload(
|
|
45699
|
-
return this.uploadOrUpdate("POST",
|
|
45636
|
+
async upload(path16, fileBody, fileOptions) {
|
|
45637
|
+
return this.uploadOrUpdate("POST", path16, fileBody, fileOptions);
|
|
45700
45638
|
}
|
|
45701
45639
|
/**
|
|
45702
45640
|
* Upload a file with a token generated from `createSignedUploadUrl`.
|
|
@@ -45735,9 +45673,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
45735
45673
|
* - `objects` table permissions: none
|
|
45736
45674
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
45737
45675
|
*/
|
|
45738
|
-
async uploadToSignedUrl(
|
|
45676
|
+
async uploadToSignedUrl(path16, token, fileBody, fileOptions) {
|
|
45739
45677
|
var _this3 = this;
|
|
45740
|
-
const cleanPath = _this3._removeEmptyFolders(
|
|
45678
|
+
const cleanPath = _this3._removeEmptyFolders(path16);
|
|
45741
45679
|
const _path = _this3._getFinalPath(cleanPath);
|
|
45742
45680
|
const url = new URL(_this3.url + `/object/upload/sign/${_path}`);
|
|
45743
45681
|
url.searchParams.set("token", token);
|
|
@@ -45799,10 +45737,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
45799
45737
|
* - `objects` table permissions: `insert`
|
|
45800
45738
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
45801
45739
|
*/
|
|
45802
|
-
async createSignedUploadUrl(
|
|
45740
|
+
async createSignedUploadUrl(path16, options) {
|
|
45803
45741
|
var _this4 = this;
|
|
45804
45742
|
return _this4.handleOperation(async () => {
|
|
45805
|
-
let _path = _this4._getFinalPath(
|
|
45743
|
+
let _path = _this4._getFinalPath(path16);
|
|
45806
45744
|
const headers = _objectSpread22({}, _this4.headers);
|
|
45807
45745
|
if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
|
|
45808
45746
|
const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
|
|
@@ -45811,7 +45749,7 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
45811
45749
|
if (!token) throw new StorageError("No token returned by API");
|
|
45812
45750
|
return {
|
|
45813
45751
|
signedUrl: url.toString(),
|
|
45814
|
-
path:
|
|
45752
|
+
path: path16,
|
|
45815
45753
|
token
|
|
45816
45754
|
};
|
|
45817
45755
|
});
|
|
@@ -45867,8 +45805,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
45867
45805
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
45868
45806
|
* - 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.
|
|
45869
45807
|
*/
|
|
45870
|
-
async update(
|
|
45871
|
-
return this.uploadOrUpdate("PUT",
|
|
45808
|
+
async update(path16, fileBody, fileOptions) {
|
|
45809
|
+
return this.uploadOrUpdate("PUT", path16, fileBody, fileOptions);
|
|
45872
45810
|
}
|
|
45873
45811
|
/**
|
|
45874
45812
|
* Moves an existing file to a new path in the same bucket.
|
|
@@ -46016,10 +45954,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
46016
45954
|
* - `objects` table permissions: `select`
|
|
46017
45955
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
46018
45956
|
*/
|
|
46019
|
-
async createSignedUrl(
|
|
45957
|
+
async createSignedUrl(path16, expiresIn, options) {
|
|
46020
45958
|
var _this8 = this;
|
|
46021
45959
|
return _this8.handleOperation(async () => {
|
|
46022
|
-
let _path = _this8._getFinalPath(
|
|
45960
|
+
let _path = _this8._getFinalPath(path16);
|
|
46023
45961
|
const hasTransform = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0;
|
|
46024
45962
|
let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, hasTransform ? { transform: options.transform } : {}), { headers: _this8.headers });
|
|
46025
45963
|
const query = new URLSearchParams();
|
|
@@ -46153,13 +46091,13 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
46153
46091
|
* - `objects` table permissions: `select`
|
|
46154
46092
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
46155
46093
|
*/
|
|
46156
|
-
download(
|
|
46094
|
+
download(path16, options, parameters) {
|
|
46157
46095
|
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";
|
|
46158
46096
|
const query = new URLSearchParams();
|
|
46159
46097
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
46160
46098
|
if ((options === null || options === void 0 ? void 0 : options.cacheNonce) != null) query.set("cacheNonce", String(options.cacheNonce));
|
|
46161
46099
|
const queryString = query.toString();
|
|
46162
|
-
const _path = this._getFinalPath(
|
|
46100
|
+
const _path = this._getFinalPath(path16);
|
|
46163
46101
|
const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ""}`, {
|
|
46164
46102
|
headers: this.headers,
|
|
46165
46103
|
noResolveJson: true
|
|
@@ -46189,9 +46127,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
46189
46127
|
* }
|
|
46190
46128
|
* ```
|
|
46191
46129
|
*/
|
|
46192
|
-
async info(
|
|
46130
|
+
async info(path16) {
|
|
46193
46131
|
var _this10 = this;
|
|
46194
|
-
const _path = _this10._getFinalPath(
|
|
46132
|
+
const _path = _this10._getFinalPath(path16);
|
|
46195
46133
|
return _this10.handleOperation(async () => {
|
|
46196
46134
|
return recursiveToCamel(await get(_this10.fetch, `${_this10.url}/object/info/${_path}`, { headers: _this10.headers }));
|
|
46197
46135
|
});
|
|
@@ -46211,9 +46149,9 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
46211
46149
|
* .exists('folder/avatar1.png')
|
|
46212
46150
|
* ```
|
|
46213
46151
|
*/
|
|
46214
|
-
async exists(
|
|
46152
|
+
async exists(path16) {
|
|
46215
46153
|
var _this11 = this;
|
|
46216
|
-
const _path = _this11._getFinalPath(
|
|
46154
|
+
const _path = _this11._getFinalPath(path16);
|
|
46217
46155
|
try {
|
|
46218
46156
|
await head(_this11.fetch, `${_this11.url}/object/${_path}`, { headers: _this11.headers });
|
|
46219
46157
|
return {
|
|
@@ -46291,8 +46229,8 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
46291
46229
|
* - `objects` table permissions: none
|
|
46292
46230
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
46293
46231
|
*/
|
|
46294
|
-
getPublicUrl(
|
|
46295
|
-
const _path = this._getFinalPath(
|
|
46232
|
+
getPublicUrl(path16, options) {
|
|
46233
|
+
const _path = this._getFinalPath(path16);
|
|
46296
46234
|
const query = new URLSearchParams();
|
|
46297
46235
|
if (options === null || options === void 0 ? void 0 : options.download) query.set("download", options.download === true ? "" : options.download);
|
|
46298
46236
|
if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
|
|
@@ -46429,10 +46367,10 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
46429
46367
|
* - `objects` table permissions: `select`
|
|
46430
46368
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
46431
46369
|
*/
|
|
46432
|
-
async list(
|
|
46370
|
+
async list(path16, options, parameters) {
|
|
46433
46371
|
var _this13 = this;
|
|
46434
46372
|
return _this13.handleOperation(async () => {
|
|
46435
|
-
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix:
|
|
46373
|
+
const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path16 || "" });
|
|
46436
46374
|
return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
|
|
46437
46375
|
});
|
|
46438
46376
|
}
|
|
@@ -46496,11 +46434,11 @@ var StorageFileApi = class extends BaseApiClient {
|
|
|
46496
46434
|
if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
|
|
46497
46435
|
return btoa(data);
|
|
46498
46436
|
}
|
|
46499
|
-
_getFinalPath(
|
|
46500
|
-
return `${this.bucketId}/${
|
|
46437
|
+
_getFinalPath(path16) {
|
|
46438
|
+
return `${this.bucketId}/${path16.replace(/^\/+/, "")}`;
|
|
46501
46439
|
}
|
|
46502
|
-
_removeEmptyFolders(
|
|
46503
|
-
return
|
|
46440
|
+
_removeEmptyFolders(path16) {
|
|
46441
|
+
return path16.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
|
|
46504
46442
|
}
|
|
46505
46443
|
/** Modifies the `query`, appending values the from `transform` */
|
|
46506
46444
|
applyTransformOptsToQuery(query, transform2) {
|
|
@@ -55575,7 +55513,7 @@ function shouldShowDeprecationWarning() {
|
|
|
55575
55513
|
}
|
|
55576
55514
|
if (shouldShowDeprecationWarning()) console.warn("\u26A0\uFE0F Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
55577
55515
|
|
|
55578
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
55516
|
+
// node_modules/@remixhq/core/dist/chunk-XETDXVGM.js
|
|
55579
55517
|
var storedSessionSchema = external_exports.object({
|
|
55580
55518
|
access_token: external_exports.string().min(1),
|
|
55581
55519
|
refresh_token: external_exports.string().min(1),
|
|
@@ -55589,7 +55527,7 @@ var storedSessionSchema = external_exports.object({
|
|
|
55589
55527
|
function xdgConfigHome() {
|
|
55590
55528
|
const value = process.env.XDG_CONFIG_HOME;
|
|
55591
55529
|
if (typeof value === "string" && value.trim()) return value;
|
|
55592
|
-
return
|
|
55530
|
+
return import_path14.default.join(import_os7.default.homedir(), ".config");
|
|
55593
55531
|
}
|
|
55594
55532
|
async function maybeLoadKeytar() {
|
|
55595
55533
|
try {
|
|
@@ -55607,22 +55545,22 @@ async function maybeLoadKeytar() {
|
|
|
55607
55545
|
return null;
|
|
55608
55546
|
}
|
|
55609
55547
|
async function ensurePathPermissions(filePath) {
|
|
55610
|
-
const dir =
|
|
55611
|
-
await
|
|
55548
|
+
const dir = import_path14.default.dirname(filePath);
|
|
55549
|
+
await import_promises25.default.mkdir(dir, { recursive: true });
|
|
55612
55550
|
try {
|
|
55613
|
-
await
|
|
55551
|
+
await import_promises25.default.chmod(dir, 448);
|
|
55614
55552
|
} catch {
|
|
55615
55553
|
}
|
|
55616
55554
|
try {
|
|
55617
|
-
await
|
|
55555
|
+
await import_promises25.default.chmod(filePath, 384);
|
|
55618
55556
|
} catch {
|
|
55619
55557
|
}
|
|
55620
55558
|
}
|
|
55621
55559
|
async function writeJsonAtomic2(filePath, value) {
|
|
55622
|
-
await
|
|
55560
|
+
await import_promises25.default.mkdir(import_path14.default.dirname(filePath), { recursive: true });
|
|
55623
55561
|
const tmpPath = `${filePath}.tmp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
55624
|
-
await
|
|
55625
|
-
await
|
|
55562
|
+
await import_promises25.default.writeFile(tmpPath, JSON.stringify(value, null, 2) + "\n", "utf8");
|
|
55563
|
+
await import_promises25.default.rename(tmpPath, filePath);
|
|
55626
55564
|
}
|
|
55627
55565
|
async function writeSessionFileFallback(filePath, session) {
|
|
55628
55566
|
await writeJsonAtomic2(filePath, session);
|
|
@@ -55631,7 +55569,7 @@ async function writeSessionFileFallback(filePath, session) {
|
|
|
55631
55569
|
function createLocalSessionStore(params) {
|
|
55632
55570
|
const service = params?.service?.trim() || "remix-cli";
|
|
55633
55571
|
const account = params?.account?.trim() || "default";
|
|
55634
|
-
const filePath = params?.filePath?.trim() ||
|
|
55572
|
+
const filePath = params?.filePath?.trim() || import_path14.default.join(xdgConfigHome(), "remix", "session.json");
|
|
55635
55573
|
async function readKeytar() {
|
|
55636
55574
|
const keytar = await maybeLoadKeytar();
|
|
55637
55575
|
if (!keytar) return null;
|
|
@@ -55645,7 +55583,7 @@ function createLocalSessionStore(params) {
|
|
|
55645
55583
|
}
|
|
55646
55584
|
}
|
|
55647
55585
|
async function readFile() {
|
|
55648
|
-
const raw = await
|
|
55586
|
+
const raw = await import_promises25.default.readFile(filePath, "utf8").catch(() => null);
|
|
55649
55587
|
if (!raw) return null;
|
|
55650
55588
|
try {
|
|
55651
55589
|
const parsed = storedSessionSchema.safeParse(JSON.parse(raw));
|
|
@@ -55789,7 +55727,7 @@ function createSupabaseAuthHelpers(config2) {
|
|
|
55789
55727
|
};
|
|
55790
55728
|
}
|
|
55791
55729
|
|
|
55792
|
-
// node_modules/@remixhq/core/dist/chunk-
|
|
55730
|
+
// node_modules/@remixhq/core/dist/chunk-XCZRNB35.js
|
|
55793
55731
|
var DEFAULT_API_URL = "https://api.remix.one";
|
|
55794
55732
|
var DEFAULT_SUPABASE_URL = "https://xtfxwbckjpfmqubnsusu.supabase.co";
|
|
55795
55733
|
var DEFAULT_SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh0Znh3YmNranBmbXF1Ym5zdXN1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjA2MDEyMzAsImV4cCI6MjA3NjE3NzIzMH0.dzWGAWrK4CvrmHVHzf8w7JlUZohdap0ZPnLZnABMV8s";
|
|
@@ -55827,10 +55765,10 @@ async function resolveConfig(_opts) {
|
|
|
55827
55765
|
}
|
|
55828
55766
|
|
|
55829
55767
|
// node_modules/@remixhq/mcp/dist/index.js
|
|
55830
|
-
var
|
|
55768
|
+
var import_path15 = __toESM(require("path"), 1);
|
|
55831
55769
|
var import_child_process = require("child_process");
|
|
55832
55770
|
var import_fs3 = require("fs");
|
|
55833
|
-
var
|
|
55771
|
+
var import_path16 = __toESM(require("path"), 1);
|
|
55834
55772
|
async function createRemixTokenProvider(config2) {
|
|
55835
55773
|
const resolvedConfig = config2 ?? await resolveConfig();
|
|
55836
55774
|
const sessionStore = createLocalSessionStore();
|
|
@@ -56123,12 +56061,12 @@ function parsePositiveIntEnv(name, fallback) {
|
|
|
56123
56061
|
}
|
|
56124
56062
|
function parseAllowedRoots(raw) {
|
|
56125
56063
|
if (!raw) return null;
|
|
56126
|
-
const roots = raw.split(
|
|
56064
|
+
const roots = raw.split(import_path15.default.delimiter).map((entry) => entry.trim()).filter(Boolean).map((entry) => import_path15.default.resolve(entry));
|
|
56127
56065
|
return roots.length > 0 ? roots : null;
|
|
56128
56066
|
}
|
|
56129
56067
|
function isWithinRoot(root, candidate) {
|
|
56130
|
-
const relative =
|
|
56131
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
56068
|
+
const relative = import_path15.default.relative(root, candidate);
|
|
56069
|
+
return relative === "" || !relative.startsWith("..") && !import_path15.default.isAbsolute(relative);
|
|
56132
56070
|
}
|
|
56133
56071
|
function loadPolicy() {
|
|
56134
56072
|
return {
|
|
@@ -56140,7 +56078,7 @@ function loadPolicy() {
|
|
|
56140
56078
|
};
|
|
56141
56079
|
}
|
|
56142
56080
|
function resolvePolicyCwd(policy, cwd) {
|
|
56143
|
-
const resolved =
|
|
56081
|
+
const resolved = import_path15.default.resolve(cwd?.trim() || process.cwd());
|
|
56144
56082
|
if (!policy.allowedRepoRoots) return resolved;
|
|
56145
56083
|
if (policy.allowedRepoRoots.some((root) => isWithinRoot(root, resolved))) return resolved;
|
|
56146
56084
|
throw createPolicyError("Requested working directory is outside the allowed repository roots.", resolved);
|
|
@@ -56299,9 +56237,6 @@ var applyInputSchema = {
|
|
|
56299
56237
|
confirm: external_exports.boolean(),
|
|
56300
56238
|
allowBranchMismatch: external_exports.boolean().optional()
|
|
56301
56239
|
};
|
|
56302
|
-
var reAnchorInputSchema = {
|
|
56303
|
-
...applyInputSchema
|
|
56304
|
-
};
|
|
56305
56240
|
var requestMergeInputSchema = {
|
|
56306
56241
|
...commonRequestFieldsSchema
|
|
56307
56242
|
};
|
|
@@ -56414,7 +56349,7 @@ var initSyncDataSchema = external_exports.object({
|
|
|
56414
56349
|
repoRoot: external_exports.string(),
|
|
56415
56350
|
bindingMode: external_exports.enum(["legacy", "lane", "explicit_root"]).optional(),
|
|
56416
56351
|
createdCanonicalFamily: external_exports.boolean().optional(),
|
|
56417
|
-
baselineStatus: external_exports.enum(["seeded", "existing", "
|
|
56352
|
+
baselineStatus: external_exports.enum(["seeded", "existing", "baseline_missing", "requires_sync"]).optional()
|
|
56418
56353
|
});
|
|
56419
56354
|
var initQueuedDataSchema = external_exports.object({
|
|
56420
56355
|
queued: external_exports.literal(true),
|
|
@@ -56462,7 +56397,6 @@ var drainFinalizeQueueDataSchema = external_exports.object({
|
|
|
56462
56397
|
results: external_exports.array(genericRecordSchema)
|
|
56463
56398
|
});
|
|
56464
56399
|
var syncDataSchema = genericRecordSchema;
|
|
56465
|
-
var reAnchorDataSchema = genericRecordSchema;
|
|
56466
56400
|
var requestMergeDataSchema = genericRecordSchema;
|
|
56467
56401
|
var mergeRequestQueueDataSchema = external_exports.object({
|
|
56468
56402
|
queue: mergeRequestQueueSchema,
|
|
@@ -56538,7 +56472,6 @@ var addSuccessSchema = makeSuccessSchema(addDataSchema);
|
|
|
56538
56472
|
var recordTurnSuccessSchema = makeSuccessSchema(recordTurnDataSchema);
|
|
56539
56473
|
var drainFinalizeQueueSuccessSchema = makeSuccessSchema(drainFinalizeQueueDataSchema);
|
|
56540
56474
|
var syncSuccessSchema = makeSuccessSchema(syncDataSchema);
|
|
56541
|
-
var reAnchorSuccessSchema = makeSuccessSchema(reAnchorDataSchema);
|
|
56542
56475
|
var requestMergeSuccessSchema = makeSuccessSchema(requestMergeDataSchema);
|
|
56543
56476
|
var mergeRequestQueueSuccessSchema = makeSuccessSchema(mergeRequestQueueDataSchema);
|
|
56544
56477
|
var viewMergeRequestSuccessSchema = makeSuccessSchema(viewMergeRequestDataSchema);
|
|
@@ -56557,7 +56490,7 @@ var updateMemberRoleSuccessSchema = makeSuccessSchema(updateMemberRoleDataSchema
|
|
|
56557
56490
|
function getRiskLevel(status) {
|
|
56558
56491
|
if (status.recommendedAction === "reconcile") return "high";
|
|
56559
56492
|
if (status.recommendedAction === "choose_family" || status.recommendedAction === "await_finalize") return "medium";
|
|
56560
|
-
if (status.recommendedAction === "pull" || status.
|
|
56493
|
+
if (status.recommendedAction === "pull" || status.remote.incomingOpenMergeRequestCount) {
|
|
56561
56494
|
return "medium";
|
|
56562
56495
|
}
|
|
56563
56496
|
if (status.repo.branchMismatch || !status.repo.isGitRepo || !status.binding.isBound || !status.repo.worktree.isClean) return "medium";
|
|
@@ -56574,10 +56507,6 @@ function getRecommendedNextActions(status) {
|
|
|
56574
56507
|
return ["Run remix_collab_init to bind the repository to Remix before using any Remix collaboration mutation flow."];
|
|
56575
56508
|
case "pull":
|
|
56576
56509
|
return ["Run remix_collab_sync_preview, then remix_collab_sync_apply if the preview is acceptable. This pulls the server delta into the local working tree without rewriting local git history."];
|
|
56577
|
-
case "re_anchor":
|
|
56578
|
-
return [
|
|
56579
|
-
"Run remix_collab_re_anchor_preview, then remix_collab_re_anchor_apply. This seeds a local Remix baseline. It is required because no local baseline exists for this lane yet (fresh clone, deleted .remix/ state, or first init didn't seed) \u2014 not because of any specific git operation. After it succeeds, automatic hook recording can capture completed turns."
|
|
56580
|
-
];
|
|
56581
56510
|
case "record":
|
|
56582
56511
|
return [
|
|
56583
56512
|
"No MCP recording tool is required. Automatic hook finalization will capture the local boundary at the end of the completed turn; this covers agent edits, manual user edits, git commit, git pull, git merge, git rebase, and git reset."
|
|
@@ -56662,8 +56591,8 @@ async function initCollab(params) {
|
|
|
56662
56591
|
return {
|
|
56663
56592
|
data: syncResult,
|
|
56664
56593
|
warnings: collectResultWarnings(result),
|
|
56665
|
-
recommendedNextActions: syncResult.baselineStatus === "
|
|
56666
|
-
"This checkout has no local Remix baseline yet. Run
|
|
56594
|
+
recommendedNextActions: syncResult.baselineStatus === "baseline_missing" ? [
|
|
56595
|
+
"This checkout has no local Remix revision baseline yet. Run remix_collab_init or remix_collab_sync_preview/apply to seed one. After it succeeds, automatic hook recording can capture completed turns."
|
|
56667
56596
|
] : syncResult.baselineStatus === "requires_sync" ? [
|
|
56668
56597
|
"Run remix_collab_sync_preview, then remix_collab_sync_apply to pull the server delta and create the first local baseline for this checkout."
|
|
56669
56598
|
] : ["Run remix_collab_status to inspect sync, reconcile, and merge-request readiness before mutating bound-repo state."],
|
|
@@ -56766,26 +56695,6 @@ async function syncCollab(params) {
|
|
|
56766
56695
|
}
|
|
56767
56696
|
};
|
|
56768
56697
|
}
|
|
56769
|
-
async function reAnchor(params) {
|
|
56770
|
-
const api = await createCollabApiClient();
|
|
56771
|
-
const result = await collabReAnchor({
|
|
56772
|
-
api,
|
|
56773
|
-
cwd: params.cwd,
|
|
56774
|
-
dryRun: params.dryRun,
|
|
56775
|
-
allowBranchMismatch: params.allowBranchMismatch ?? false
|
|
56776
|
-
});
|
|
56777
|
-
return {
|
|
56778
|
-
data: result,
|
|
56779
|
-
warnings: collectWarnings(result.warnings),
|
|
56780
|
-
recommendedNextActions: params.dryRun ? [
|
|
56781
|
-
"Run remix_collab_re_anchor_apply with confirm=true to seed a local Remix baseline for this checkout. Re-anchor is for missing-baseline cases only and does not replace automatic hook recording for ordinary local content changes."
|
|
56782
|
-
] : [],
|
|
56783
|
-
logContext: {
|
|
56784
|
-
repoRoot: result.repoRoot,
|
|
56785
|
-
appId: result.currentAppId
|
|
56786
|
-
}
|
|
56787
|
-
};
|
|
56788
|
-
}
|
|
56789
56698
|
async function requestMerge(params) {
|
|
56790
56699
|
const api = await createCollabApiClient();
|
|
56791
56700
|
const drainWarnings = await drainBeforeMutation(api);
|
|
@@ -57502,22 +57411,25 @@ async function accessDebug(params) {
|
|
|
57502
57411
|
}
|
|
57503
57412
|
};
|
|
57504
57413
|
}
|
|
57505
|
-
var MARKER_REL_PATH =
|
|
57506
|
-
var LOG_REL_PATH =
|
|
57414
|
+
var MARKER_REL_PATH = import_path16.default.join(".remix", ".history-imported");
|
|
57415
|
+
var LOG_REL_PATH = import_path16.default.join(".remix", "history-import.log");
|
|
57507
57416
|
function shouldAutoSpawnHistoryImport(repoRoot) {
|
|
57508
57417
|
try {
|
|
57509
|
-
return !(0, import_fs3.existsSync)(
|
|
57418
|
+
return !(0, import_fs3.existsSync)(import_path16.default.join(repoRoot, MARKER_REL_PATH));
|
|
57510
57419
|
} catch {
|
|
57511
57420
|
return false;
|
|
57512
57421
|
}
|
|
57513
57422
|
}
|
|
57514
|
-
function
|
|
57515
|
-
|
|
57423
|
+
function isAutoSpawnEligibleBindingMode(bindingMode) {
|
|
57424
|
+
return bindingMode === "explicit_root";
|
|
57425
|
+
}
|
|
57426
|
+
function spawnHistoryImportDetached(repoRoot, options) {
|
|
57427
|
+
const remixDir = import_path16.default.join(repoRoot, ".remix");
|
|
57516
57428
|
try {
|
|
57517
57429
|
(0, import_fs3.mkdirSync)(remixDir, { recursive: true });
|
|
57518
57430
|
} catch {
|
|
57519
57431
|
}
|
|
57520
|
-
const logPath =
|
|
57432
|
+
const logPath = import_path16.default.join(repoRoot, LOG_REL_PATH);
|
|
57521
57433
|
const out = (0, import_fs3.openSync)(logPath, "a");
|
|
57522
57434
|
const err = (0, import_fs3.openSync)(logPath, "a");
|
|
57523
57435
|
const child = (0, import_child_process.spawn)(
|
|
@@ -57527,6 +57439,8 @@ function spawnHistoryImportDetached(repoRoot) {
|
|
|
57527
57439
|
"import",
|
|
57528
57440
|
"--repo",
|
|
57529
57441
|
repoRoot,
|
|
57442
|
+
"--before",
|
|
57443
|
+
options.cutoffAt,
|
|
57530
57444
|
// Include prompt text for parity with the CLI auto-spawn path:
|
|
57531
57445
|
// first-time UX is a lot worse if the dashboard renders every
|
|
57532
57446
|
// historical row as "(prompt not uploaded)".
|
|
@@ -57675,11 +57589,13 @@ function registerCollabTools(server, context) {
|
|
|
57675
57589
|
});
|
|
57676
57590
|
try {
|
|
57677
57591
|
const repoRoot = result && typeof result === "object" && "data" in result && result.data && typeof result.data.repoRoot === "string" ? result.data.repoRoot : null;
|
|
57678
|
-
|
|
57679
|
-
|
|
57592
|
+
const bindingMode = result && typeof result === "object" && "data" in result && result.data && typeof result.data.bindingMode === "string" ? result.data.bindingMode : null;
|
|
57593
|
+
if (repoRoot && isAutoSpawnEligibleBindingMode(bindingMode) && shouldAutoSpawnHistoryImport(repoRoot)) {
|
|
57594
|
+
const cutoffAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
57595
|
+
const spawned = spawnHistoryImportDetached(repoRoot, { cutoffAt });
|
|
57680
57596
|
context.logger.log({
|
|
57681
57597
|
level: "info",
|
|
57682
|
-
message: `history_import_auto_spawned pid=${spawned.pid ?? "?"} log=${spawned.logPath}`,
|
|
57598
|
+
message: `history_import_auto_spawned pid=${spawned.pid ?? "?"} log=${spawned.logPath} cutoffAt=${cutoffAt}`,
|
|
57683
57599
|
tool: "remix_collab_init",
|
|
57684
57600
|
repoRoot
|
|
57685
57601
|
});
|
|
@@ -57783,31 +57699,6 @@ function registerCollabTools(server, context) {
|
|
|
57783
57699
|
return syncCollab({ cwd, dryRun: false, allowBranchMismatch: input.allowBranchMismatch ?? false });
|
|
57784
57700
|
}
|
|
57785
57701
|
});
|
|
57786
|
-
registerTool(server, context, {
|
|
57787
|
-
name: "remix_collab_re_anchor_preview",
|
|
57788
|
-
description: "Preview whether this checkout needs a fresh local Remix baseline. Use only when status reports `re_anchor` (no local baseline exists for this lane yet \u2014 fresh clone, deleted `.remix/` state, or first init didn't seed). Re-anchor does not replace automatic hook recording; ordinary local content changes (including merges, pulls, and rebases) are captured at the completed-turn boundary, not by re-anchor.",
|
|
57789
|
-
access: "read",
|
|
57790
|
-
inputSchema: previewInputSchema,
|
|
57791
|
-
outputSchema: reAnchorSuccessSchema,
|
|
57792
|
-
run: async (args) => {
|
|
57793
|
-
const input = external_exports.object(previewInputSchema).parse(args);
|
|
57794
|
-
const cwd = resolvePolicyCwd(context.policy, input.cwd);
|
|
57795
|
-
return reAnchor({ cwd, dryRun: true });
|
|
57796
|
-
}
|
|
57797
|
-
});
|
|
57798
|
-
registerTool(server, context, {
|
|
57799
|
-
name: "remix_collab_re_anchor_apply",
|
|
57800
|
-
description: "Establish a local Remix baseline for the current checkout against the existing app head, without rewriting the local checkout afterward. Required only when status reports `re_anchor` (missing local baseline). It does not replace automatic hook recording \u2014 local commits, pulls, merges, and rebases are still captured at the completed-turn boundary.",
|
|
57801
|
-
access: "local_write",
|
|
57802
|
-
inputSchema: reAnchorInputSchema,
|
|
57803
|
-
outputSchema: reAnchorSuccessSchema,
|
|
57804
|
-
run: async (args) => {
|
|
57805
|
-
const input = external_exports.object(reAnchorInputSchema).parse(args);
|
|
57806
|
-
assertConfirm(input.confirm, "remix_collab_re_anchor_apply");
|
|
57807
|
-
const cwd = resolvePolicyCwd(context.policy, input.cwd);
|
|
57808
|
-
return reAnchor({ cwd, dryRun: false, allowBranchMismatch: input.allowBranchMismatch ?? false });
|
|
57809
|
-
}
|
|
57810
|
-
});
|
|
57811
57702
|
registerTool(server, context, {
|
|
57812
57703
|
name: "remix_collab_request_merge",
|
|
57813
57704
|
description: "Open a prompt-backed Remix merge request from the current bound repository to its upstream app instead of merging locally with raw git.",
|
|
@@ -59572,6 +59463,7 @@ function createRemixMcpServer(params) {
|
|
|
59572
59463
|
}
|
|
59573
59464
|
|
|
59574
59465
|
// src/hook-auth.ts
|
|
59466
|
+
var HOOK_API_REQUEST_TIMEOUT_MS = 6e4;
|
|
59575
59467
|
async function createHookCollabApiClient() {
|
|
59576
59468
|
const config2 = await resolveConfig();
|
|
59577
59469
|
const sessionStore = createLocalSessionStore();
|
|
@@ -59584,18 +59476,19 @@ async function createHookCollabApiClient() {
|
|
|
59584
59476
|
}
|
|
59585
59477
|
});
|
|
59586
59478
|
return createApiClient(config2, {
|
|
59587
|
-
tokenProvider
|
|
59479
|
+
tokenProvider,
|
|
59480
|
+
defaultRequestTimeoutMs: HOOK_API_REQUEST_TIMEOUT_MS
|
|
59588
59481
|
});
|
|
59589
59482
|
}
|
|
59590
59483
|
|
|
59591
59484
|
// src/hook-diagnostics.ts
|
|
59592
59485
|
var import_node_crypto2 = require("crypto");
|
|
59593
|
-
var
|
|
59486
|
+
var import_promises27 = __toESM(require("fs/promises"), 1);
|
|
59594
59487
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
59595
59488
|
var import_node_path7 = __toESM(require("path"), 1);
|
|
59596
59489
|
|
|
59597
59490
|
// src/hook-state.ts
|
|
59598
|
-
var
|
|
59491
|
+
var import_promises26 = __toESM(require("fs/promises"), 1);
|
|
59599
59492
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
59600
59493
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
59601
59494
|
var import_node_crypto = require("crypto");
|
|
@@ -59700,7 +59593,7 @@ function getPendingTurnStateRootPath() {
|
|
|
59700
59593
|
return stateRoot();
|
|
59701
59594
|
}
|
|
59702
59595
|
async function loadPendingTurnState(sessionId) {
|
|
59703
|
-
const raw = await
|
|
59596
|
+
const raw = await import_promises26.default.readFile(statePath(sessionId), "utf8").catch(() => null);
|
|
59704
59597
|
if (!raw) return null;
|
|
59705
59598
|
try {
|
|
59706
59599
|
const parsed = JSON.parse(raw);
|
|
@@ -59727,7 +59620,7 @@ async function loadPendingTurnState(sessionId) {
|
|
|
59727
59620
|
}
|
|
59728
59621
|
async function listPendingTurnStateSummaries() {
|
|
59729
59622
|
const root = stateRoot();
|
|
59730
|
-
const entries = await
|
|
59623
|
+
const entries = await import_promises26.default.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
59731
59624
|
const sessionIds = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.replace(/\.json$/, "")).sort((a2, b) => a2.localeCompare(b));
|
|
59732
59625
|
const states = await Promise.all(sessionIds.map((sessionId) => loadPendingTurnState(sessionId)));
|
|
59733
59626
|
return states.filter((state) => state !== null).sort((a2, b) => b.submittedAt.localeCompare(a2.submittedAt)).map((state) => summarizePendingTurnState(state));
|
|
@@ -59736,7 +59629,7 @@ async function listPendingTurnStateSummaries() {
|
|
|
59736
59629
|
// package.json
|
|
59737
59630
|
var package_default = {
|
|
59738
59631
|
name: "@remixhq/claude-plugin",
|
|
59739
|
-
version: "0.1.
|
|
59632
|
+
version: "0.1.23",
|
|
59740
59633
|
description: "Claude Code plugin for Remix collaboration workflows",
|
|
59741
59634
|
homepage: "https://github.com/RemixDotOne/remix-claude-plugin",
|
|
59742
59635
|
license: "MIT",
|
|
@@ -59770,12 +59663,12 @@ var package_default = {
|
|
|
59770
59663
|
postbuild: `node -e "const fs=require('node:fs'); for (const p of ['dist/mcp-server.cjs','dist/hook-pre-git.cjs','dist/hook-user-prompt.cjs','dist/hook-post-collab.cjs','dist/hook-stop-collab.cjs']) fs.chmodSync(p, 0o755);"`,
|
|
59771
59664
|
dev: "tsx src/mcp-server.ts",
|
|
59772
59665
|
typecheck: "tsc -p tsconfig.json --noEmit",
|
|
59773
|
-
test: "node --import tsx --test src/**/*.test.ts",
|
|
59666
|
+
test: "node --import tsx --test 'src/**/*.test.ts'",
|
|
59774
59667
|
prepack: "npm run build"
|
|
59775
59668
|
},
|
|
59776
59669
|
dependencies: {
|
|
59777
|
-
"@remixhq/core": "^0.1.
|
|
59778
|
-
"@remixhq/mcp": "^0.1.
|
|
59670
|
+
"@remixhq/core": "^0.1.18",
|
|
59671
|
+
"@remixhq/mcp": "^0.1.18"
|
|
59779
59672
|
},
|
|
59780
59673
|
devDependencies: {
|
|
59781
59674
|
"@types/node": "^25.4.0",
|
|
@@ -59817,7 +59710,7 @@ function clampEventLimit(limit) {
|
|
|
59817
59710
|
return Math.max(1, Math.min(MAX_EVENT_LIMIT, Math.trunc(limit)));
|
|
59818
59711
|
}
|
|
59819
59712
|
async function readEventsFromFile(filePath) {
|
|
59820
|
-
const raw = await
|
|
59713
|
+
const raw = await import_promises27.default.readFile(filePath, "utf8").catch(() => null);
|
|
59821
59714
|
if (!raw) return [];
|
|
59822
59715
|
return raw.split("\n").map((line) => line.trim()).filter(Boolean).flatMap((line) => {
|
|
59823
59716
|
try {
|