@mstar-harness/cli 3.6.0-alpha.3 → 3.6.0
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/dist/mstar-harness.js +386 -110
- package/package.json +1 -1
package/dist/mstar-harness.js
CHANGED
|
@@ -6,22 +6,38 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
7
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
function __accessProp(key) {
|
|
10
|
+
return this[key];
|
|
11
|
+
}
|
|
12
|
+
var __toESMCache_node;
|
|
13
|
+
var __toESMCache_esm;
|
|
9
14
|
var __toESM = (mod, isNodeMode, target) => {
|
|
15
|
+
var canCache = mod != null && typeof mod === "object";
|
|
16
|
+
if (canCache) {
|
|
17
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
18
|
+
var cached = cache.get(mod);
|
|
19
|
+
if (cached)
|
|
20
|
+
return cached;
|
|
21
|
+
}
|
|
10
22
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
11
23
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
if (mod && typeof mod === "object" || typeof mod === "function") {
|
|
25
|
+
for (let key of __getOwnPropNames(mod))
|
|
26
|
+
if (!__hasOwnProp.call(to, key))
|
|
27
|
+
__defProp(to, key, {
|
|
28
|
+
get: __accessProp.bind(mod, key),
|
|
29
|
+
enumerable: true
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (canCache)
|
|
33
|
+
cache.set(mod, to);
|
|
18
34
|
return to;
|
|
19
35
|
};
|
|
20
36
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
21
37
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
22
38
|
|
|
23
|
-
// ../../node_modules/cli-width/index.js
|
|
24
|
-
var require_cli_width = __commonJS((exports, module)
|
|
39
|
+
// ../../node_modules/.bun/cli-width@4.1.0/node_modules/cli-width/index.js
|
|
40
|
+
var require_cli_width = __commonJS(function(exports, module) {
|
|
25
41
|
module.exports = cliWidth;
|
|
26
42
|
function normalizeOpts(options) {
|
|
27
43
|
const defaultOpts = {
|
|
@@ -60,8 +76,8 @@ var require_cli_width = __commonJS((exports, module) => {
|
|
|
60
76
|
}
|
|
61
77
|
});
|
|
62
78
|
|
|
63
|
-
// ../../node_modules/mute-stream/lib/index.js
|
|
64
|
-
var require_lib = __commonJS((exports, module)
|
|
79
|
+
// ../../node_modules/.bun/mute-stream@3.0.0/node_modules/mute-stream/lib/index.js
|
|
80
|
+
var require_lib = __commonJS(function(exports, module) {
|
|
65
81
|
var Stream = __require("stream");
|
|
66
82
|
|
|
67
83
|
class MuteStream extends Stream {
|
|
@@ -180,8 +196,8 @@ var require_lib = __commonJS((exports, module) => {
|
|
|
180
196
|
module.exports = MuteStream;
|
|
181
197
|
});
|
|
182
198
|
|
|
183
|
-
// ../../node_modules/picocolors/picocolors.js
|
|
184
|
-
var require_picocolors = __commonJS((exports, module)
|
|
199
|
+
// ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
200
|
+
var require_picocolors = __commonJS(function(exports, module) {
|
|
185
201
|
var p = process || {};
|
|
186
202
|
var argv = p.argv || [];
|
|
187
203
|
var env = p.env || {};
|
|
@@ -250,8 +266,8 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
250
266
|
module.exports.createColors = createColors;
|
|
251
267
|
});
|
|
252
268
|
|
|
253
|
-
// ../../node_modules/commander/lib/error.js
|
|
254
|
-
var require_error = __commonJS((exports)
|
|
269
|
+
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/error.js
|
|
270
|
+
var require_error = __commonJS(function(exports) {
|
|
255
271
|
class CommanderError extends Error {
|
|
256
272
|
constructor(exitCode, code, message) {
|
|
257
273
|
super(message);
|
|
@@ -274,8 +290,8 @@ var require_error = __commonJS((exports) => {
|
|
|
274
290
|
exports.InvalidArgumentError = InvalidArgumentError;
|
|
275
291
|
});
|
|
276
292
|
|
|
277
|
-
// ../../node_modules/commander/lib/argument.js
|
|
278
|
-
var require_argument = __commonJS((exports)
|
|
293
|
+
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/argument.js
|
|
294
|
+
var require_argument = __commonJS(function(exports) {
|
|
279
295
|
var { InvalidArgumentError } = require_error();
|
|
280
296
|
|
|
281
297
|
class Argument {
|
|
@@ -354,8 +370,8 @@ var require_argument = __commonJS((exports) => {
|
|
|
354
370
|
exports.humanReadableArgName = humanReadableArgName;
|
|
355
371
|
});
|
|
356
372
|
|
|
357
|
-
// ../../node_modules/commander/lib/help.js
|
|
358
|
-
var require_help = __commonJS((exports)
|
|
373
|
+
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/help.js
|
|
374
|
+
var require_help = __commonJS(function(exports) {
|
|
359
375
|
var { humanReadableArgName } = require_argument();
|
|
360
376
|
|
|
361
377
|
class Help {
|
|
@@ -711,8 +727,8 @@ ${itemIndentStr}`);
|
|
|
711
727
|
exports.stripColor = stripColor;
|
|
712
728
|
});
|
|
713
729
|
|
|
714
|
-
// ../../node_modules/commander/lib/option.js
|
|
715
|
-
var require_option = __commonJS((exports)
|
|
730
|
+
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/option.js
|
|
731
|
+
var require_option = __commonJS(function(exports) {
|
|
716
732
|
var { InvalidArgumentError } = require_error();
|
|
717
733
|
|
|
718
734
|
class Option {
|
|
@@ -895,8 +911,8 @@ var require_option = __commonJS((exports) => {
|
|
|
895
911
|
exports.DualOptions = DualOptions;
|
|
896
912
|
});
|
|
897
913
|
|
|
898
|
-
// ../../node_modules/commander/lib/suggestSimilar.js
|
|
899
|
-
var require_suggestSimilar = __commonJS((exports)
|
|
914
|
+
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/suggestSimilar.js
|
|
915
|
+
var require_suggestSimilar = __commonJS(function(exports) {
|
|
900
916
|
var maxDistance = 3;
|
|
901
917
|
function editDistance(a, b) {
|
|
902
918
|
if (Math.abs(a.length - b.length) > maxDistance)
|
|
@@ -968,8 +984,8 @@ var require_suggestSimilar = __commonJS((exports) => {
|
|
|
968
984
|
exports.suggestSimilar = suggestSimilar;
|
|
969
985
|
});
|
|
970
986
|
|
|
971
|
-
// ../../node_modules/commander/lib/command.js
|
|
972
|
-
var require_command = __commonJS((exports)
|
|
987
|
+
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/command.js
|
|
988
|
+
var require_command = __commonJS(function(exports) {
|
|
973
989
|
var EventEmitter = __require("node:events").EventEmitter;
|
|
974
990
|
var childProcess = __require("node:child_process");
|
|
975
991
|
var path2 = __require("node:path");
|
|
@@ -1222,7 +1238,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1222
1238
|
this._exitCallback = (err) => {
|
|
1223
1239
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
1224
1240
|
throw err;
|
|
1225
|
-
}
|
|
1241
|
+
}
|
|
1226
1242
|
};
|
|
1227
1243
|
}
|
|
1228
1244
|
return this;
|
|
@@ -2323,8 +2339,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2323
2339
|
exports.useColor = useColor;
|
|
2324
2340
|
});
|
|
2325
2341
|
|
|
2326
|
-
// ../../node_modules/commander/index.js
|
|
2327
|
-
var require_commander = __commonJS((exports)
|
|
2342
|
+
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/index.js
|
|
2343
|
+
var require_commander = __commonJS(function(exports) {
|
|
2328
2344
|
var { Argument } = require_argument();
|
|
2329
2345
|
var { Command } = require_command();
|
|
2330
2346
|
var { CommanderError, InvalidArgumentError } = require_error();
|
|
@@ -2343,8 +2359,8 @@ var require_commander = __commonJS((exports) => {
|
|
|
2343
2359
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
2344
2360
|
});
|
|
2345
2361
|
|
|
2346
|
-
// ../../node_modules/picocolors/picocolors.js
|
|
2347
|
-
var require_picocolors2 = __commonJS((exports, module)
|
|
2362
|
+
// ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
2363
|
+
var require_picocolors2 = __commonJS(function(exports, module) {
|
|
2348
2364
|
var p = process || {};
|
|
2349
2365
|
var argv = p.argv || [];
|
|
2350
2366
|
var env = p.env || {};
|
|
@@ -2415,10 +2431,10 @@ var require_picocolors2 = __commonJS((exports, module) => {
|
|
|
2415
2431
|
|
|
2416
2432
|
// src/index.ts
|
|
2417
2433
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
2434
|
+
import { createHash, randomUUID as randomUUID3 } from "crypto";
|
|
2418
2435
|
import fs8 from "fs";
|
|
2419
2436
|
import path12 from "path";
|
|
2420
|
-
|
|
2421
|
-
// ../../node_modules/@inquirer/core/dist/lib/key.js
|
|
2437
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/key.js
|
|
2422
2438
|
var keybindings = ["emacs", "vim"];
|
|
2423
2439
|
var keybindingLookup = new Set(keybindings);
|
|
2424
2440
|
function isKeybinding(value) {
|
|
@@ -2435,7 +2451,7 @@ var isDownKey = (key, keybindings2 = []) => key.name === "down" || keybindings2.
|
|
|
2435
2451
|
var isBackspaceKey = (key) => key.name === "backspace";
|
|
2436
2452
|
var isNumberKey = (key) => "1234567890".includes(key.name);
|
|
2437
2453
|
var isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
2438
|
-
// ../../node_modules/@inquirer/core/dist/lib/errors.js
|
|
2454
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/errors.js
|
|
2439
2455
|
class AbortPromptError extends Error {
|
|
2440
2456
|
name = "AbortPromptError";
|
|
2441
2457
|
message = "Prompt was aborted";
|
|
@@ -2461,10 +2477,10 @@ class HookError extends Error {
|
|
|
2461
2477
|
class ValidationError extends Error {
|
|
2462
2478
|
name = "ValidationError";
|
|
2463
2479
|
}
|
|
2464
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-state.js
|
|
2480
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/use-state.js
|
|
2465
2481
|
import { AsyncResource as AsyncResource2 } from "node:async_hooks";
|
|
2466
2482
|
|
|
2467
|
-
// ../../node_modules/@inquirer/core/dist/lib/hook-engine.js
|
|
2483
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/hook-engine.js
|
|
2468
2484
|
import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
|
|
2469
2485
|
var hookStorage = new AsyncLocalStorage;
|
|
2470
2486
|
function createStore(rl) {
|
|
@@ -2569,7 +2585,7 @@ var effectScheduler = {
|
|
|
2569
2585
|
}
|
|
2570
2586
|
};
|
|
2571
2587
|
|
|
2572
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-state.js
|
|
2588
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/use-state.js
|
|
2573
2589
|
function isFactory(value) {
|
|
2574
2590
|
return typeof value === "function";
|
|
2575
2591
|
}
|
|
@@ -2578,7 +2594,7 @@ function isReducer(value) {
|
|
|
2578
2594
|
}
|
|
2579
2595
|
function useState(defaultValue) {
|
|
2580
2596
|
return withPointer((pointer) => {
|
|
2581
|
-
const setState = AsyncResource2.bind(function
|
|
2597
|
+
const setState = AsyncResource2.bind(function setState2(newValue) {
|
|
2582
2598
|
const currentValue = pointer.get();
|
|
2583
2599
|
const nextValue = isReducer(newValue) ? newValue(currentValue) : newValue;
|
|
2584
2600
|
if (!Object.is(currentValue, nextValue)) {
|
|
@@ -2595,7 +2611,7 @@ function useState(defaultValue) {
|
|
|
2595
2611
|
});
|
|
2596
2612
|
}
|
|
2597
2613
|
|
|
2598
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-effect.js
|
|
2614
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/use-effect.js
|
|
2599
2615
|
function useEffect(cb, depArray) {
|
|
2600
2616
|
withPointer((pointer) => {
|
|
2601
2617
|
const oldDeps = pointer.get();
|
|
@@ -2607,10 +2623,10 @@ function useEffect(cb, depArray) {
|
|
|
2607
2623
|
});
|
|
2608
2624
|
}
|
|
2609
2625
|
|
|
2610
|
-
// ../../node_modules/@inquirer/core/dist/lib/theme.js
|
|
2626
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/theme.js
|
|
2611
2627
|
import { styleText } from "node:util";
|
|
2612
2628
|
|
|
2613
|
-
// ../../node_modules/@inquirer/figures/dist/index.js
|
|
2629
|
+
// ../../node_modules/.bun/@inquirer+figures@2.0.9/node_modules/@inquirer/figures/dist/index.js
|
|
2614
2630
|
import process2 from "node:process";
|
|
2615
2631
|
function isUnicodeSupported() {
|
|
2616
2632
|
if (!process2.platform.startsWith("win")) {
|
|
@@ -2899,7 +2915,7 @@ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
|
2899
2915
|
var dist_default = figures;
|
|
2900
2916
|
var replacements = Object.entries(specialMainSymbols);
|
|
2901
2917
|
|
|
2902
|
-
// ../../node_modules/@inquirer/core/dist/lib/theme.js
|
|
2918
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/theme.js
|
|
2903
2919
|
var defaultTheme = {
|
|
2904
2920
|
prefix: {
|
|
2905
2921
|
idle: styleText("blue", "?"),
|
|
@@ -2927,7 +2943,7 @@ function getDefaultTheme() {
|
|
|
2927
2943
|
};
|
|
2928
2944
|
}
|
|
2929
2945
|
|
|
2930
|
-
// ../../node_modules/@inquirer/core/dist/lib/make-theme.js
|
|
2946
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/make-theme.js
|
|
2931
2947
|
function isPlainObject(value) {
|
|
2932
2948
|
if (typeof value !== "object" || value === null)
|
|
2933
2949
|
return false;
|
|
@@ -2955,7 +2971,7 @@ function makeTheme(...themes) {
|
|
|
2955
2971
|
return deepMerge(...themesToMerge);
|
|
2956
2972
|
}
|
|
2957
2973
|
|
|
2958
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-prefix.js
|
|
2974
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/use-prefix.js
|
|
2959
2975
|
function usePrefix({ status = "idle", theme }) {
|
|
2960
2976
|
const [showLoader, setShowLoader] = useState(false);
|
|
2961
2977
|
const [tick, setTick] = useState(0);
|
|
@@ -2985,7 +3001,7 @@ function usePrefix({ status = "idle", theme }) {
|
|
|
2985
3001
|
const iconName = status === "loading" ? "idle" : status;
|
|
2986
3002
|
return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
|
|
2987
3003
|
}
|
|
2988
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-memo.js
|
|
3004
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/use-memo.js
|
|
2989
3005
|
function useMemo(fn, dependencies) {
|
|
2990
3006
|
return withPointer((pointer) => {
|
|
2991
3007
|
const prev = pointer.get();
|
|
@@ -2997,11 +3013,11 @@ function useMemo(fn, dependencies) {
|
|
|
2997
3013
|
return prev.value;
|
|
2998
3014
|
});
|
|
2999
3015
|
}
|
|
3000
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-ref.js
|
|
3016
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/use-ref.js
|
|
3001
3017
|
function useRef(val) {
|
|
3002
3018
|
return useState({ current: val })[0];
|
|
3003
3019
|
}
|
|
3004
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-keypress.js
|
|
3020
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/use-keypress.js
|
|
3005
3021
|
function useKeypress(userHandler) {
|
|
3006
3022
|
const signal = useRef(userHandler);
|
|
3007
3023
|
signal.current = userHandler;
|
|
@@ -3019,10 +3035,10 @@ function useKeypress(userHandler) {
|
|
|
3019
3035
|
};
|
|
3020
3036
|
}, []);
|
|
3021
3037
|
}
|
|
3022
|
-
// ../../node_modules/@inquirer/core/dist/lib/utils.js
|
|
3038
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/utils.js
|
|
3023
3039
|
var import_cli_width = __toESM(require_cli_width(), 1);
|
|
3024
3040
|
|
|
3025
|
-
// ../../node_modules/fast-string-truncated-width/dist/utils.js
|
|
3041
|
+
// ../../node_modules/.bun/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
|
|
3026
3042
|
var getCodePointsLength = (() => {
|
|
3027
3043
|
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
3028
3044
|
return (input) => {
|
|
@@ -3041,7 +3057,7 @@ var isWideNotCJKTNotEmoji = (x) => {
|
|
|
3041
3057
|
return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
3042
3058
|
};
|
|
3043
3059
|
|
|
3044
|
-
// ../../node_modules/fast-string-truncated-width/dist/index.js
|
|
3060
|
+
// ../../node_modules/.bun/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/index.js
|
|
3045
3061
|
var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
3046
3062
|
var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
3047
3063
|
var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
|
|
@@ -3140,7 +3156,7 @@ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {})
|
|
|
3140
3156
|
};
|
|
3141
3157
|
var dist_default2 = getStringTruncatedWidth;
|
|
3142
3158
|
|
|
3143
|
-
// ../../node_modules/fast-string-width/dist/index.js
|
|
3159
|
+
// ../../node_modules/.bun/fast-string-width@3.0.2/node_modules/fast-string-width/dist/index.js
|
|
3144
3160
|
var NO_TRUNCATION2 = {
|
|
3145
3161
|
limit: Infinity,
|
|
3146
3162
|
ellipsis: "",
|
|
@@ -3151,7 +3167,7 @@ var fastStringWidth = (input, options = {}) => {
|
|
|
3151
3167
|
};
|
|
3152
3168
|
var dist_default3 = fastStringWidth;
|
|
3153
3169
|
|
|
3154
|
-
// ../../node_modules/fast-wrap-ansi/lib/main.js
|
|
3170
|
+
// ../../node_modules/.bun/fast-wrap-ansi@0.2.2/node_modules/fast-wrap-ansi/lib/main.js
|
|
3155
3171
|
var ESC = "\x1B";
|
|
3156
3172
|
var CSI = "\u009b";
|
|
3157
3173
|
var END_CODE = 39;
|
|
@@ -3363,7 +3379,7 @@ function wrapAnsi(string, columns, options) {
|
|
|
3363
3379
|
`);
|
|
3364
3380
|
}
|
|
3365
3381
|
|
|
3366
|
-
// ../../node_modules/@inquirer/core/dist/lib/utils.js
|
|
3382
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/utils.js
|
|
3367
3383
|
function breakLines(content, width) {
|
|
3368
3384
|
return content.split(`
|
|
3369
3385
|
`).flatMap((line) => wrapAnsi(line, width, { trim: false, wordWrap: false }).split(`
|
|
@@ -3374,7 +3390,7 @@ function readlineWidth() {
|
|
|
3374
3390
|
return import_cli_width.default({ defaultWidth: 80, output: readline().output });
|
|
3375
3391
|
}
|
|
3376
3392
|
|
|
3377
|
-
// ../../node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
|
|
3393
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
|
|
3378
3394
|
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
3379
3395
|
const state = useRef({
|
|
3380
3396
|
lastPointer: active,
|
|
@@ -3440,12 +3456,12 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
|
3440
3456
|
return pageBuffer.filter((line) => typeof line === "string").join(`
|
|
3441
3457
|
`);
|
|
3442
3458
|
}
|
|
3443
|
-
// ../../node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
3459
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
3444
3460
|
var import_mute_stream = __toESM(require_lib(), 1);
|
|
3445
3461
|
import * as readline2 from "node:readline";
|
|
3446
3462
|
import { AsyncResource as AsyncResource3 } from "node:async_hooks";
|
|
3447
3463
|
|
|
3448
|
-
// ../../node_modules/signal-exit/dist/mjs/signals.js
|
|
3464
|
+
// ../../node_modules/.bun/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/signals.js
|
|
3449
3465
|
var signals = [];
|
|
3450
3466
|
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
3451
3467
|
if (process.platform !== "win32") {
|
|
@@ -3455,7 +3471,7 @@ if (process.platform === "linux") {
|
|
|
3455
3471
|
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
3456
3472
|
}
|
|
3457
3473
|
|
|
3458
|
-
// ../../node_modules/signal-exit/dist/mjs/index.js
|
|
3474
|
+
// ../../node_modules/.bun/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js
|
|
3459
3475
|
var processOk = (process3) => !!process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
|
|
3460
3476
|
var kExitEmitter = Symbol.for("signal-exit emitter");
|
|
3461
3477
|
var global = globalThis;
|
|
@@ -3653,10 +3669,10 @@ var {
|
|
|
3653
3669
|
unload
|
|
3654
3670
|
} = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
|
|
3655
3671
|
|
|
3656
|
-
// ../../node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
3672
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
3657
3673
|
import { stripVTControlCharacters } from "node:util";
|
|
3658
3674
|
|
|
3659
|
-
// ../../node_modules/@inquirer/ansi/dist/index.js
|
|
3675
|
+
// ../../node_modules/.bun/@inquirer+ansi@2.0.8/node_modules/@inquirer/ansi/dist/index.js
|
|
3660
3676
|
var ESC2 = "\x1B[";
|
|
3661
3677
|
var cursorLeft = ESC2 + "G";
|
|
3662
3678
|
var cursorHide = ESC2 + "?25l";
|
|
@@ -3672,7 +3688,7 @@ var cursorTo = (x, y) => {
|
|
|
3672
3688
|
var eraseLine = ESC2 + "2K";
|
|
3673
3689
|
var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
|
|
3674
3690
|
|
|
3675
|
-
// ../../node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
3691
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
3676
3692
|
var height = (content) => content.split(`
|
|
3677
3693
|
`).length;
|
|
3678
3694
|
var lastLine = (content) => content.split(`
|
|
@@ -3738,7 +3754,7 @@ class ScreenManager {
|
|
|
3738
3754
|
}
|
|
3739
3755
|
}
|
|
3740
3756
|
|
|
3741
|
-
// ../../node_modules/@inquirer/core/dist/lib/promise-polyfill.js
|
|
3757
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/promise-polyfill.js
|
|
3742
3758
|
class PromisePolyfill extends Promise {
|
|
3743
3759
|
static withResolver() {
|
|
3744
3760
|
let resolve;
|
|
@@ -3751,7 +3767,7 @@ class PromisePolyfill extends Promise {
|
|
|
3751
3767
|
}
|
|
3752
3768
|
}
|
|
3753
3769
|
|
|
3754
|
-
// ../../node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
3770
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
3755
3771
|
import path from "node:path";
|
|
3756
3772
|
var nativeSetImmediate = globalThis.setImmediate;
|
|
3757
3773
|
function getCallSites() {
|
|
@@ -3862,7 +3878,7 @@ function createPrompt(view) {
|
|
|
3862
3878
|
};
|
|
3863
3879
|
return prompt;
|
|
3864
3880
|
}
|
|
3865
|
-
// ../../node_modules/@inquirer/core/dist/lib/Separator.js
|
|
3881
|
+
// ../../node_modules/.bun/@inquirer+core@12.0.2+1c220d1d55e2409f/node_modules/@inquirer/core/dist/lib/Separator.js
|
|
3866
3882
|
import { styleText as styleText2 } from "node:util";
|
|
3867
3883
|
class Separator {
|
|
3868
3884
|
separator = styleText2("dim", Array.from({ length: 15 }).join(dist_default.line));
|
|
@@ -3876,7 +3892,7 @@ class Separator {
|
|
|
3876
3892
|
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
3877
3893
|
}
|
|
3878
3894
|
}
|
|
3879
|
-
// ../../node_modules/@inquirer/select/dist/index.js
|
|
3895
|
+
// ../../node_modules/.bun/@inquirer+select@5.2.4+1c220d1d55e2409f/node_modules/@inquirer/select/dist/index.js
|
|
3880
3896
|
import { styleText as styleText3 } from "node:util";
|
|
3881
3897
|
var selectTheme = {
|
|
3882
3898
|
icon: { cursor: dist_default.pointer },
|
|
@@ -4051,7 +4067,7 @@ var dist_default4 = createPrompt((config, done) => {
|
|
|
4051
4067
|
// src/index.ts
|
|
4052
4068
|
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
4053
4069
|
|
|
4054
|
-
// ../../node_modules/commander/esm.mjs
|
|
4070
|
+
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/esm.mjs
|
|
4055
4071
|
var import__ = __toESM(require_commander(), 1);
|
|
4056
4072
|
var {
|
|
4057
4073
|
program,
|
|
@@ -8544,6 +8560,9 @@ function prReviewSeatPrompt(opts) {
|
|
|
8544
8560
|
if (!isAbsolute9(worktreePath)) {
|
|
8545
8561
|
throw new TypeError(`prReviewSeatPrompt: worktreePath must be an absolute path - got ${JSON.stringify(opts.worktreePath)}`);
|
|
8546
8562
|
}
|
|
8563
|
+
if (opts.diffFile !== undefined && opts.diffFile !== "" && !isAbsolute9(opts.diffFile)) {
|
|
8564
|
+
throw new TypeError(`prReviewSeatPrompt: diffFile must be an absolute path - got ${JSON.stringify(opts.diffFile)}`);
|
|
8565
|
+
}
|
|
8547
8566
|
const slug = `${domain}-${seat}`;
|
|
8548
8567
|
const lines = [];
|
|
8549
8568
|
lines.push(`# PR review audit seat \u2014 Stage ${opts.stage}${opts.securitySeat === true ? " (security)" : ""}`);
|
|
@@ -8569,6 +8588,9 @@ function prReviewSeatPrompt(opts) {
|
|
|
8569
8588
|
const sections = opts.stage === 1 ? tier === "quick" ? "Scoping, Evidence rules" : "Review pipeline, Worktree isolation, Scoping, Evidence rules" : "Merge class, Attack and vet, Evidence rules, Sizing & change shape";
|
|
8570
8589
|
lines.push(`1. \`${prReviewRef}\` \u2014 read at least these sections: ${sections}.`);
|
|
8571
8590
|
lines.push(`2. The review worktree: \`${worktreePath}\` \u2014 your ONLY working directory this session; read-only (no edits, no fixes, no stash, no commits, no posts).`);
|
|
8591
|
+
if (opts.diffFile) {
|
|
8592
|
+
lines.push(`- Read the pinned diff snapshot FIRST: \`${opts.diffFile}\` \u2014 it is the review's diff basis (already computed at setup); read it before opening files.`);
|
|
8593
|
+
}
|
|
8572
8594
|
if (opts.stage === 2) {
|
|
8573
8595
|
lines.push(`3. \`${join15(skillRoot, "references", "finding-format.md")}\` \u2014 the template every finding follows.`);
|
|
8574
8596
|
if (opts.securitySeat === true) {
|
|
@@ -11455,8 +11477,13 @@ function addTimeoutMs() {
|
|
|
11455
11477
|
const parsed = Number(raw);
|
|
11456
11478
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : DSH_ADD_TIMEOUT_MS;
|
|
11457
11479
|
}
|
|
11458
|
-
var
|
|
11480
|
+
var DSH_FALLBACKS_VERSION = "0.4.1";
|
|
11481
|
+
var DSH_PLUGIN_SPECS = ["@mstar-harness/dsh", `dsh-llm-fallbacks@${DSH_FALLBACKS_VERSION}`];
|
|
11459
11482
|
var DSH_FALLBACKS_SPEC = DSH_PLUGIN_SPECS[1];
|
|
11483
|
+
function dshLoaderName(spec) {
|
|
11484
|
+
const at = spec.lastIndexOf("@");
|
|
11485
|
+
return at > 0 ? spec.slice(0, at) : spec;
|
|
11486
|
+
}
|
|
11460
11487
|
var DSH_INSTALL_HINT = "Install the DeepSeek Harness CLI (@deepseek-ai/dsh), e.g. `pnpm add -g @deepseek-ai/dsh` or `npm install -g @deepseek-ai/dsh`, then re-run init.";
|
|
11461
11488
|
function runDsh(args, dryRun, timeoutMs) {
|
|
11462
11489
|
return runCliCommand([DSH_BIN, ...args], { dryRun, timeoutMs, env: process.env });
|
|
@@ -11533,7 +11560,7 @@ function runInit2(scope, dryRun, initFlags) {
|
|
|
11533
11560
|
notes.push(`skipped-by-flag: ${spec} (--no-fallbacks)`);
|
|
11534
11561
|
continue;
|
|
11535
11562
|
}
|
|
11536
|
-
if (!dryRun && installed.has(spec)) {
|
|
11563
|
+
if (!dryRun && (installed.has(spec) || installed.has(dshLoaderName(spec)))) {
|
|
11537
11564
|
notes.push(`skipped-existing: ${spec} (already installed in profile ${DSH_PROFILE})`);
|
|
11538
11565
|
continue;
|
|
11539
11566
|
}
|
|
@@ -11578,7 +11605,7 @@ function runDoctor2(scope) {
|
|
|
11578
11605
|
}
|
|
11579
11606
|
const byName = new Map(entries.map((entry) => [entry.name, entry]));
|
|
11580
11607
|
for (const spec of DSH_PLUGIN_SPECS) {
|
|
11581
|
-
const entry = byName.get(spec);
|
|
11608
|
+
const entry = byName.get(spec) ?? byName.get(dshLoaderName(spec));
|
|
11582
11609
|
const state = !entry ? "uninstalled" : entry.enabled ? "mounted" : "disabled";
|
|
11583
11610
|
notes.push(`${spec}: ${state}`);
|
|
11584
11611
|
if (state === "mounted")
|
|
@@ -11599,9 +11626,8 @@ var dshAdapter = {
|
|
|
11599
11626
|
import fs5 from "node:fs";
|
|
11600
11627
|
import path8 from "node:path";
|
|
11601
11628
|
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
11602
|
-
var
|
|
11603
|
-
var
|
|
11604
|
-
var PACKAGE_NAMES = new Set(["morning-star", PLUGIN_NAME, "github:btspoony/mstar-harness"]);
|
|
11629
|
+
var OMP_PACKAGE_REL = path8.join("packages", "omp");
|
|
11630
|
+
var PACKAGE_NAMES = new Set(["morning-star", PLUGIN_NAME, "github:btspoony/mstar-harness", "@mstar-harness/omp"]);
|
|
11605
11631
|
var SKILL_SMOKE = ["mstar-host", "mstar-harness-core", "pm"];
|
|
11606
11632
|
var COMMAND_SMOKE = ["iteration-start", "iteration-drive", "iteration-loop", "codebase-audit"];
|
|
11607
11633
|
function ompAvailable() {
|
|
@@ -11664,11 +11690,9 @@ function findInstalledPlugin(plugins) {
|
|
|
11664
11690
|
}
|
|
11665
11691
|
function validatePluginTree(pluginRoot) {
|
|
11666
11692
|
const errors2 = [];
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
|
|
11670
|
-
errors2.push(`Missing omp plugin marker: ${markerPath}`);
|
|
11671
|
-
}
|
|
11693
|
+
const markerPath = path8.join(pluginRoot, "plugin.json");
|
|
11694
|
+
if (!fs5.existsSync(markerPath)) {
|
|
11695
|
+
errors2.push(`Missing omp plugin marker: ${markerPath}`);
|
|
11672
11696
|
}
|
|
11673
11697
|
for (const skill of SKILL_SMOKE) {
|
|
11674
11698
|
const skillPath = path8.join(pluginRoot, "skills", skill, "SKILL.md");
|
|
@@ -11705,9 +11729,33 @@ function runInit3(scope, dryRun) {
|
|
|
11705
11729
|
}
|
|
11706
11730
|
}
|
|
11707
11731
|
if (!ompAvailable()) {
|
|
11708
|
-
notes.push("omp CLI not found on PATH. Install Oh My Pi (`omp`), then re-run init or manually: omp plugin install
|
|
11732
|
+
notes.push("omp CLI not found on PATH. Install Oh My Pi (`omp`), then re-run init or manually: omp plugin install @mstar-harness/omp");
|
|
11709
11733
|
} else {
|
|
11710
|
-
const
|
|
11734
|
+
const ompPackagePath = path8.join(HARNESS_REPO_PATH, OMP_PACKAGE_REL);
|
|
11735
|
+
if (!dryRun && !fs5.existsSync(path8.join(ompPackagePath, "plugin.json"))) {
|
|
11736
|
+
try {
|
|
11737
|
+
runCliCommand(["bun", "install"], { cwd: HARNESS_REPO_PATH, dryRun });
|
|
11738
|
+
runCliCommand(["bun", "run", "engine:build"], { cwd: HARNESS_REPO_PATH, dryRun });
|
|
11739
|
+
runCliCommand(["bun", "run", "omp:build"], { cwd: HARNESS_REPO_PATH, dryRun });
|
|
11740
|
+
notes.push("Built the omp package (engine dist + discovery mirrors) before linking.");
|
|
11741
|
+
} catch (buildError) {
|
|
11742
|
+
const buildMessage = buildError instanceof Error ? buildError.message : String(buildError);
|
|
11743
|
+
notes.push(`Warning: could not build packages/omp (${buildMessage}). Falling back to: omp plugin install @mstar-harness/omp`);
|
|
11744
|
+
const installArgs = ["plugin", "install", "@mstar-harness/omp"];
|
|
11745
|
+
if (scope === "project")
|
|
11746
|
+
installArgs.push("--scope", "project");
|
|
11747
|
+
try {
|
|
11748
|
+
runOmp(installArgs, dryRun);
|
|
11749
|
+
notes.push(`Installed @mstar-harness/omp via omp plugin install (${scope}).`);
|
|
11750
|
+
} catch (installError) {
|
|
11751
|
+
notes.push(`omp plugin install also failed: ${installError instanceof Error ? installError.message : String(installError)}`);
|
|
11752
|
+
}
|
|
11753
|
+
notes.push(...postInstallNotes(scope, dryRun, projectRoot));
|
|
11754
|
+
return { location: HARNESS_REPO_PATH, notes };
|
|
11755
|
+
}
|
|
11756
|
+
}
|
|
11757
|
+
notes.push(`Linked omp plugin tree resolved via the workspace engine member; dist + root mirrors are gitignored build outputs (rebuilt automatically above when absent)`);
|
|
11758
|
+
const linkArgs = ["plugin", "link", ompPackagePath];
|
|
11711
11759
|
if (scope === "project")
|
|
11712
11760
|
linkArgs.push("--scope", "project");
|
|
11713
11761
|
if (dryRun) {
|
|
@@ -11715,16 +11763,16 @@ function runInit3(scope, dryRun) {
|
|
|
11715
11763
|
} else {
|
|
11716
11764
|
try {
|
|
11717
11765
|
runOmp(linkArgs, dryRun);
|
|
11718
|
-
notes.push(`Linked local harness into omp plugins (${scope}): omp plugin link ${
|
|
11766
|
+
notes.push(`Linked local harness omp package into omp plugins (${scope}): omp plugin link ${ompPackagePath}${scope === "project" ? " --scope project" : ""}`);
|
|
11719
11767
|
} catch (error) {
|
|
11720
11768
|
const message = error instanceof Error ? error.message : String(error);
|
|
11721
|
-
notes.push(`omp plugin link failed (${message}). Falling back guidance: omp plugin install
|
|
11769
|
+
notes.push(`omp plugin link failed (${message}). Falling back guidance: omp plugin install @mstar-harness/omp`);
|
|
11722
11770
|
try {
|
|
11723
|
-
const installArgs = ["plugin", "install", "
|
|
11771
|
+
const installArgs = ["plugin", "install", "@mstar-harness/omp"];
|
|
11724
11772
|
if (scope === "project")
|
|
11725
11773
|
installArgs.push("--scope", "project");
|
|
11726
11774
|
runOmp(installArgs, dryRun);
|
|
11727
|
-
notes.push(`Installed
|
|
11775
|
+
notes.push(`Installed @mstar-harness/omp via omp plugin install (${scope}).`);
|
|
11728
11776
|
} catch (installError) {
|
|
11729
11777
|
const installMessage = installError instanceof Error ? installError.message : String(installError);
|
|
11730
11778
|
notes.push(`omp plugin install also failed: ${installMessage}`);
|
|
@@ -11739,16 +11787,28 @@ function runInit3(scope, dryRun) {
|
|
|
11739
11787
|
notes.push("Verify with: omp plugin list");
|
|
11740
11788
|
notes.push("Enter PM with /skill:pm ; commands: /iteration-start /iteration-drive /iteration-loop /codebase-audit");
|
|
11741
11789
|
notes.push(`Host adapter: mstar-host \u2192 references/omp.md (skill://mstar-host/references/omp.md)`);
|
|
11742
|
-
notes.push(`Alternate install without CLI link: omp plugin install
|
|
11790
|
+
notes.push(`Alternate install without CLI link: omp plugin install @mstar-harness/omp`);
|
|
11743
11791
|
return {
|
|
11744
11792
|
location: HARNESS_REPO_PATH,
|
|
11745
11793
|
notes
|
|
11746
11794
|
};
|
|
11747
11795
|
}
|
|
11796
|
+
function postInstallNotes(scope, dryRun, projectRoot) {
|
|
11797
|
+
const notes = [];
|
|
11798
|
+
if (scope === "project") {
|
|
11799
|
+
notes.push(...appendHarnessProjectGitignore(projectRoot, dryRun));
|
|
11800
|
+
notes.push(...appendGitignore(projectRoot, [".omp/plugins/", ".omp/plugin-overrides.json", ".omp/plugins/installed_plugins.json"], dryRun));
|
|
11801
|
+
}
|
|
11802
|
+
notes.push("Verify with: omp plugin list");
|
|
11803
|
+
notes.push("Enter PM with /skill:pm ; commands: /iteration-start /iteration-drive /iteration-loop /codebase-audit");
|
|
11804
|
+
notes.push(`Host adapter: mstar-host \u2192 references/omp.md (skill://mstar-host/references/omp.md)`);
|
|
11805
|
+
notes.push(`Alternate install without CLI link: omp plugin install @mstar-harness/omp`);
|
|
11806
|
+
return notes;
|
|
11807
|
+
}
|
|
11748
11808
|
function runDoctor3(scope) {
|
|
11749
11809
|
const errors2 = [];
|
|
11750
11810
|
errors2.push(...validateLocalHarnessRepo());
|
|
11751
|
-
errors2.push(...validatePluginTree(HARNESS_REPO_PATH));
|
|
11811
|
+
errors2.push(...validatePluginTree(path8.join(HARNESS_REPO_PATH, OMP_PACKAGE_REL)));
|
|
11752
11812
|
if (!ompAvailable()) {
|
|
11753
11813
|
errors2.push("omp CLI not found on PATH (required for omp target doctor checks).");
|
|
11754
11814
|
} else {
|
|
@@ -14136,6 +14196,9 @@ prReviewCommand.command("validate-report").description("Validate a saved local P
|
|
|
14136
14196
|
function gitSync(args, cwd) {
|
|
14137
14197
|
return execFileSync10("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
14138
14198
|
}
|
|
14199
|
+
function gitRaw(args, cwd) {
|
|
14200
|
+
return execFileSync10("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"], maxBuffer: GIT_CAPTURE_MAX_BYTES });
|
|
14201
|
+
}
|
|
14139
14202
|
function ghSync(args, input) {
|
|
14140
14203
|
return execFileSync10("gh", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], ...input !== undefined ? { input } : {} }).trim();
|
|
14141
14204
|
}
|
|
@@ -14161,7 +14224,11 @@ function refResolves(ref, cwd) {
|
|
|
14161
14224
|
}
|
|
14162
14225
|
function probeChangesetEmpty(diffCmdArgs, cwd, worktreePath) {
|
|
14163
14226
|
if (diffCmdArgs[0] === "__working_tree__") {
|
|
14164
|
-
const
|
|
14227
|
+
const diffOut = gitProbe(["diff"], worktreePath);
|
|
14228
|
+
const cachedOut = gitProbe(["diff", "--cached"], worktreePath);
|
|
14229
|
+
if (diffOut === null || cachedOut === null)
|
|
14230
|
+
return false;
|
|
14231
|
+
const dirty = diffOut.length > 0 || cachedOut.length > 0;
|
|
14165
14232
|
if (dirty)
|
|
14166
14233
|
return false;
|
|
14167
14234
|
let untracked = "";
|
|
@@ -14178,17 +14245,26 @@ function probeChangesetEmpty(diffCmdArgs, cwd, worktreePath) {
|
|
|
14178
14245
|
const sha = diffCmdArgs[1];
|
|
14179
14246
|
const EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
14180
14247
|
const diffFrom = refResolves(`${sha}^`, worktreePath) ? `${sha}^` : EMPTY_TREE;
|
|
14181
|
-
|
|
14248
|
+
const probe2 = gitProbe(["diff", diffFrom, sha], worktreePath);
|
|
14249
|
+
return probe2 === null ? false : probe2.trim().length === 0;
|
|
14182
14250
|
}
|
|
14183
|
-
|
|
14251
|
+
const probe = gitProbe(diffCmdArgs, worktreePath);
|
|
14252
|
+
return probe === null ? false : probe.length === 0;
|
|
14184
14253
|
}
|
|
14185
14254
|
function gitIf(args, cwd) {
|
|
14186
14255
|
try {
|
|
14187
|
-
return execFileSync10("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
14256
|
+
return execFileSync10("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], maxBuffer: GIT_CAPTURE_MAX_BYTES });
|
|
14188
14257
|
} catch {
|
|
14189
14258
|
return "";
|
|
14190
14259
|
}
|
|
14191
14260
|
}
|
|
14261
|
+
function gitProbe(args, cwd) {
|
|
14262
|
+
try {
|
|
14263
|
+
return execFileSync10("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], maxBuffer: GIT_CAPTURE_MAX_BYTES });
|
|
14264
|
+
} catch {
|
|
14265
|
+
return null;
|
|
14266
|
+
}
|
|
14267
|
+
}
|
|
14192
14268
|
function probeChangesetEmptyPreworktree(mode, headSpec, cwd) {
|
|
14193
14269
|
if (mode === "working-tree")
|
|
14194
14270
|
return probeChangesetEmpty(["__working_tree__"], cwd, cwd);
|
|
@@ -14315,7 +14391,7 @@ function ghApi(apiPath, payload) {
|
|
|
14315
14391
|
input: payload
|
|
14316
14392
|
});
|
|
14317
14393
|
}
|
|
14318
|
-
prReviewCommand.command("worktree-setup").description("Create the isolated review worktree per pr-review.md \xA7 Worktree isolation: resolves the real base, picks a " + "collision-free branch name, fetches with explicit refspecs, creates the worktree, computes the diff basis INSIDE it, " + "and records a sidecar json consumed by worktree-cleanup; prints {reviewBranch, worktreePath, base, mergeBase, diffCmd} " + "(input modes: --pr <n> | --branch <b> | --diff | --working-tree | --commit <sha>)").option("--pr <n>", "PR number input mode (pull/<n>/head via gh)").option("--branch <name>", "Bare remote-branch input mode").option("--diff", "Arbitrary diff input mode \u2014 no worktree, no refs").option("--working-tree", "Uncommitted working-tree input mode \u2014 no worktree, no refs").option("--commit <sha>", "Single-commit input mode").option("--path <dir>", "Worktree target directory (default:
|
|
14394
|
+
prReviewCommand.command("worktree-setup").description("Create the isolated review worktree per pr-review.md \xA7 Worktree isolation: resolves the real base, picks a " + "collision-free branch name, fetches with explicit refspecs, creates the worktree, computes the diff basis INSIDE it, " + "and records a sidecar json consumed by worktree-cleanup; prints {reviewBranch, worktreePath, base, mergeBase, diffCmd, diffFile} " + "(input modes: --pr <n> | --branch <b> | --diff | --working-tree | --commit <sha>)").option("--pr <n>", "PR number input mode (pull/<n>/head via gh)").option("--branch <name>", "Bare remote-branch input mode").option("--diff", "Arbitrary diff input mode \u2014 no worktree, no refs").option("--working-tree", "Uncommitted working-tree input mode \u2014 no worktree, no refs").option("--commit <sha>", "Single-commit input mode").option("--path <dir>", "Worktree target directory (default: <repo>/.worktrees/review-<branch>)").action((options) => {
|
|
14319
14395
|
try {
|
|
14320
14396
|
const modesDeclared = [
|
|
14321
14397
|
options.pr !== undefined,
|
|
@@ -14355,7 +14431,7 @@ prReviewCommand.command("worktree-setup").description("Create the isolated revie
|
|
|
14355
14431
|
process.exitCode = 1;
|
|
14356
14432
|
return;
|
|
14357
14433
|
}
|
|
14358
|
-
console.log(JSON.stringify({ reviewBranch: null, worktreePath: repoRoot, base: null, mergeBase: null, diffCmd: mode === "diff" ? "(provided changeset)" : "git diff + git diff --cached + ls-files --others" }, null, 2));
|
|
14434
|
+
console.log(JSON.stringify({ reviewBranch: null, worktreePath: repoRoot, base: null, mergeBase: null, diffCmd: mode === "diff" ? "(provided changeset)" : "git diff + git diff --cached + ls-files --others", diffFile: null }, null, 2));
|
|
14359
14435
|
return;
|
|
14360
14436
|
}
|
|
14361
14437
|
let prNumber = 0;
|
|
@@ -14405,7 +14481,21 @@ prReviewCommand.command("worktree-setup").description("Create the isolated revie
|
|
|
14405
14481
|
const baseCandidate = mode === "pr" ? namePrNumber : Number(String(Math.abs([...headSpec].reduce((h, ch) => (h * 31 + ch.charCodeAt(0)) % 1000003, 7))));
|
|
14406
14482
|
const reviewBranch = pickReviewBranchName(existing, baseCandidate === 0 ? 1 : baseCandidate, cliToday().replace(/-/g, ""));
|
|
14407
14483
|
const branchSuffix = mode === "pr" ? "" : `-${headSpec.slice(0, 8)}`;
|
|
14408
|
-
const worktreePath = path12.resolve(options.path ??
|
|
14484
|
+
const worktreePath = path12.resolve(options.path ?? path12.join(repoRoot, ".worktrees", `review-${reviewBranch}${branchSuffix}`));
|
|
14485
|
+
if (options.path === undefined) {
|
|
14486
|
+
fs8.mkdirSync(path12.join(repoRoot, ".worktrees"), { recursive: true });
|
|
14487
|
+
if (gitIf(["check-ignore", ".worktrees/"], repoRoot) === "") {
|
|
14488
|
+
const excludePath = path12.join(repoRoot, ".git", "info", "exclude");
|
|
14489
|
+
const existing2 = fs8.existsSync(excludePath) ? fs8.readFileSync(excludePath, "utf8") : "";
|
|
14490
|
+
if (!existing2.split(`
|
|
14491
|
+
`).some((line) => line.trim() === ".worktrees/")) {
|
|
14492
|
+
fs8.appendFileSync(excludePath, `${existing2 === "" || existing2.endsWith(`
|
|
14493
|
+
`) ? "" : `
|
|
14494
|
+
`}.worktrees/
|
|
14495
|
+
`);
|
|
14496
|
+
}
|
|
14497
|
+
}
|
|
14498
|
+
}
|
|
14409
14499
|
const originUrl = gitIf(["remote", "get-url", "origin"], repoRoot);
|
|
14410
14500
|
let fetched = true;
|
|
14411
14501
|
try {
|
|
@@ -14421,7 +14511,11 @@ prReviewCommand.command("worktree-setup").description("Create the isolated revie
|
|
|
14421
14511
|
} catch {
|
|
14422
14512
|
fetched = false;
|
|
14423
14513
|
}
|
|
14424
|
-
|
|
14514
|
+
let wroteSnapshot = false;
|
|
14515
|
+
let wroteSidecar = false;
|
|
14516
|
+
let pendingSidecar;
|
|
14517
|
+
let sidecarFd;
|
|
14518
|
+
const cleanupOnFailure = (branchToDelete) => {
|
|
14425
14519
|
try {
|
|
14426
14520
|
if (fs8.existsSync(worktreePath))
|
|
14427
14521
|
gitSync(["worktree", "remove", "--force", worktreePath], repoRoot);
|
|
@@ -14429,6 +14523,12 @@ prReviewCommand.command("worktree-setup").description("Create the isolated revie
|
|
|
14429
14523
|
if (branchToDelete !== "" && !existing.has(branchToDelete)) {
|
|
14430
14524
|
gitSync(["branch", "-D", branchToDelete], repoRoot);
|
|
14431
14525
|
}
|
|
14526
|
+
if (wroteSidecar && sidecarFd !== undefined) {
|
|
14527
|
+
removeOwnedFreshSidecarFile(sidecarFd, worktreePath);
|
|
14528
|
+
sidecarFd = undefined;
|
|
14529
|
+
}
|
|
14530
|
+
if (wroteSnapshot && pendingSidecar !== undefined)
|
|
14531
|
+
removeOwnedSnapshotFile(worktreePath, pendingSidecar);
|
|
14432
14532
|
} catch {}
|
|
14433
14533
|
};
|
|
14434
14534
|
const fetchedHeadResolves = mode === "pr" ? refResolves(reviewBranch, repoRoot) : mode === "branch" ? originUrl !== "" && refResolves(`origin/${options.branch}`, repoRoot) : mode === "commit" ? Boolean(gitIf(["rev-parse", "--verify", "--quiet", `${headSpec}^{commit}`], repoRoot).trim()) : refResolves(headSpec, repoRoot);
|
|
@@ -14461,48 +14561,222 @@ prReviewCommand.command("worktree-setup").description("Create the isolated revie
|
|
|
14461
14561
|
const changesetEmpty = probeChangesetEmpty(diffArgs, worktreePath, worktreePath);
|
|
14462
14562
|
const emptyGate = preflightChangeset(mode, { refsResolve: true, changesetEmpty });
|
|
14463
14563
|
if (changesetEmpty) {
|
|
14464
|
-
|
|
14564
|
+
cleanupOnFailure(mode === "pr" ? reviewBranch : "");
|
|
14465
14565
|
}
|
|
14466
14566
|
if (!emptyGate.ok && emptyGate.violations.some((v) => v.code === "prreview.preflight.changeset-empty")) {
|
|
14467
14567
|
printChecklist("pr-review worktree-setup preflight", emptyGate);
|
|
14468
14568
|
process.exitCode = 1;
|
|
14469
14569
|
return;
|
|
14470
14570
|
}
|
|
14471
|
-
const
|
|
14472
|
-
|
|
14473
|
-
|
|
14474
|
-
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
|
|
14480
|
-
|
|
14571
|
+
const captureAndRecordSnapshot = () => {
|
|
14572
|
+
const diffFile = prReviewArtifactPathFor(worktreePath, "diff");
|
|
14573
|
+
const sidecarPath = prReviewArtifactPathFor(worktreePath, "json");
|
|
14574
|
+
const snapshotParts = [];
|
|
14575
|
+
if (mode === "commit") {
|
|
14576
|
+
snapshotParts.push(Buffer.from(`# Review package: ${baseRef} (single commit)
|
|
14577
|
+
|
|
14578
|
+
## Commits
|
|
14579
|
+
`), gitRaw(["log", "--oneline", "-1", headSpec], worktreePath), Buffer.from(`
|
|
14580
|
+
## Files changed
|
|
14581
|
+
`), gitRaw(["show", "--stat", headSpec], worktreePath), Buffer.from(`
|
|
14582
|
+
## Diff
|
|
14583
|
+
`), gitRaw(["show", "-U10", headSpec], worktreePath));
|
|
14584
|
+
} else {
|
|
14585
|
+
const range = diffArgs[1];
|
|
14586
|
+
const [rangeBase, rangeHead] = range.split("...");
|
|
14587
|
+
snapshotParts.push(Buffer.from(`# Review package: ${baseRef}..${headSpec}
|
|
14588
|
+
|
|
14589
|
+
## Commits
|
|
14590
|
+
`), gitRaw(["log", "--oneline", `${rangeBase}..${rangeHead}`], worktreePath), Buffer.from(`
|
|
14591
|
+
## Files changed
|
|
14592
|
+
`), gitRaw(["diff", "--stat", range], worktreePath), Buffer.from(`
|
|
14593
|
+
## Diff
|
|
14594
|
+
`), gitRaw(["diff", "-U10", range], worktreePath));
|
|
14595
|
+
}
|
|
14596
|
+
const snapshot = Buffer.concat(snapshotParts);
|
|
14597
|
+
const recordedBase = mode === "pr" || mode !== "commit" && !baseRef.startsWith("origin/") ? `origin/${baseRef}` : baseRef;
|
|
14598
|
+
const sidecar2 = {
|
|
14599
|
+
reviewBranch: mode === "pr" ? reviewBranch : "",
|
|
14600
|
+
worktreePath,
|
|
14601
|
+
base: recordedBase,
|
|
14602
|
+
mergeBase,
|
|
14603
|
+
diffCmd,
|
|
14604
|
+
reportSaved: false,
|
|
14605
|
+
createdAt: new Date().toISOString(),
|
|
14606
|
+
repoRoot,
|
|
14607
|
+
diffFile,
|
|
14608
|
+
diffFileSha256: createHash("sha256").update(snapshot).digest("hex")
|
|
14609
|
+
};
|
|
14610
|
+
try {
|
|
14611
|
+
sidecarFd = fs8.openSync(sidecarPath, "wx+");
|
|
14612
|
+
} catch (error) {
|
|
14613
|
+
if (error.code !== "EEXIST" && error.code !== "EISDIR")
|
|
14614
|
+
throw error;
|
|
14615
|
+
throw new Error(`cannot record setup sidecar at ${sidecarPath} - run mstar pr-review worktree-cleanup first (never cleaning a foreign review)`);
|
|
14616
|
+
}
|
|
14617
|
+
writeFdSync(sidecarFd, Buffer.from(JSON.stringify(sidecar2, null, 2), "utf8"));
|
|
14618
|
+
wroteSidecar = true;
|
|
14619
|
+
try {
|
|
14620
|
+
fs8.writeFileSync(diffFile, snapshot, { flag: "wx" });
|
|
14621
|
+
} catch (error) {
|
|
14622
|
+
if (error.code !== "EEXIST" && error.code !== "EISDIR")
|
|
14623
|
+
throw error;
|
|
14624
|
+
throw new Error(`refusing to overwrite pre-existing non-snapshot path ${diffFile}`);
|
|
14625
|
+
}
|
|
14626
|
+
wroteSnapshot = true;
|
|
14627
|
+
const snapshotStat = fs8.lstatSync(diffFile);
|
|
14628
|
+
sidecar2.diffFileDev = snapshotStat.dev;
|
|
14629
|
+
sidecar2.diffFileIno = String(snapshotStat.ino);
|
|
14630
|
+
sidecar2.diffFileMtimeMs = snapshotStat.mtimeMs;
|
|
14631
|
+
pendingSidecar = sidecar2;
|
|
14632
|
+
fs8.ftruncateSync(sidecarFd, 0);
|
|
14633
|
+
writeFdSync(sidecarFd, Buffer.from(JSON.stringify(sidecar2, null, 2), "utf8"));
|
|
14634
|
+
fs8.closeSync(sidecarFd);
|
|
14635
|
+
sidecarFd = undefined;
|
|
14636
|
+
return sidecar2;
|
|
14481
14637
|
};
|
|
14482
|
-
|
|
14638
|
+
let sidecar;
|
|
14639
|
+
try {
|
|
14640
|
+
sidecar = captureAndRecordSnapshot();
|
|
14641
|
+
} catch (error) {
|
|
14642
|
+
cleanupOnFailure(mode === "pr" ? reviewBranch : "");
|
|
14643
|
+
throw error;
|
|
14644
|
+
}
|
|
14483
14645
|
console.log(JSON.stringify({
|
|
14484
14646
|
reviewBranch: sidecar.reviewBranch === "" ? null : sidecar.reviewBranch,
|
|
14485
14647
|
worktreePath: sidecar.worktreePath,
|
|
14486
14648
|
base: sidecar.base,
|
|
14487
14649
|
mergeBase: sidecar.mergeBase === "" ? null : sidecar.mergeBase,
|
|
14488
|
-
diffCmd: sidecar.diffCmd
|
|
14650
|
+
diffCmd: sidecar.diffCmd,
|
|
14651
|
+
diffFile: sidecar.diffFile
|
|
14489
14652
|
}, null, 2));
|
|
14490
14653
|
} catch (error) {
|
|
14491
14654
|
failScript(error, "pr-review worktree-setup");
|
|
14492
14655
|
}
|
|
14493
14656
|
});
|
|
14494
|
-
function
|
|
14657
|
+
function prReviewArtifactPathFor(worktreePath, suffix) {
|
|
14495
14658
|
const parent = path12.dirname(path12.resolve(worktreePath));
|
|
14496
14659
|
const name = path12.basename(path12.resolve(worktreePath));
|
|
14497
|
-
return path12.join(parent, `.${name}.prreview
|
|
14660
|
+
return path12.join(parent, `.${name}.prreview.${suffix}`);
|
|
14661
|
+
}
|
|
14662
|
+
function writeFdSync(fd, buf) {
|
|
14663
|
+
let written = 0;
|
|
14664
|
+
while (written < buf.length)
|
|
14665
|
+
written += fs8.writeSync(fd, buf, written, buf.length - written, written);
|
|
14666
|
+
}
|
|
14667
|
+
function removeOwnedSnapshotFile(worktreePath, sidecar) {
|
|
14668
|
+
const snapshotPath = prReviewArtifactPathFor(worktreePath, "diff");
|
|
14669
|
+
let fd;
|
|
14670
|
+
try {
|
|
14671
|
+
fd = fs8.openSync(snapshotPath, "r");
|
|
14672
|
+
} catch (error) {
|
|
14673
|
+
if (error.code === "ENOENT")
|
|
14674
|
+
return;
|
|
14675
|
+
console.error(import_picocolors2.default.yellow(`worktree-cleanup: snapshot at ${snapshotPath} left in place (cannot open: ${error.message})`));
|
|
14676
|
+
return;
|
|
14677
|
+
}
|
|
14678
|
+
try {
|
|
14679
|
+
const st = fs8.fstatSync(fd);
|
|
14680
|
+
if (!st.isFile())
|
|
14681
|
+
return;
|
|
14682
|
+
const recordedIno = sidecar.diffFileIno;
|
|
14683
|
+
const recordedDev = sidecar.diffFileDev;
|
|
14684
|
+
const recordedMtimeMs = sidecar.diffFileMtimeMs;
|
|
14685
|
+
const owned = typeof recordedIno === "string" && recordedIno !== "" && typeof recordedDev === "number" && Number.isFinite(recordedDev) && typeof recordedMtimeMs === "number" && Number.isFinite(recordedMtimeMs) && String(st.ino) === recordedIno && st.dev === recordedDev && st.mtimeMs === recordedMtimeMs;
|
|
14686
|
+
if (!owned) {
|
|
14687
|
+
console.error(import_picocolors2.default.yellow(`worktree-cleanup: snapshot at ${snapshotPath} left in place (file identity does not match the recorded snapshot)`));
|
|
14688
|
+
return;
|
|
14689
|
+
}
|
|
14690
|
+
if (st.nlink !== 1) {
|
|
14691
|
+
console.error(import_picocolors2.default.yellow(`worktree-cleanup: snapshot at ${snapshotPath} left in place (link count does not match the recorded snapshot)`));
|
|
14692
|
+
return;
|
|
14693
|
+
}
|
|
14694
|
+
const tmp = `${snapshotPath}.cleanup.${process.pid}.${randomUUID3()}`;
|
|
14695
|
+
try {
|
|
14696
|
+
fs8.renameSync(snapshotPath, tmp);
|
|
14697
|
+
} catch (error) {
|
|
14698
|
+
console.error(import_picocolors2.default.yellow(`worktree-cleanup: snapshot at ${snapshotPath} left in place (cannot detach: ${error.message})`));
|
|
14699
|
+
return;
|
|
14700
|
+
}
|
|
14701
|
+
const st2 = fs8.fstatSync(fd);
|
|
14702
|
+
let tmpStat;
|
|
14703
|
+
try {
|
|
14704
|
+
tmpStat = fs8.lstatSync(tmp);
|
|
14705
|
+
} catch {
|
|
14706
|
+
tmpStat = undefined;
|
|
14707
|
+
}
|
|
14708
|
+
if (tmpStat !== undefined && tmpStat.ino === st2.ino && tmpStat.dev === st2.dev && st2.nlink === 1 && tmpStat.nlink === 1) {
|
|
14709
|
+
fs8.unlinkSync(tmp);
|
|
14710
|
+
const st3 = fs8.fstatSync(fd);
|
|
14711
|
+
if (st3.nlink !== 0) {
|
|
14712
|
+
console.error(import_picocolors2.default.yellow(`worktree-cleanup: unlink at ${tmp} detached a pathname replacement, not the verified snapshot inode (${snapshotPath} still holds ${st3.nlink} link(s)) - the replacement is gone, the verified snapshot was NOT deleted`));
|
|
14713
|
+
}
|
|
14714
|
+
} else {
|
|
14715
|
+
try {
|
|
14716
|
+
fs8.linkSync(tmp, snapshotPath);
|
|
14717
|
+
fs8.unlinkSync(tmp);
|
|
14718
|
+
} catch (error) {
|
|
14719
|
+
if (error.code === "EEXIST") {
|
|
14720
|
+
console.error(import_picocolors2.default.yellow(`worktree-cleanup: snapshot replacement left at ${tmp} (snapshot path was recreated concurrently)`));
|
|
14721
|
+
} else {
|
|
14722
|
+
console.error(import_picocolors2.default.yellow(`worktree-cleanup: snapshot replacement left at ${tmp} (restore failed: ${error.message})`));
|
|
14723
|
+
}
|
|
14724
|
+
}
|
|
14725
|
+
}
|
|
14726
|
+
} finally {
|
|
14727
|
+
fs8.closeSync(fd);
|
|
14728
|
+
}
|
|
14498
14729
|
}
|
|
14499
|
-
function
|
|
14500
|
-
|
|
14730
|
+
function removeOwnedFreshSidecarFile(sidecarFd, worktreePath) {
|
|
14731
|
+
const sidecarPath = prReviewArtifactPathFor(worktreePath, "json");
|
|
14732
|
+
try {
|
|
14733
|
+
const st = fs8.fstatSync(sidecarFd);
|
|
14734
|
+
if (!st.isFile() || st.nlink !== 1) {
|
|
14735
|
+
console.error(import_picocolors2.default.yellow(`worktree-setup rollback: sidecar at ${sidecarPath} left in place (identity no longer held)`));
|
|
14736
|
+
return;
|
|
14737
|
+
}
|
|
14738
|
+
const tmp = `${sidecarPath}.cleanup.${process.pid}.${randomUUID3()}`;
|
|
14739
|
+
try {
|
|
14740
|
+
fs8.renameSync(sidecarPath, tmp);
|
|
14741
|
+
} catch (error) {
|
|
14742
|
+
console.error(import_picocolors2.default.yellow(`worktree-setup rollback: sidecar at ${sidecarPath} left in place (cannot detach: ${error.message})`));
|
|
14743
|
+
return;
|
|
14744
|
+
}
|
|
14745
|
+
const st2 = fs8.fstatSync(sidecarFd);
|
|
14746
|
+
let tmpStat;
|
|
14747
|
+
try {
|
|
14748
|
+
tmpStat = fs8.lstatSync(tmp);
|
|
14749
|
+
} catch {
|
|
14750
|
+
tmpStat = undefined;
|
|
14751
|
+
}
|
|
14752
|
+
if (tmpStat !== undefined && tmpStat.ino === st2.ino && tmpStat.dev === st2.dev) {
|
|
14753
|
+
fs8.unlinkSync(tmp);
|
|
14754
|
+
const st3 = fs8.fstatSync(sidecarFd);
|
|
14755
|
+
if (st3.nlink !== 0) {
|
|
14756
|
+
console.error(import_picocolors2.default.yellow(`worktree-setup rollback: unlink at ${tmp} detached a pathname replacement, not the verified sidecar inode (${sidecarPath} still holds ${st3.nlink} link(s)) - the replacement is gone, the verified sidecar was NOT deleted`));
|
|
14757
|
+
}
|
|
14758
|
+
} else {
|
|
14759
|
+
try {
|
|
14760
|
+
fs8.linkSync(tmp, sidecarPath);
|
|
14761
|
+
fs8.unlinkSync(tmp);
|
|
14762
|
+
} catch (error) {
|
|
14763
|
+
if (error.code === "EEXIST") {
|
|
14764
|
+
console.error(import_picocolors2.default.yellow(`worktree-setup rollback: sidecar replacement left at ${tmp} (sidecar path was recreated concurrently)`));
|
|
14765
|
+
} else {
|
|
14766
|
+
console.error(import_picocolors2.default.yellow(`worktree-setup rollback: sidecar replacement left at ${tmp} (restore failed: ${error.message})`));
|
|
14767
|
+
}
|
|
14768
|
+
}
|
|
14769
|
+
}
|
|
14770
|
+
} finally {
|
|
14771
|
+
try {
|
|
14772
|
+
fs8.closeSync(sidecarFd);
|
|
14773
|
+
} catch {}
|
|
14774
|
+
}
|
|
14501
14775
|
}
|
|
14502
14776
|
prReviewCommand.command("worktree-cleanup").description("Remove the review worktree per pr-review.md \xA7 Worktree isolation cleanup: refuses unless --report-saved is given OR the " + "setup sidecar records report-saved; removes the worktree, prunes, and deletes EXACTLY the recorded review branch \u2014 a " + "--branch argument that disagrees with the sidecar is refused (never delete a foreign/pre-existing branch)").requiredOption("--path <dir>", "Worktree directory created by worktree-setup").requiredOption("--branch <name>", "The recorded review branch (must match the setup sidecar for PR mode)").option("--report-saved", "Assert the local report has been saved before removal").action((options) => {
|
|
14503
14777
|
try {
|
|
14504
14778
|
const worktreePath = path12.resolve(resolveCliPath(options.path));
|
|
14505
|
-
const sidecarPath =
|
|
14779
|
+
const sidecarPath = prReviewArtifactPathFor(worktreePath, "json");
|
|
14506
14780
|
if (!fs8.existsSync(sidecarPath)) {
|
|
14507
14781
|
throw new Error(`no setup sidecar found at ${sidecarPath} - run pr-review worktree-setup first (foreign worktrees are never cleaned here)`);
|
|
14508
14782
|
}
|
|
@@ -14534,6 +14808,7 @@ prReviewCommand.command("worktree-cleanup").description("Remove the review workt
|
|
|
14534
14808
|
}
|
|
14535
14809
|
gitSync(["branch", "-D", sidecar.reviewBranch], gitRoot);
|
|
14536
14810
|
}
|
|
14811
|
+
removeOwnedSnapshotFile(worktreePath, sidecar);
|
|
14537
14812
|
fs8.rmSync(sidecarPath, { force: true });
|
|
14538
14813
|
console.log(import_picocolors2.default.green(`worktree-cleanup: removed ${worktreePath}${sidecar.reviewBranch !== "" ? ` + deleted ${sidecar.reviewBranch}` : " (no local branch to delete)"}`));
|
|
14539
14814
|
} catch (error) {
|
|
@@ -14583,7 +14858,7 @@ function measureLargestTouchedTotal(diffOutput, headRef, cwd) {
|
|
|
14583
14858
|
}
|
|
14584
14859
|
return maxTotal;
|
|
14585
14860
|
}
|
|
14586
|
-
prReviewCommand.command("seat-prompt").description("Generate the read-only audit-seat prompt per pr-review.md \xA7 Seat prompts (Hard Rules 4/5 verbatim, payload-return contract, " + "no-verdict/no-post clauses, slug <domain>-<seat>, Merge-class instruction on stage 2); prints the prompt").requiredOption("--stage <1|2>", "Pipeline stage (1 = collect, 2 = domain/security)").requiredOption("--domain <d>", "Review domain for this seat").requiredOption("--seat <id>", "Seat id (slug becomes <domain>-<seat>)").requiredOption("--worktree <path>", "Absolute review worktree path").option("--security", "Mark this seat as the security-lens seat (stage 2)").option("--skill-root <dir>", "Skill root containing references/pr-review.md (default: resolved skills/mstar-audit)").option("--recon <facts...>", "Recon facts (variadic: --recon fact1 fact2 ...)").option("--tier <quick|default|deep>", "Prompt tier (SP-A): quick shrinks read-first + folds the security lens in-seat; deep adds cross-domain security seat + stage-as-wave (default: default)").action((options) => {
|
|
14861
|
+
prReviewCommand.command("seat-prompt").description("Generate the read-only audit-seat prompt per pr-review.md \xA7 Seat prompts (Hard Rules 4/5 verbatim, payload-return contract, " + "no-verdict/no-post clauses, slug <domain>-<seat>, Merge-class instruction on stage 2); prints the prompt").requiredOption("--stage <1|2>", "Pipeline stage (1 = collect, 2 = domain/security)").requiredOption("--domain <d>", "Review domain for this seat").requiredOption("--seat <id>", "Seat id (slug becomes <domain>-<seat>)").requiredOption("--worktree <path>", "Absolute review worktree path").option("--security", "Mark this seat as the security-lens seat (stage 2)").option("--skill-root <dir>", "Skill root containing references/pr-review.md (default: resolved skills/mstar-audit)").option("--recon <facts...>", "Recon facts (variadic: --recon fact1 fact2 ...)").option("--tier <quick|default|deep>", "Prompt tier (SP-A): quick shrinks read-first + folds the security lens in-seat; deep adds cross-domain security seat + stage-as-wave (default: default)").option("--diff-file <path>", "Absolute path to the pinned diff snapshot written by worktree-setup (read-first ingredient)").action((options) => {
|
|
14587
14862
|
try {
|
|
14588
14863
|
if (options.stage !== "1" && options.stage !== "2") {
|
|
14589
14864
|
throw new SddScriptError(`usage: pr-review seat-prompt \u2014 --stage must be 1 or 2, got ${JSON.stringify(options.stage)}`, 2);
|
|
@@ -14601,7 +14876,8 @@ prReviewCommand.command("seat-prompt").description("Generate the read-only audit
|
|
|
14601
14876
|
worktreePath: path12.resolve(options.worktree),
|
|
14602
14877
|
reconFacts: options.recon ?? [],
|
|
14603
14878
|
...options.security === true ? { securitySeat: true } : {},
|
|
14604
|
-
...tier !== undefined ? { tier } : {}
|
|
14879
|
+
...tier !== undefined ? { tier } : {},
|
|
14880
|
+
...options.diffFile !== undefined && options.diffFile !== "" ? { diffFile: path12.resolve(resolveCliPath(options.diffFile)) } : {}
|
|
14605
14881
|
});
|
|
14606
14882
|
console.log(prompt);
|
|
14607
14883
|
} catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mstar-harness/cli",
|
|
3
|
-
"version": "3.6.0
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Morning Star harness CLI — installer bootstrap + mstar workflow verbs (path/status/lease/sdd/iteration/dispatch/worktree/lint/design-md/audit/compound/host/skill).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|