dlw-machine-setup 0.11.0 → 0.12.0-canary.1

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.
Files changed (2) hide show
  1. package/bin/installer.js +249 -399
  2. package/package.json +3 -2
package/bin/installer.js CHANGED
@@ -60,49 +60,49 @@ var require_yoctocolors_cjs = __commonJS({
60
60
  return result;
61
61
  };
62
62
  };
63
- var colors5 = {};
64
- colors5.reset = format(0, 0);
65
- colors5.bold = format(1, 22);
66
- colors5.dim = format(2, 22);
67
- colors5.italic = format(3, 23);
68
- colors5.underline = format(4, 24);
69
- colors5.overline = format(53, 55);
70
- colors5.inverse = format(7, 27);
71
- colors5.hidden = format(8, 28);
72
- colors5.strikethrough = format(9, 29);
73
- colors5.black = format(30, 39);
74
- colors5.red = format(31, 39);
75
- colors5.green = format(32, 39);
76
- colors5.yellow = format(33, 39);
77
- colors5.blue = format(34, 39);
78
- colors5.magenta = format(35, 39);
79
- colors5.cyan = format(36, 39);
80
- colors5.white = format(37, 39);
81
- colors5.gray = format(90, 39);
82
- colors5.bgBlack = format(40, 49);
83
- colors5.bgRed = format(41, 49);
84
- colors5.bgGreen = format(42, 49);
85
- colors5.bgYellow = format(43, 49);
86
- colors5.bgBlue = format(44, 49);
87
- colors5.bgMagenta = format(45, 49);
88
- colors5.bgCyan = format(46, 49);
89
- colors5.bgWhite = format(47, 49);
90
- colors5.bgGray = format(100, 49);
91
- colors5.redBright = format(91, 39);
92
- colors5.greenBright = format(92, 39);
93
- colors5.yellowBright = format(93, 39);
94
- colors5.blueBright = format(94, 39);
95
- colors5.magentaBright = format(95, 39);
96
- colors5.cyanBright = format(96, 39);
97
- colors5.whiteBright = format(97, 39);
98
- colors5.bgRedBright = format(101, 49);
99
- colors5.bgGreenBright = format(102, 49);
100
- colors5.bgYellowBright = format(103, 49);
101
- colors5.bgBlueBright = format(104, 49);
102
- colors5.bgMagentaBright = format(105, 49);
103
- colors5.bgCyanBright = format(106, 49);
104
- colors5.bgWhiteBright = format(107, 49);
105
- module2.exports = colors5;
63
+ var colors4 = {};
64
+ colors4.reset = format(0, 0);
65
+ colors4.bold = format(1, 22);
66
+ colors4.dim = format(2, 22);
67
+ colors4.italic = format(3, 23);
68
+ colors4.underline = format(4, 24);
69
+ colors4.overline = format(53, 55);
70
+ colors4.inverse = format(7, 27);
71
+ colors4.hidden = format(8, 28);
72
+ colors4.strikethrough = format(9, 29);
73
+ colors4.black = format(30, 39);
74
+ colors4.red = format(31, 39);
75
+ colors4.green = format(32, 39);
76
+ colors4.yellow = format(33, 39);
77
+ colors4.blue = format(34, 39);
78
+ colors4.magenta = format(35, 39);
79
+ colors4.cyan = format(36, 39);
80
+ colors4.white = format(37, 39);
81
+ colors4.gray = format(90, 39);
82
+ colors4.bgBlack = format(40, 49);
83
+ colors4.bgRed = format(41, 49);
84
+ colors4.bgGreen = format(42, 49);
85
+ colors4.bgYellow = format(43, 49);
86
+ colors4.bgBlue = format(44, 49);
87
+ colors4.bgMagenta = format(45, 49);
88
+ colors4.bgCyan = format(46, 49);
89
+ colors4.bgWhite = format(47, 49);
90
+ colors4.bgGray = format(100, 49);
91
+ colors4.redBright = format(91, 39);
92
+ colors4.greenBright = format(92, 39);
93
+ colors4.yellowBright = format(93, 39);
94
+ colors4.blueBright = format(94, 39);
95
+ colors4.magentaBright = format(95, 39);
96
+ colors4.cyanBright = format(96, 39);
97
+ colors4.whiteBright = format(97, 39);
98
+ colors4.bgRedBright = format(101, 49);
99
+ colors4.bgGreenBright = format(102, 49);
100
+ colors4.bgYellowBright = format(103, 49);
101
+ colors4.bgBlueBright = format(104, 49);
102
+ colors4.bgMagentaBright = format(105, 49);
103
+ colors4.bgCyanBright = format(106, 49);
104
+ colors4.bgWhiteBright = format(107, 49);
105
+ module2.exports = colors4;
106
106
  }
107
107
  });
108
108
 
@@ -1612,14 +1612,14 @@ var require_lib = __commonJS({
1612
1612
  var require_ansi_escapes = __commonJS({
1613
1613
  "node_modules/ansi-escapes/index.js"(exports2, module2) {
1614
1614
  "use strict";
1615
- var ansiEscapes5 = module2.exports;
1616
- module2.exports.default = ansiEscapes5;
1615
+ var ansiEscapes4 = module2.exports;
1616
+ module2.exports.default = ansiEscapes4;
1617
1617
  var ESC = "\x1B[";
1618
1618
  var OSC = "\x1B]";
1619
1619
  var BEL = "\x07";
1620
1620
  var SEP = ";";
1621
1621
  var isTerminalApp = process.env.TERM_PROGRAM === "Apple_Terminal";
1622
- ansiEscapes5.cursorTo = (x, y) => {
1622
+ ansiEscapes4.cursorTo = (x, y) => {
1623
1623
  if (typeof x !== "number") {
1624
1624
  throw new TypeError("The `x` argument is required");
1625
1625
  }
@@ -1628,7 +1628,7 @@ var require_ansi_escapes = __commonJS({
1628
1628
  }
1629
1629
  return ESC + (y + 1) + ";" + (x + 1) + "H";
1630
1630
  };
1631
- ansiEscapes5.cursorMove = (x, y) => {
1631
+ ansiEscapes4.cursorMove = (x, y) => {
1632
1632
  if (typeof x !== "number") {
1633
1633
  throw new TypeError("The `x` argument is required");
1634
1634
  }
@@ -1645,46 +1645,46 @@ var require_ansi_escapes = __commonJS({
1645
1645
  }
1646
1646
  return ret;
1647
1647
  };
1648
- ansiEscapes5.cursorUp = (count = 1) => ESC + count + "A";
1649
- ansiEscapes5.cursorDown = (count = 1) => ESC + count + "B";
1650
- ansiEscapes5.cursorForward = (count = 1) => ESC + count + "C";
1651
- ansiEscapes5.cursorBackward = (count = 1) => ESC + count + "D";
1652
- ansiEscapes5.cursorLeft = ESC + "G";
1653
- ansiEscapes5.cursorSavePosition = isTerminalApp ? "\x1B7" : ESC + "s";
1654
- ansiEscapes5.cursorRestorePosition = isTerminalApp ? "\x1B8" : ESC + "u";
1655
- ansiEscapes5.cursorGetPosition = ESC + "6n";
1656
- ansiEscapes5.cursorNextLine = ESC + "E";
1657
- ansiEscapes5.cursorPrevLine = ESC + "F";
1658
- ansiEscapes5.cursorHide = ESC + "?25l";
1659
- ansiEscapes5.cursorShow = ESC + "?25h";
1660
- ansiEscapes5.eraseLines = (count) => {
1648
+ ansiEscapes4.cursorUp = (count = 1) => ESC + count + "A";
1649
+ ansiEscapes4.cursorDown = (count = 1) => ESC + count + "B";
1650
+ ansiEscapes4.cursorForward = (count = 1) => ESC + count + "C";
1651
+ ansiEscapes4.cursorBackward = (count = 1) => ESC + count + "D";
1652
+ ansiEscapes4.cursorLeft = ESC + "G";
1653
+ ansiEscapes4.cursorSavePosition = isTerminalApp ? "\x1B7" : ESC + "s";
1654
+ ansiEscapes4.cursorRestorePosition = isTerminalApp ? "\x1B8" : ESC + "u";
1655
+ ansiEscapes4.cursorGetPosition = ESC + "6n";
1656
+ ansiEscapes4.cursorNextLine = ESC + "E";
1657
+ ansiEscapes4.cursorPrevLine = ESC + "F";
1658
+ ansiEscapes4.cursorHide = ESC + "?25l";
1659
+ ansiEscapes4.cursorShow = ESC + "?25h";
1660
+ ansiEscapes4.eraseLines = (count) => {
1661
1661
  let clear = "";
1662
1662
  for (let i = 0; i < count; i++) {
1663
- clear += ansiEscapes5.eraseLine + (i < count - 1 ? ansiEscapes5.cursorUp() : "");
1663
+ clear += ansiEscapes4.eraseLine + (i < count - 1 ? ansiEscapes4.cursorUp() : "");
1664
1664
  }
1665
1665
  if (count) {
1666
- clear += ansiEscapes5.cursorLeft;
1666
+ clear += ansiEscapes4.cursorLeft;
1667
1667
  }
1668
1668
  return clear;
1669
1669
  };
1670
- ansiEscapes5.eraseEndLine = ESC + "K";
1671
- ansiEscapes5.eraseStartLine = ESC + "1K";
1672
- ansiEscapes5.eraseLine = ESC + "2K";
1673
- ansiEscapes5.eraseDown = ESC + "J";
1674
- ansiEscapes5.eraseUp = ESC + "1J";
1675
- ansiEscapes5.eraseScreen = ESC + "2J";
1676
- ansiEscapes5.scrollUp = ESC + "S";
1677
- ansiEscapes5.scrollDown = ESC + "T";
1678
- ansiEscapes5.clearScreen = "\x1Bc";
1679
- ansiEscapes5.clearTerminal = process.platform === "win32" ? `${ansiEscapes5.eraseScreen}${ESC}0f` : (
1670
+ ansiEscapes4.eraseEndLine = ESC + "K";
1671
+ ansiEscapes4.eraseStartLine = ESC + "1K";
1672
+ ansiEscapes4.eraseLine = ESC + "2K";
1673
+ ansiEscapes4.eraseDown = ESC + "J";
1674
+ ansiEscapes4.eraseUp = ESC + "1J";
1675
+ ansiEscapes4.eraseScreen = ESC + "2J";
1676
+ ansiEscapes4.scrollUp = ESC + "S";
1677
+ ansiEscapes4.scrollDown = ESC + "T";
1678
+ ansiEscapes4.clearScreen = "\x1Bc";
1679
+ ansiEscapes4.clearTerminal = process.platform === "win32" ? `${ansiEscapes4.eraseScreen}${ESC}0f` : (
1680
1680
  // 1. Erases the screen (Only done in case `2` is not supported)
1681
1681
  // 2. Erases the whole screen including scrollback buffer
1682
1682
  // 3. Moves cursor to the top-left position
1683
1683
  // More info: https://www.real-world-systems.com/docs/ANSIcode.html
1684
- `${ansiEscapes5.eraseScreen}${ESC}3J${ESC}H`
1684
+ `${ansiEscapes4.eraseScreen}${ESC}3J${ESC}H`
1685
1685
  );
1686
- ansiEscapes5.beep = BEL;
1687
- ansiEscapes5.link = (text, url) => {
1686
+ ansiEscapes4.beep = BEL;
1687
+ ansiEscapes4.link = (text, url) => {
1688
1688
  return [
1689
1689
  OSC,
1690
1690
  "8",
@@ -1700,7 +1700,7 @@ var require_ansi_escapes = __commonJS({
1700
1700
  BEL
1701
1701
  ].join("");
1702
1702
  };
1703
- ansiEscapes5.image = (buffer, options = {}) => {
1703
+ ansiEscapes4.image = (buffer, options = {}) => {
1704
1704
  let ret = `${OSC}1337;File=inline=1`;
1705
1705
  if (options.width) {
1706
1706
  ret += `;width=${options.width}`;
@@ -1713,7 +1713,7 @@ var require_ansi_escapes = __commonJS({
1713
1713
  }
1714
1714
  return ret + ":" + buffer.toString("base64") + BEL;
1715
1715
  };
1716
- ansiEscapes5.iTerm = {
1716
+ ansiEscapes4.iTerm = {
1717
1717
  setCwd: (cwd = process.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
1718
1718
  annotation: (message, options = {}) => {
1719
1719
  let ret = `${OSC}1337;`;
@@ -1748,7 +1748,6 @@ var isDownKey = (key) => (
1748
1748
  key.name === "j" || // Emacs keybinding
1749
1749
  key.ctrl && key.name === "n"
1750
1750
  );
1751
- var isSpaceKey = (key) => key.name === "space";
1752
1751
  var isBackspaceKey = (key) => key.name === "backspace";
1753
1752
  var isNumberKey = (key) => "123456789".includes(key.name);
1754
1753
  var isEnterKey = (key) => key.name === "enter" || key.name === "return";
@@ -2840,179 +2839,8 @@ var Separator = class {
2840
2839
  }
2841
2840
  };
2842
2841
 
2843
- // node_modules/@inquirer/checkbox/dist/esm/index.mjs
2844
- var import_yoctocolors_cjs3 = __toESM(require_yoctocolors_cjs(), 1);
2845
- var import_ansi_escapes2 = __toESM(require_ansi_escapes(), 1);
2846
- var checkboxTheme = {
2847
- icon: {
2848
- checked: import_yoctocolors_cjs3.default.green(esm_default.circleFilled),
2849
- unchecked: esm_default.circle,
2850
- cursor: esm_default.pointer
2851
- },
2852
- style: {
2853
- disabledChoice: (text) => import_yoctocolors_cjs3.default.dim(`- ${text}`),
2854
- renderSelectedChoices: (selectedChoices) => selectedChoices.map((choice) => choice.short).join(", "),
2855
- description: (text) => import_yoctocolors_cjs3.default.cyan(text)
2856
- },
2857
- helpMode: "auto"
2858
- };
2859
- function isSelectable(item) {
2860
- return !Separator.isSeparator(item) && !item.disabled;
2861
- }
2862
- function isChecked(item) {
2863
- return isSelectable(item) && Boolean(item.checked);
2864
- }
2865
- function toggle(item) {
2866
- return isSelectable(item) ? { ...item, checked: !item.checked } : item;
2867
- }
2868
- function check(checked) {
2869
- return function(item) {
2870
- return isSelectable(item) ? { ...item, checked } : item;
2871
- };
2872
- }
2873
- function normalizeChoices(choices) {
2874
- return choices.map((choice) => {
2875
- if (Separator.isSeparator(choice))
2876
- return choice;
2877
- if (typeof choice === "string") {
2878
- return {
2879
- value: choice,
2880
- name: choice,
2881
- short: choice,
2882
- disabled: false,
2883
- checked: false
2884
- };
2885
- }
2886
- const name = choice.name ?? String(choice.value);
2887
- return {
2888
- value: choice.value,
2889
- name,
2890
- short: choice.short ?? name,
2891
- description: choice.description,
2892
- disabled: choice.disabled ?? false,
2893
- checked: choice.checked ?? false
2894
- };
2895
- });
2896
- }
2897
- var esm_default2 = createPrompt((config, done) => {
2898
- const { instructions, pageSize = 7, loop = true, required, validate = () => true } = config;
2899
- const theme = makeTheme(checkboxTheme, config.theme);
2900
- const prefix = usePrefix({ theme });
2901
- const firstRender = useRef(true);
2902
- const [status, setStatus] = useState("pending");
2903
- const [items, setItems] = useState(normalizeChoices(config.choices));
2904
- const bounds = useMemo(() => {
2905
- const first = items.findIndex(isSelectable);
2906
- const last = items.findLastIndex(isSelectable);
2907
- if (first < 0) {
2908
- throw new ValidationError("[checkbox prompt] No selectable choices. All choices are disabled.");
2909
- }
2910
- return { first, last };
2911
- }, [items]);
2912
- const [active, setActive] = useState(bounds.first);
2913
- const [showHelpTip, setShowHelpTip] = useState(true);
2914
- const [errorMsg, setError] = useState();
2915
- useKeypress(async (key) => {
2916
- if (isEnterKey(key)) {
2917
- const selection = items.filter(isChecked);
2918
- const isValid = await validate([...selection]);
2919
- if (required && !items.some(isChecked)) {
2920
- setError("At least one choice must be selected");
2921
- } else if (isValid === true) {
2922
- setStatus("done");
2923
- done(selection.map((choice) => choice.value));
2924
- } else {
2925
- setError(isValid || "You must select a valid value");
2926
- }
2927
- } else if (isUpKey(key) || isDownKey(key)) {
2928
- if (loop || isUpKey(key) && active !== bounds.first || isDownKey(key) && active !== bounds.last) {
2929
- const offset = isUpKey(key) ? -1 : 1;
2930
- let next = active;
2931
- do {
2932
- next = (next + offset + items.length) % items.length;
2933
- } while (!isSelectable(items[next]));
2934
- setActive(next);
2935
- }
2936
- } else if (isSpaceKey(key)) {
2937
- setError(void 0);
2938
- setShowHelpTip(false);
2939
- setItems(items.map((choice, i) => i === active ? toggle(choice) : choice));
2940
- } else if (key.name === "a") {
2941
- const selectAll = items.some((choice) => isSelectable(choice) && !choice.checked);
2942
- setItems(items.map(check(selectAll)));
2943
- } else if (key.name === "i") {
2944
- setItems(items.map(toggle));
2945
- } else if (isNumberKey(key)) {
2946
- const position = Number(key.name) - 1;
2947
- const item = items[position];
2948
- if (item != null && isSelectable(item)) {
2949
- setActive(position);
2950
- setItems(items.map((choice, i) => i === position ? toggle(choice) : choice));
2951
- }
2952
- }
2953
- });
2954
- const message = theme.style.message(config.message);
2955
- let description;
2956
- const page = usePagination({
2957
- items,
2958
- active,
2959
- renderItem({ item, isActive }) {
2960
- if (Separator.isSeparator(item)) {
2961
- return ` ${item.separator}`;
2962
- }
2963
- if (item.disabled) {
2964
- const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
2965
- return theme.style.disabledChoice(`${item.name} ${disabledLabel}`);
2966
- }
2967
- if (isActive) {
2968
- description = item.description;
2969
- }
2970
- const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked;
2971
- const color = isActive ? theme.style.highlight : (x) => x;
2972
- const cursor = isActive ? theme.icon.cursor : " ";
2973
- return color(`${cursor}${checkbox} ${item.name}`);
2974
- },
2975
- pageSize,
2976
- loop
2977
- });
2978
- if (status === "done") {
2979
- const selection = items.filter(isChecked);
2980
- const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, items));
2981
- return `${prefix} ${message} ${answer}`;
2982
- }
2983
- let helpTipTop = "";
2984
- let helpTipBottom = "";
2985
- if (theme.helpMode === "always" || theme.helpMode === "auto" && showHelpTip && (instructions === void 0 || instructions)) {
2986
- if (typeof instructions === "string") {
2987
- helpTipTop = instructions;
2988
- } else {
2989
- const keys = [
2990
- `${theme.style.key("space")} to select`,
2991
- `${theme.style.key("a")} to toggle all`,
2992
- `${theme.style.key("i")} to invert selection`,
2993
- `and ${theme.style.key("enter")} to proceed`
2994
- ];
2995
- helpTipTop = ` (Press ${keys.join(", ")})`;
2996
- }
2997
- if (items.length > pageSize && (theme.helpMode === "always" || theme.helpMode === "auto" && firstRender.current)) {
2998
- helpTipBottom = `
2999
- ${theme.style.help("(Use arrow keys to reveal more choices)")}`;
3000
- firstRender.current = false;
3001
- }
3002
- }
3003
- const choiceDescription = description ? `
3004
- ${theme.style.description(description)}` : ``;
3005
- let error = "";
3006
- if (errorMsg) {
3007
- error = `
3008
- ${theme.style.error(errorMsg)}`;
3009
- }
3010
- return `${prefix} ${message}${helpTipTop}
3011
- ${page}${helpTipBottom}${choiceDescription}${error}${import_ansi_escapes2.default.cursorHide}`;
3012
- });
3013
-
3014
2842
  // node_modules/@inquirer/confirm/dist/esm/index.mjs
3015
- var esm_default3 = createPrompt((config, done) => {
2843
+ var esm_default2 = createPrompt((config, done) => {
3016
2844
  const { transformer = (answer) => answer ? "yes" : "no" } = config;
3017
2845
  const [status, setStatus] = useState("pending");
3018
2846
  const [value, setValue] = useState("");
@@ -3044,7 +2872,7 @@ var esm_default3 = createPrompt((config, done) => {
3044
2872
  });
3045
2873
 
3046
2874
  // node_modules/@inquirer/input/dist/esm/index.mjs
3047
- var esm_default4 = createPrompt((config, done) => {
2875
+ var esm_default3 = createPrompt((config, done) => {
3048
2876
  const { required, validate = () => true } = config;
3049
2877
  const theme = makeTheme(config.theme);
3050
2878
  const [status, setStatus] = useState("pending");
@@ -3104,8 +2932,8 @@ var esm_default4 = createPrompt((config, done) => {
3104
2932
  });
3105
2933
 
3106
2934
  // node_modules/@inquirer/password/dist/esm/index.mjs
3107
- var import_ansi_escapes3 = __toESM(require_ansi_escapes(), 1);
3108
- var esm_default5 = createPrompt((config, done) => {
2935
+ var import_ansi_escapes2 = __toESM(require_ansi_escapes(), 1);
2936
+ var esm_default4 = createPrompt((config, done) => {
3109
2937
  const { validate = () => true } = config;
3110
2938
  const theme = makeTheme(config.theme);
3111
2939
  const [status, setStatus] = useState("pending");
@@ -3142,7 +2970,7 @@ var esm_default5 = createPrompt((config, done) => {
3142
2970
  const maskChar = typeof config.mask === "string" ? config.mask : "*";
3143
2971
  formattedValue = maskChar.repeat(value.length);
3144
2972
  } else if (status !== "done") {
3145
- helpTip = `${theme.style.help("[input is masked]")}${import_ansi_escapes3.default.cursorHide}`;
2973
+ helpTip = `${theme.style.help("[input is masked]")}${import_ansi_escapes2.default.cursorHide}`;
3146
2974
  }
3147
2975
  if (status === "done") {
3148
2976
  formattedValue = theme.style.answer(formattedValue);
@@ -3155,20 +2983,20 @@ var esm_default5 = createPrompt((config, done) => {
3155
2983
  });
3156
2984
 
3157
2985
  // node_modules/@inquirer/select/dist/esm/index.mjs
3158
- var import_yoctocolors_cjs4 = __toESM(require_yoctocolors_cjs(), 1);
3159
- var import_ansi_escapes4 = __toESM(require_ansi_escapes(), 1);
2986
+ var import_yoctocolors_cjs3 = __toESM(require_yoctocolors_cjs(), 1);
2987
+ var import_ansi_escapes3 = __toESM(require_ansi_escapes(), 1);
3160
2988
  var selectTheme = {
3161
2989
  icon: { cursor: esm_default.pointer },
3162
2990
  style: {
3163
- disabled: (text) => import_yoctocolors_cjs4.default.dim(`- ${text}`),
3164
- description: (text) => import_yoctocolors_cjs4.default.cyan(text)
2991
+ disabled: (text) => import_yoctocolors_cjs3.default.dim(`- ${text}`),
2992
+ description: (text) => import_yoctocolors_cjs3.default.cyan(text)
3165
2993
  },
3166
2994
  helpMode: "auto"
3167
2995
  };
3168
- function isSelectable2(item) {
2996
+ function isSelectable(item) {
3169
2997
  return !Separator.isSeparator(item) && !item.disabled;
3170
2998
  }
3171
- function normalizeChoices2(choices) {
2999
+ function normalizeChoices(choices) {
3172
3000
  return choices.map((choice) => {
3173
3001
  if (Separator.isSeparator(choice))
3174
3002
  return choice;
@@ -3190,17 +3018,17 @@ function normalizeChoices2(choices) {
3190
3018
  };
3191
3019
  });
3192
3020
  }
3193
- var esm_default6 = createPrompt((config, done) => {
3021
+ var esm_default5 = createPrompt((config, done) => {
3194
3022
  const { loop = true, pageSize = 7 } = config;
3195
3023
  const firstRender = useRef(true);
3196
3024
  const theme = makeTheme(selectTheme, config.theme);
3197
3025
  const prefix = usePrefix({ theme });
3198
3026
  const [status, setStatus] = useState("pending");
3199
3027
  const searchTimeoutRef = useRef();
3200
- const items = useMemo(() => normalizeChoices2(config.choices), [config.choices]);
3028
+ const items = useMemo(() => normalizeChoices(config.choices), [config.choices]);
3201
3029
  const bounds = useMemo(() => {
3202
- const first = items.findIndex(isSelectable2);
3203
- const last = items.findLastIndex(isSelectable2);
3030
+ const first = items.findIndex(isSelectable);
3031
+ const last = items.findLastIndex(isSelectable);
3204
3032
  if (first < 0) {
3205
3033
  throw new ValidationError("[select prompt] No selectable choices. All choices are disabled.");
3206
3034
  }
@@ -3209,7 +3037,7 @@ var esm_default6 = createPrompt((config, done) => {
3209
3037
  const defaultItemIndex = useMemo(() => {
3210
3038
  if (!("default" in config))
3211
3039
  return -1;
3212
- return items.findIndex((item) => isSelectable2(item) && item.value === config.default);
3040
+ return items.findIndex((item) => isSelectable(item) && item.value === config.default);
3213
3041
  }, [config.default, items]);
3214
3042
  const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
3215
3043
  const selectedChoice = items[active];
@@ -3225,14 +3053,14 @@ var esm_default6 = createPrompt((config, done) => {
3225
3053
  let next = active;
3226
3054
  do {
3227
3055
  next = (next + offset + items.length) % items.length;
3228
- } while (!isSelectable2(items[next]));
3056
+ } while (!isSelectable(items[next]));
3229
3057
  setActive(next);
3230
3058
  }
3231
3059
  } else if (isNumberKey(key)) {
3232
3060
  rl.clearLine(0);
3233
3061
  const position = Number(key.name) - 1;
3234
3062
  const item = items[position];
3235
- if (item != null && isSelectable2(item)) {
3063
+ if (item != null && isSelectable(item)) {
3236
3064
  setActive(position);
3237
3065
  }
3238
3066
  } else if (isBackspaceKey(key)) {
@@ -3240,7 +3068,7 @@ var esm_default6 = createPrompt((config, done) => {
3240
3068
  } else {
3241
3069
  const searchTerm = rl.line.toLowerCase();
3242
3070
  const matchIndex = items.findIndex((item) => {
3243
- if (Separator.isSeparator(item) || !isSelectable2(item))
3071
+ if (Separator.isSeparator(item) || !isSelectable(item))
3244
3072
  return false;
3245
3073
  return item.name.toLowerCase().startsWith(searchTerm);
3246
3074
  });
@@ -3291,13 +3119,13 @@ ${theme.style.help("(Use arrow keys to reveal more choices)")}`;
3291
3119
  const choiceDescription = selectedChoice.description ? `
3292
3120
  ${theme.style.description(selectedChoice.description)}` : ``;
3293
3121
  return `${[prefix, message, helpTipTop].filter(Boolean).join(" ")}
3294
- ${page}${helpTipBottom}${choiceDescription}${import_ansi_escapes4.default.cursorHide}`;
3122
+ ${page}${helpTipBottom}${choiceDescription}${import_ansi_escapes3.default.cursorHide}`;
3295
3123
  });
3296
3124
 
3297
3125
  // src/index.ts
3298
- var import_fs17 = require("fs");
3126
+ var import_fs18 = require("fs");
3299
3127
  var import_readline2 = require("readline");
3300
- var import_path17 = require("path");
3128
+ var import_path18 = require("path");
3301
3129
 
3302
3130
  // src/utils/fetch.ts
3303
3131
  var DEFAULT_TIMEOUT_MS = 3e4;
@@ -4215,8 +4043,8 @@ async function fetchContexts(domains, token, repo, targetDir) {
4215
4043
  }
4216
4044
 
4217
4045
  // src/steps/resources/fetch-factory.ts
4218
- var import_fs9 = require("fs");
4219
- var import_path9 = require("path");
4046
+ var import_fs10 = require("fs");
4047
+ var import_path10 = require("path");
4220
4048
 
4221
4049
  // src/bundles/run-bundle.ts
4222
4050
  var import_fs8 = require("fs");
@@ -4729,6 +4557,40 @@ function assertBundleRootExists(ctx) {
4729
4557
  }
4730
4558
  }
4731
4559
 
4560
+ // src/utils/channel.ts
4561
+ var import_fs9 = require("fs");
4562
+ var import_path9 = require("path");
4563
+ function getChannel() {
4564
+ try {
4565
+ const pkgPath = (0, import_path9.join)(__dirname, "..", "package.json");
4566
+ const { version } = JSON.parse((0, import_fs9.readFileSync)(pkgPath, "utf-8"));
4567
+ if (typeof version === "string" && version.includes("-")) return "test";
4568
+ } catch {
4569
+ }
4570
+ return "prod";
4571
+ }
4572
+
4573
+ // src/utils/resolve-release.ts
4574
+ async function fetchLatestPrerelease(token, repo) {
4575
+ const headers = {
4576
+ "Accept": "application/vnd.github+json",
4577
+ "Authorization": `Bearer ${token}`
4578
+ };
4579
+ const res = await fetchWithRetry(`https://api.github.com/repos/${repo}/releases?per_page=100`, { headers });
4580
+ if (!res.ok) {
4581
+ throw new Error(`GitHub API error (${res.status}): ${getReadableError(res.status)}`);
4582
+ }
4583
+ const releases = await res.json();
4584
+ const match = releases.find((r) => r.prerelease === true);
4585
+ if (!match) {
4586
+ throw new Error(`No pre-release found in ${repo} (test channel)`);
4587
+ }
4588
+ return { tagName: match.tag_name ?? "unknown", assets: match.assets ?? [] };
4589
+ }
4590
+ async function resolveReleaseForChannel(token, repo) {
4591
+ return getChannel() === "test" ? fetchLatestPrerelease(token, repo) : fetchLatestRelease(token, repo);
4592
+ }
4593
+
4732
4594
  // src/steps/resources/fetch-factory.ts
4733
4595
  var FACTORY_ASSET_NAME = "factory.tar.gz";
4734
4596
  var FACTORY_ROOT_FOLDER = "factory";
@@ -4777,7 +4639,7 @@ var fetch_factory_default = defineStep({
4777
4639
  const sortedCreated = [...created].sort((a, b) => a.length - b.length);
4778
4640
  for (const rel of sortedCreated) {
4779
4641
  const abs = resolveProjectPath(rel, projectPath);
4780
- if (!(0, import_fs9.existsSync)(abs)) continue;
4642
+ if (!(0, import_fs10.existsSync)(abs)) continue;
4781
4643
  if (isDirectorySafe(abs)) {
4782
4644
  deleteDirIfExists(abs);
4783
4645
  summary.push(`removed ${rel}`);
@@ -4805,7 +4667,7 @@ async function fetchFactory(token, repo, targetDir, agent, agentTeams) {
4805
4667
  };
4806
4668
  let release;
4807
4669
  try {
4808
- release = await fetchLatestRelease(token, repo);
4670
+ release = await resolveReleaseForChannel(token, repo);
4809
4671
  } catch (err) {
4810
4672
  result.failureReason = err instanceof Error ? err.message : String(err);
4811
4673
  return result;
@@ -4818,15 +4680,15 @@ async function fetchFactory(token, repo, targetDir, agent, agentTeams) {
4818
4680
  let archive = null;
4819
4681
  try {
4820
4682
  archive = await downloadAndExtractAsset(token, asset, targetDir, ".temp-factory-download");
4821
- const extractedEntries = (0, import_fs9.readdirSync)(archive.extractedRoot);
4683
+ const extractedEntries = (0, import_fs10.readdirSync)(archive.extractedRoot);
4822
4684
  const extractedFolder = extractedEntries.find((e) => e.toLowerCase() === FACTORY_ROOT_FOLDER.toLowerCase());
4823
4685
  if (!extractedFolder) {
4824
4686
  result.failureReason = `No ${FACTORY_ROOT_FOLDER}/ folder in archive`;
4825
4687
  return result;
4826
4688
  }
4827
- const extractedPath = (0, import_path9.join)(archive.extractedRoot, extractedFolder);
4828
- const manifestPath = (0, import_path9.join)(extractedPath, "install.json");
4829
- if (!(0, import_fs9.existsSync)(manifestPath)) {
4689
+ const extractedPath = (0, import_path10.join)(archive.extractedRoot, extractedFolder);
4690
+ const manifestPath = (0, import_path10.join)(extractedPath, "install.json");
4691
+ if (!(0, import_fs10.existsSync)(manifestPath)) {
4830
4692
  result.failureReason = "Factory archive has no install.json \u2014 upgrade Factory or downgrade installer";
4831
4693
  return result;
4832
4694
  }
@@ -4842,7 +4704,7 @@ async function fetchFactory(token, repo, targetDir, agent, agentTeams) {
4842
4704
  async function installViaBundle(manifestPath, extractedPath, targetDir, agent, agentTeams, result) {
4843
4705
  let manifest;
4844
4706
  try {
4845
- manifest = JSON.parse((0, import_fs9.readFileSync)(manifestPath, "utf-8"));
4707
+ manifest = JSON.parse((0, import_fs10.readFileSync)(manifestPath, "utf-8"));
4846
4708
  } catch (e) {
4847
4709
  throw new Error(`install.json is not valid JSON: ${e instanceof Error ? e.message : String(e)}`);
4848
4710
  }
@@ -4865,8 +4727,8 @@ async function installViaBundle(manifestPath, extractedPath, targetDir, agent, a
4865
4727
  }
4866
4728
 
4867
4729
  // src/steps/resources/fetch-abap-hooks.ts
4868
- var import_fs10 = require("fs");
4869
- var import_path10 = require("path");
4730
+ var import_fs11 = require("fs");
4731
+ var import_path11 = require("path");
4870
4732
  var HOOKS_ASSET_NAME = "sap-hooks.tar.gz";
4871
4733
  var HOOKS_TAG_PREFIX = "hooks-v";
4872
4734
  var HOOKS_ROOT_FOLDER = "hooks";
@@ -4998,7 +4860,7 @@ async function fetchAbapHooks(token, repo, targetDir, agent) {
4998
4860
  let archive = null;
4999
4861
  try {
5000
4862
  archive = await downloadAndExtractAsset(token, asset, targetDir, ".temp-abap-hooks-download");
5001
- const extractedEntries = (0, import_fs10.readdirSync)(archive.extractedRoot);
4863
+ const extractedEntries = (0, import_fs11.readdirSync)(archive.extractedRoot);
5002
4864
  const innerFolder = extractedEntries.find(
5003
4865
  (e) => e.toLowerCase() === HOOKS_ROOT_FOLDER.toLowerCase()
5004
4866
  );
@@ -5006,12 +4868,12 @@ async function fetchAbapHooks(token, repo, targetDir, agent) {
5006
4868
  result.failureReason = `No ${HOOKS_ROOT_FOLDER}/ folder in archive`;
5007
4869
  return result;
5008
4870
  }
5009
- const bundleRoot = (0, import_path10.join)(archive.extractedRoot, innerFolder);
5010
- if (!(0, import_fs10.statSync)(bundleRoot).isDirectory()) {
4871
+ const bundleRoot = (0, import_path11.join)(archive.extractedRoot, innerFolder);
4872
+ if (!(0, import_fs11.statSync)(bundleRoot).isDirectory()) {
5011
4873
  result.failureReason = `${HOOKS_ROOT_FOLDER}/ entry is not a directory`;
5012
4874
  return result;
5013
4875
  }
5014
- const presentDefs = HOOK_DEFINITIONS.filter((d) => (0, import_fs10.existsSync)((0, import_path10.join)(bundleRoot, d.script)));
4876
+ const presentDefs = HOOK_DEFINITIONS.filter((d) => (0, import_fs11.existsSync)((0, import_path11.join)(bundleRoot, d.script)));
5015
4877
  if (presentDefs.length === 0) {
5016
4878
  result.failureReason = "Archive contains no recognized hook scripts";
5017
4879
  return result;
@@ -5065,8 +4927,8 @@ async function fetchAbapHooks(token, repo, targetDir, agent) {
5065
4927
  }
5066
4928
 
5067
4929
  // src/steps/setup/write-instructions.ts
5068
- var import_fs11 = require("fs");
5069
- var import_path11 = require("path");
4930
+ var import_fs12 = require("fs");
4931
+ var import_path12 = require("path");
5070
4932
 
5071
4933
  // src/steps/shared.ts
5072
4934
  var cached = null;
@@ -5101,13 +4963,13 @@ var write_instructions_default = defineStep({
5101
4963
  const projectPath = ctx.config.projectPath;
5102
4964
  const content = buildCombinedInstructions(domains, filteredMcpConfig, agent, projectPath);
5103
4965
  const target = getAgentTarget(agent);
5104
- const filePath = (0, import_path11.join)(projectPath, target.instructions);
5105
- const fileDir = (0, import_path11.dirname)(filePath);
5106
- if (!(0, import_fs11.existsSync)(fileDir)) (0, import_fs11.mkdirSync)(fileDir, { recursive: true });
5107
- const fileExistedBefore = (0, import_fs11.existsSync)(filePath);
4966
+ const filePath = (0, import_path12.join)(projectPath, target.instructions);
4967
+ const fileDir = (0, import_path12.dirname)(filePath);
4968
+ if (!(0, import_fs12.existsSync)(fileDir)) (0, import_fs12.mkdirSync)(fileDir, { recursive: true });
4969
+ const fileExistedBefore = (0, import_fs12.existsSync)(filePath);
5108
4970
  let cursorFrontmatterWritten = false;
5109
4971
  if (agent === "cursor" && !fileExistedBefore) {
5110
- (0, import_fs11.writeFileSync)(filePath, `---
4972
+ (0, import_fs12.writeFileSync)(filePath, `---
5111
4973
  description: AI development instructions from One-Shot Installer
5112
4974
  alwaysApply: true
5113
4975
  ---
@@ -5188,16 +5050,16 @@ alwaysApply: true
5188
5050
  }
5189
5051
  });
5190
5052
  function collectMdFiles(dir) {
5191
- if (!(0, import_fs11.existsSync)(dir)) return [];
5192
- const entries = (0, import_fs11.readdirSync)(dir, { recursive: true });
5053
+ if (!(0, import_fs12.existsSync)(dir)) return [];
5054
+ const entries = (0, import_fs12.readdirSync)(dir, { recursive: true });
5193
5055
  return entries.filter((entry) => {
5194
- const fullPath = (0, import_path11.join)(dir, entry);
5195
- return entry.endsWith(".md") && (0, import_fs11.statSync)(fullPath).isFile();
5056
+ const fullPath = (0, import_path12.join)(dir, entry);
5057
+ return entry.endsWith(".md") && (0, import_fs12.statSync)(fullPath).isFile();
5196
5058
  }).map((entry) => entry.replace(/\\/g, "/")).sort();
5197
5059
  }
5198
5060
  function extractFirstHeading(filePath) {
5199
5061
  try {
5200
- const content = (0, import_fs11.readFileSync)(filePath, "utf-8");
5062
+ const content = (0, import_fs12.readFileSync)(filePath, "utf-8");
5201
5063
  const withoutFrontmatter = content.replace(/^---[\s\S]*?---\s*/, "");
5202
5064
  const match = withoutFrontmatter.match(/^#\s+(.+)/m);
5203
5065
  if (match) {
@@ -5215,16 +5077,16 @@ function formatPathRef(contextPath, description, agent) {
5215
5077
  return `- \`${contextPath}\` \u2014 ${description}`;
5216
5078
  }
5217
5079
  function resolveDomainFolder(domain, contextsDir) {
5218
- if ((0, import_fs11.existsSync)(contextsDir)) {
5080
+ if ((0, import_fs12.existsSync)(contextsDir)) {
5219
5081
  try {
5220
- const entries = (0, import_fs11.readdirSync)(contextsDir);
5082
+ const entries = (0, import_fs12.readdirSync)(contextsDir);
5221
5083
  const match = entries.find((e) => e.toLowerCase() === domain.toLowerCase());
5222
- if (match) return { folderName: match, folderPath: (0, import_path11.join)(contextsDir, match) };
5084
+ if (match) return { folderName: match, folderPath: (0, import_path12.join)(contextsDir, match) };
5223
5085
  } catch {
5224
5086
  }
5225
5087
  }
5226
5088
  const fallback = domain.toUpperCase();
5227
- return { folderName: fallback, folderPath: (0, import_path11.join)(contextsDir, fallback) };
5089
+ return { folderName: fallback, folderPath: (0, import_path12.join)(contextsDir, fallback) };
5228
5090
  }
5229
5091
  function buildContextRefsSection(domains, agent, contextsDir) {
5230
5092
  const lines2 = [
@@ -5236,34 +5098,34 @@ function buildContextRefsSection(domains, agent, contextsDir) {
5236
5098
  let hasAnyFiles = false;
5237
5099
  for (const domain of domains) {
5238
5100
  const { folderName, folderPath: domainPath } = resolveDomainFolder(domain, contextsDir);
5239
- if (!(0, import_fs11.existsSync)(domainPath)) continue;
5101
+ if (!(0, import_fs12.existsSync)(domainPath)) continue;
5240
5102
  const domainFiles = [];
5241
- const ctxInstructions = (0, import_path11.join)(domainPath, "context-instructions.md");
5242
- if ((0, import_fs11.existsSync)(ctxInstructions)) {
5103
+ const ctxInstructions = (0, import_path12.join)(domainPath, "context-instructions.md");
5104
+ if ((0, import_fs12.existsSync)(ctxInstructions)) {
5243
5105
  const desc = extractFirstHeading(ctxInstructions);
5244
5106
  domainFiles.push(formatPathRef(`_ai-context/${folderName}/context-instructions.md`, desc, agent));
5245
5107
  }
5246
- const instructionsMd = (0, import_path11.join)(domainPath, "core", "instructions.md");
5247
- if ((0, import_fs11.existsSync)(instructionsMd)) {
5108
+ const instructionsMd = (0, import_path12.join)(domainPath, "core", "instructions.md");
5109
+ if ((0, import_fs12.existsSync)(instructionsMd)) {
5248
5110
  const desc = extractFirstHeading(instructionsMd);
5249
5111
  domainFiles.push(formatPathRef(`_ai-context/${folderName}/core/instructions.md`, `${desc} (start here)`, agent));
5250
5112
  }
5251
- const coreDir = (0, import_path11.join)(domainPath, "core");
5252
- if ((0, import_fs11.existsSync)(coreDir)) {
5113
+ const coreDir = (0, import_path12.join)(domainPath, "core");
5114
+ if ((0, import_fs12.existsSync)(coreDir)) {
5253
5115
  const coreFiles = collectMdFiles(coreDir).filter((f) => f !== "instructions.md" && !f.startsWith("instructions/"));
5254
5116
  for (const file of coreFiles) {
5255
- const desc = extractFirstHeading((0, import_path11.join)(coreDir, file));
5117
+ const desc = extractFirstHeading((0, import_path12.join)(coreDir, file));
5256
5118
  domainFiles.push(formatPathRef(`_ai-context/${folderName}/core/${file}`, desc, agent));
5257
5119
  }
5258
5120
  }
5259
- const refDir = (0, import_path11.join)(domainPath, "reference");
5260
- if ((0, import_fs11.existsSync)(refDir)) {
5121
+ const refDir = (0, import_path12.join)(domainPath, "reference");
5122
+ if ((0, import_fs12.existsSync)(refDir)) {
5261
5123
  const refFiles = collectMdFiles(refDir);
5262
5124
  if (refFiles.length > 0) {
5263
5125
  domainFiles.push(``);
5264
5126
  domainFiles.push(`**Reference & cheat sheets:**`);
5265
5127
  for (const file of refFiles) {
5266
- const desc = extractFirstHeading((0, import_path11.join)(refDir, file));
5128
+ const desc = extractFirstHeading((0, import_path12.join)(refDir, file));
5267
5129
  domainFiles.push(formatPathRef(`_ai-context/${folderName}/reference/${file}`, desc, agent));
5268
5130
  }
5269
5131
  }
@@ -5294,7 +5156,7 @@ function buildMCPSection(mcpConfig) {
5294
5156
  return lines2.join("\n");
5295
5157
  }
5296
5158
  function buildCombinedInstructions(domains, mcpConfig, agent, projectPath) {
5297
- const contextsDir = (0, import_path11.join)(projectPath, "_ai-context");
5159
+ const contextsDir = (0, import_path12.join)(projectPath, "_ai-context");
5298
5160
  const lines2 = [`# AI Development Instructions`, ``, `> Generated by One-Shot Installer`, ``];
5299
5161
  lines2.push(buildContextRefsSection(domains, agent, contextsDir));
5300
5162
  if (Object.keys(mcpConfig).length > 0) lines2.push(buildMCPSection(mcpConfig));
@@ -5302,8 +5164,8 @@ function buildCombinedInstructions(domains, mcpConfig, agent, projectPath) {
5302
5164
  }
5303
5165
 
5304
5166
  // src/steps/setup/write-mcp-config.ts
5305
- var import_fs12 = require("fs");
5306
- var import_path12 = require("path");
5167
+ var import_fs13 = require("fs");
5168
+ var import_path13 = require("path");
5307
5169
  var red2 = (text) => `\x1B[31m${text}\x1B[0m`;
5308
5170
  var write_mcp_config_default = defineStep({
5309
5171
  name: "write-mcp-config",
@@ -5315,16 +5177,16 @@ var write_mcp_config_default = defineStep({
5315
5177
  execute: async (ctx) => {
5316
5178
  const filteredMcpConfig = getFilteredMcpConfig(ctx);
5317
5179
  const target = getAgentTarget(ctx.config.agent);
5318
- const mcpJsonPath = (0, import_path12.join)(ctx.config.projectPath, target.mcpConfig);
5319
- const fileExistedBefore = (0, import_fs12.existsSync)(mcpJsonPath);
5180
+ const mcpJsonPath = (0, import_path13.join)(ctx.config.projectPath, target.mcpConfig);
5181
+ const fileExistedBefore = (0, import_fs13.existsSync)(mcpJsonPath);
5320
5182
  if (target.mcpDir) {
5321
- const dir = (0, import_path12.join)(ctx.config.projectPath, target.mcpDir);
5322
- if (!(0, import_fs12.existsSync)(dir)) (0, import_fs12.mkdirSync)(dir, { recursive: true });
5183
+ const dir = (0, import_path13.join)(ctx.config.projectPath, target.mcpDir);
5184
+ if (!(0, import_fs13.existsSync)(dir)) (0, import_fs13.mkdirSync)(dir, { recursive: true });
5323
5185
  }
5324
5186
  let existingFile = {};
5325
- if ((0, import_fs12.existsSync)(mcpJsonPath)) {
5187
+ if ((0, import_fs13.existsSync)(mcpJsonPath)) {
5326
5188
  try {
5327
- existingFile = JSON.parse((0, import_fs12.readFileSync)(mcpJsonPath, "utf-8"));
5189
+ existingFile = JSON.parse((0, import_fs13.readFileSync)(mcpJsonPath, "utf-8"));
5328
5190
  } catch {
5329
5191
  const box = [
5330
5192
  "",
@@ -5350,7 +5212,7 @@ var write_mcp_config_default = defineStep({
5350
5212
  }
5351
5213
  const mergedServers = { ...existingServers, ...newServers };
5352
5214
  const outputFile = { ...existingFile, [target.mcpRootKey]: mergedServers };
5353
- (0, import_fs12.writeFileSync)(mcpJsonPath, JSON.stringify(outputFile, null, 2), "utf-8");
5215
+ (0, import_fs13.writeFileSync)(mcpJsonPath, JSON.stringify(outputFile, null, 2), "utf-8");
5354
5216
  ctx.installed.mcpServersAdded = addedServers;
5355
5217
  const record = {
5356
5218
  filePath: target.mcpConfig,
@@ -5471,14 +5333,14 @@ var run_mcp_install_commands_default = defineStep({
5471
5333
  }
5472
5334
  });
5473
5335
  function isClaudeCliAvailable() {
5474
- const check2 = (0, import_child_process3.spawnSync)("claude --version", { shell: true, stdio: "ignore" });
5475
- return check2.status === 0;
5336
+ const check = (0, import_child_process3.spawnSync)("claude --version", { shell: true, stdio: "ignore" });
5337
+ return check.status === 0;
5476
5338
  }
5477
5339
 
5478
5340
  // src/steps/setup/build-code-index.ts
5479
5341
  var import_child_process4 = require("child_process");
5480
- var import_fs13 = require("fs");
5481
- var import_path13 = require("path");
5342
+ var import_fs14 = require("fs");
5343
+ var import_path14 = require("path");
5482
5344
  var CODE_INDEX_RELATIVE_PATH = ".claude/factory/utils/code-index";
5483
5345
  var INDEX_OUTPUT_RELATIVE_PATH = ".claude/factory/repo-index.json";
5484
5346
  var INDEX_STAMP_RELATIVE_PATH = ".claude/factory/index.stamp";
@@ -5487,8 +5349,8 @@ var build_code_index_default = defineStep({
5487
5349
  label: "Building code index",
5488
5350
  when: (ctx) => ctx.installed.factoryInstalled === true,
5489
5351
  execute: async (ctx) => {
5490
- const codeIndexDirectory = (0, import_path13.join)(ctx.config.projectPath, CODE_INDEX_RELATIVE_PATH);
5491
- if (!(0, import_fs13.existsSync)(codeIndexDirectory)) {
5352
+ const codeIndexDirectory = (0, import_path14.join)(ctx.config.projectPath, CODE_INDEX_RELATIVE_PATH);
5353
+ if (!(0, import_fs14.existsSync)(codeIndexDirectory)) {
5492
5354
  return {
5493
5355
  status: "skipped",
5494
5356
  detail: `code-index not found at ${CODE_INDEX_RELATIVE_PATH} \u2014 older Factory release?`,
@@ -5517,7 +5379,7 @@ var build_code_index_default = defineStep({
5517
5379
  record: { depsInstalled: false, indexBuilt: false }
5518
5380
  };
5519
5381
  }
5520
- const indexerScriptPath = (0, import_path13.join)(codeIndexDirectory, "index.cjs");
5382
+ const indexerScriptPath = (0, import_path14.join)(codeIndexDirectory, "index.cjs");
5521
5383
  const indexerResult = (0, import_child_process4.spawnSync)(`node "${indexerScriptPath}" "${ctx.config.projectPath}"`, {
5522
5384
  shell: true,
5523
5385
  stdio: "pipe",
@@ -5548,21 +5410,21 @@ var build_code_index_default = defineStep({
5548
5410
  const projectPath = ctx.config.projectPath;
5549
5411
  const summaryActions = [];
5550
5412
  if (record.indexBuilt) {
5551
- const indexFilePath = (0, import_path13.join)(projectPath, INDEX_OUTPUT_RELATIVE_PATH);
5552
- if ((0, import_fs13.existsSync)(indexFilePath)) {
5553
- (0, import_fs13.unlinkSync)(indexFilePath);
5413
+ const indexFilePath = (0, import_path14.join)(projectPath, INDEX_OUTPUT_RELATIVE_PATH);
5414
+ if ((0, import_fs14.existsSync)(indexFilePath)) {
5415
+ (0, import_fs14.unlinkSync)(indexFilePath);
5554
5416
  summaryActions.push(`removed ${INDEX_OUTPUT_RELATIVE_PATH}`);
5555
5417
  }
5556
- const stampFilePath = (0, import_path13.join)(projectPath, INDEX_STAMP_RELATIVE_PATH);
5557
- if ((0, import_fs13.existsSync)(stampFilePath)) {
5558
- (0, import_fs13.unlinkSync)(stampFilePath);
5418
+ const stampFilePath = (0, import_path14.join)(projectPath, INDEX_STAMP_RELATIVE_PATH);
5419
+ if ((0, import_fs14.existsSync)(stampFilePath)) {
5420
+ (0, import_fs14.unlinkSync)(stampFilePath);
5559
5421
  summaryActions.push(`removed ${INDEX_STAMP_RELATIVE_PATH}`);
5560
5422
  }
5561
5423
  }
5562
5424
  if (record.depsInstalled) {
5563
- const nodeModulesPath = (0, import_path13.join)(projectPath, CODE_INDEX_RELATIVE_PATH, "node_modules");
5564
- if ((0, import_fs13.existsSync)(nodeModulesPath)) {
5565
- (0, import_fs13.rmSync)(nodeModulesPath, { recursive: true, force: true });
5425
+ const nodeModulesPath = (0, import_path14.join)(projectPath, CODE_INDEX_RELATIVE_PATH, "node_modules");
5426
+ if ((0, import_fs14.existsSync)(nodeModulesPath)) {
5427
+ (0, import_fs14.rmSync)(nodeModulesPath, { recursive: true, force: true });
5566
5428
  summaryActions.push("removed code-index node_modules");
5567
5429
  }
5568
5430
  }
@@ -5579,8 +5441,8 @@ function isNodeAvailable() {
5579
5441
  }
5580
5442
 
5581
5443
  // src/steps/setup/update-gitignore.ts
5582
- var import_fs14 = require("fs");
5583
- var import_path14 = require("path");
5444
+ var import_fs15 = require("fs");
5445
+ var import_path15 = require("path");
5584
5446
  var MARKER_START2 = "# one-shot-installer:start";
5585
5447
  var MARKER_END2 = "# one-shot-installer:end";
5586
5448
  var CORE_GITIGNORE_ENTRIES = [
@@ -5601,8 +5463,8 @@ var update_gitignore_default = defineStep({
5601
5463
  name: "update-gitignore",
5602
5464
  label: "Updating .gitignore",
5603
5465
  execute: async (ctx) => {
5604
- const gitignorePath = (0, import_path14.join)(ctx.config.projectPath, ".gitignore");
5605
- const fileExistedBefore = (0, import_fs14.existsSync)(gitignorePath);
5466
+ const gitignorePath = (0, import_path15.join)(ctx.config.projectPath, ".gitignore");
5467
+ const fileExistedBefore = (0, import_fs15.existsSync)(gitignorePath);
5606
5468
  upsertMarkerBlock(gitignorePath, MARKER_START2, MARKER_END2, CORE_GITIGNORE_ENTRIES.join("\n"));
5607
5469
  const record = {
5608
5470
  filePath: ".gitignore",
@@ -5630,8 +5492,8 @@ var update_gitignore_default = defineStep({
5630
5492
  });
5631
5493
 
5632
5494
  // src/steps/setup/write-state.ts
5633
- var import_fs15 = require("fs");
5634
- var import_path15 = require("path");
5495
+ var import_fs16 = require("fs");
5496
+ var import_path16 = require("path");
5635
5497
  var import_os2 = require("os");
5636
5498
 
5637
5499
  // package.json
@@ -5645,7 +5507,8 @@ var package_default = {
5645
5507
  dev: "tsx src/index.ts",
5646
5508
  build: 'esbuild src/index.ts --bundle --platform=node --banner:js="#!/usr/bin/env node" --outfile=wrapper/bin/installer.js',
5647
5509
  "build:all": "npm run build",
5648
- "publish:wrapper": "cd wrapper && npm publish"
5510
+ "publish:test": "cd wrapper && npm publish --tag canary",
5511
+ "publish:prod": "cd wrapper && npm publish --tag latest"
5649
5512
  },
5650
5513
  dependencies: {
5651
5514
  "@inquirer/prompts": "^5.0.0"
@@ -5665,7 +5528,7 @@ var write_state_default = defineStep({
5665
5528
  name: "write-state",
5666
5529
  label: "Saving installation state",
5667
5530
  execute: async (ctx) => {
5668
- const statePath = (0, import_path15.join)(ctx.config.projectPath, ".one-shot-state.json");
5531
+ const statePath = (0, import_path16.join)(ctx.config.projectPath, ".one-shot-state.json");
5669
5532
  const mcpServersAdded = ctx.installed.mcpServersAdded ?? [];
5670
5533
  const filteredMcpConfig = Object.fromEntries(
5671
5534
  Object.entries(ctx.config.mcpConfig).filter(([name]) => mcpServersAdded.includes(name))
@@ -5696,13 +5559,13 @@ var write_state_default = defineStep({
5696
5559
  * mislead the uninstall preview which reads this field. */
5697
5560
  factory: ctx.installed.factoryInstalled ? ".claude/" : null,
5698
5561
  abapHooks: ctx.installed.abapHooksInstalled ? ".claude/hooks/" : null,
5699
- globalConfig: (0, import_path15.join)((0, import_os2.homedir)(), ".one-shot-installer")
5562
+ globalConfig: (0, import_path16.join)((0, import_os2.homedir)(), ".one-shot-installer")
5700
5563
  }
5701
5564
  };
5702
5565
  if (ctx.journal) {
5703
5566
  ctx.journal.setSummary(state);
5704
5567
  } else {
5705
- (0, import_fs15.writeFileSync)(statePath, JSON.stringify(state, null, 2), "utf-8");
5568
+ (0, import_fs16.writeFileSync)(statePath, JSON.stringify(state, null, 2), "utf-8");
5706
5569
  }
5707
5570
  return { status: "success" };
5708
5571
  },
@@ -5717,9 +5580,9 @@ var write_state_default = defineStep({
5717
5580
  });
5718
5581
 
5719
5582
  // src/uninstall.ts
5720
- var import_fs16 = require("fs");
5583
+ var import_fs17 = require("fs");
5721
5584
  var import_readline = require("readline");
5722
- var import_path16 = require("path");
5585
+ var import_path17 = require("path");
5723
5586
  var dim = (text) => `\x1B[2m${text}\x1B[0m`;
5724
5587
  var yellow = (text) => `\x1B[33m${text}\x1B[0m`;
5725
5588
  var red3 = (text) => `\x1B[31m${text}\x1B[0m`;
@@ -5737,13 +5600,13 @@ async function uninstall() {
5737
5600
  console.clear();
5738
5601
  console.log("One-Shot Setup Uninstaller\n");
5739
5602
  try {
5740
- const projectInput = await esm_default4({
5603
+ const projectInput = await esm_default3({
5741
5604
  message: "Project directory to uninstall from:",
5742
- default: (0, import_path16.resolve)(process.cwd())
5605
+ default: (0, import_path17.resolve)(process.cwd())
5743
5606
  });
5744
- const projectPath = (0, import_path16.resolve)(projectInput);
5745
- const statePath = (0, import_path16.join)(projectPath, ".one-shot-state.json");
5746
- if (!(0, import_fs16.existsSync)(statePath)) {
5607
+ const projectPath = (0, import_path17.resolve)(projectInput);
5608
+ const statePath = (0, import_path17.join)(projectPath, ".one-shot-state.json");
5609
+ if (!(0, import_fs17.existsSync)(statePath)) {
5747
5610
  console.log("");
5748
5611
  console.log(red3(" No .one-shot-state.json found at:"));
5749
5612
  console.log(` ${statePath}`);
@@ -5763,12 +5626,12 @@ async function uninstall() {
5763
5626
  console.log(dim(" This file was likely written by an older installer version that"));
5764
5627
  console.log(dim(" did not yet emit a journal. Manual cleanup is required."));
5765
5628
  console.log("");
5766
- const proceed2 = await esm_default3({
5629
+ const proceed2 = await esm_default2({
5767
5630
  message: "Delete the state file anyway?",
5768
5631
  default: false
5769
5632
  });
5770
5633
  if (proceed2) {
5771
- (0, import_fs16.unlinkSync)(statePath);
5634
+ (0, import_fs17.unlinkSync)(statePath);
5772
5635
  console.log(" Removed .one-shot-state.json");
5773
5636
  }
5774
5637
  await waitForEnter();
@@ -5776,7 +5639,7 @@ async function uninstall() {
5776
5639
  }
5777
5640
  const summary = readSummary(statePath);
5778
5641
  printPreview(projectPath, summary, entries.length);
5779
- const proceed = await esm_default3({
5642
+ const proceed = await esm_default2({
5780
5643
  message: "Proceed with uninstall?",
5781
5644
  default: false
5782
5645
  });
@@ -5810,7 +5673,7 @@ async function uninstall() {
5810
5673
  console.log("");
5811
5674
  const result = await runRollback(stepList, ctx);
5812
5675
  try {
5813
- if ((0, import_fs16.existsSync)(statePath)) (0, import_fs16.unlinkSync)(statePath);
5676
+ if ((0, import_fs17.existsSync)(statePath)) (0, import_fs17.unlinkSync)(statePath);
5814
5677
  } catch {
5815
5678
  }
5816
5679
  printSummary(result);
@@ -5822,7 +5685,7 @@ async function uninstall() {
5822
5685
  }
5823
5686
  function readSummary(statePath) {
5824
5687
  try {
5825
- const raw = JSON.parse((0, import_fs16.readFileSync)(statePath, "utf-8"));
5688
+ const raw = JSON.parse((0, import_fs17.readFileSync)(statePath, "utf-8"));
5826
5689
  return raw;
5827
5690
  } catch {
5828
5691
  return {};
@@ -5903,19 +5766,19 @@ var dim2 = (text) => `\x1B[2m${text}\x1B[0m`;
5903
5766
  var yellow2 = (text) => `\x1B[33m${text}\x1B[0m`;
5904
5767
  var green2 = (text) => `\x1B[32m${text}\x1B[0m`;
5905
5768
  function detectMarkerFileMode(filePath, markerStart) {
5906
- if (!(0, import_fs17.existsSync)(filePath)) return green2("create");
5907
- const content = (0, import_fs17.readFileSync)(filePath, "utf-8");
5769
+ if (!(0, import_fs18.existsSync)(filePath)) return green2("create");
5770
+ const content = (0, import_fs18.readFileSync)(filePath, "utf-8");
5908
5771
  if (content.includes(markerStart)) return yellow2("update");
5909
5772
  return yellow2("append");
5910
5773
  }
5911
5774
  function detectMCPFileMode(filePath) {
5912
- if (!(0, import_fs17.existsSync)(filePath)) return green2("create");
5775
+ if (!(0, import_fs18.existsSync)(filePath)) return green2("create");
5913
5776
  return yellow2("merge");
5914
5777
  }
5915
5778
  function detectContextMode(projectPath, domain) {
5916
- const contextDir = (0, import_path17.join)(projectPath, "_ai-context", domain.toUpperCase());
5917
- const contextDirLower = (0, import_path17.join)(projectPath, "_ai-context", domain);
5918
- if ((0, import_fs17.existsSync)(contextDir) || (0, import_fs17.existsSync)(contextDirLower)) return yellow2("overwrite");
5779
+ const contextDir = (0, import_path18.join)(projectPath, "_ai-context", domain.toUpperCase());
5780
+ const contextDirLower = (0, import_path18.join)(projectPath, "_ai-context", domain);
5781
+ if ((0, import_fs18.existsSync)(contextDir) || (0, import_fs18.existsSync)(contextDirLower)) return yellow2("overwrite");
5919
5782
  return green2("create");
5920
5783
  }
5921
5784
  function waitForEnter2() {
@@ -5961,7 +5824,7 @@ async function main() {
5961
5824
  await waitForEnter2();
5962
5825
  return;
5963
5826
  }
5964
- const statePath = (0, import_path17.join)(config.projectPath, ".one-shot-state.json");
5827
+ const statePath = (0, import_path18.join)(config.projectPath, ".one-shot-state.json");
5965
5828
  const journal = new Journal(statePath);
5966
5829
  journal.startFresh();
5967
5830
  const ctx = {
@@ -5985,28 +5848,15 @@ async function main() {
5985
5848
  }
5986
5849
  }
5987
5850
  async function collectInputs(options, releaseVersion, factoryAvailable = false, abapHooksAvailable = false) {
5988
- const selectedIds = await esm_default2({
5989
- message: "Technology:",
5990
- instructions: " Space to select \xB7 Enter to confirm",
5991
- choices: [
5992
- ...options.technologies.map((p) => ({
5993
- name: p.name.replace(/ Developer$/, ""),
5994
- value: p.id
5995
- })),
5996
- { name: "None", value: "none" }
5997
- ],
5998
- required: true,
5999
- loop: false
6000
- });
6001
- const selectedTechnologies = options.technologies.filter((p) => selectedIds.includes(p.id));
6002
- const agent = await esm_default6({
5851
+ const selectedTechnologies = options.technologies;
5852
+ const agent = await esm_default5({
6003
5853
  message: "AI coding tool:",
6004
5854
  choices: options.agents,
6005
5855
  loop: false
6006
5856
  });
6007
5857
  let agentTeams = false;
6008
5858
  if (factoryAvailable && agent === "claude-code") {
6009
- const brainstormer = await esm_default6({
5859
+ const brainstormer = await esm_default5({
6010
5860
  message: "Brainstorming mode:",
6011
5861
  default: "solo",
6012
5862
  choices: [
@@ -6020,7 +5870,7 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
6020
5870
  const mcpConfig = buildMCPConfiguration(selectedTechnologies, options.baseMcpServers, options.mcpServers);
6021
5871
  let azureDevOpsOrg = "";
6022
5872
  if (mcpConfig["azure-devops"]) {
6023
- const org = await esm_default4({
5873
+ const org = await esm_default3({
6024
5874
  message: "Azure DevOps org (leave empty to skip):"
6025
5875
  });
6026
5876
  azureDevOpsOrg = org.trim();
@@ -6036,13 +5886,13 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
6036
5886
  }
6037
5887
  }
6038
5888
  if (mcpConfig["sap_mcp_server"]) {
6039
- const sapUser = (await esm_default4({
5889
+ const sapUser = (await esm_default3({
6040
5890
  message: "SAP MCP (ABAP F4P) username (leave empty to skip):"
6041
5891
  })).trim();
6042
5892
  if (sapUser === "") {
6043
5893
  delete mcpConfig["sap_mcp_server"];
6044
5894
  } else {
6045
- const sapPassword = await esm_default5({
5895
+ const sapPassword = await esm_default4({
6046
5896
  message: "SAP MCP (ABAP F4P) password:",
6047
5897
  mask: "*"
6048
5898
  });
@@ -6056,9 +5906,9 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
6056
5906
  }
6057
5907
  }
6058
5908
  }
6059
- const projectInput = await esm_default4({
5909
+ const projectInput = await esm_default3({
6060
5910
  message: "Project directory:",
6061
- default: (0, import_path17.resolve)(process.cwd())
5911
+ default: (0, import_path18.resolve)(process.cwd())
6062
5912
  });
6063
5913
  const isAbapSelected = selectedTechnologies.some((t) => t.domains.includes("ABAP"));
6064
5914
  const installAbapHooks = abapHooksAvailable && agent === "claude-code" && isAbapSelected;
@@ -6066,7 +5916,7 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
6066
5916
  technologies: selectedTechnologies,
6067
5917
  agent,
6068
5918
  azureDevOpsOrg,
6069
- projectPath: (0, import_path17.resolve)(projectInput),
5919
+ projectPath: (0, import_path18.resolve)(projectInput),
6070
5920
  baseMcpServers: options.baseMcpServers,
6071
5921
  mcpConfig,
6072
5922
  releaseVersion,
@@ -6076,15 +5926,15 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
6076
5926
  };
6077
5927
  }
6078
5928
  async function previewAndConfirm(config, options) {
6079
- const technologyNames = config.technologies.length > 0 ? config.technologies.map((p) => p.name.replace(/ Developer$/, "")).join(", ") : "None";
5929
+ const technologyNames = config.technologies.map((p) => p.name.replace(/ Developer$/, "")).join(", ");
6080
5930
  const agentDisplay = options.agents.find((a) => a.value === config.agent)?.name ?? config.agent;
6081
5931
  const target = getAgentTarget(config.agent);
6082
5932
  const instructionFile = target.instructions;
6083
5933
  const mcpConfigFile = target.mcpConfig;
6084
5934
  const serverEntries = Object.entries(config.mcpConfig);
6085
- const instructionFilePath = (0, import_path17.join)(config.projectPath, instructionFile);
6086
- const mcpConfigFilePath = (0, import_path17.join)(config.projectPath, mcpConfigFile);
6087
- const gitignorePath = (0, import_path17.join)(config.projectPath, ".gitignore");
5935
+ const instructionFilePath = (0, import_path18.join)(config.projectPath, instructionFile);
5936
+ const mcpConfigFilePath = (0, import_path18.join)(config.projectPath, mcpConfigFile);
5937
+ const gitignorePath = (0, import_path18.join)(config.projectPath, ".gitignore");
6088
5938
  const instructionMode = detectMarkerFileMode(instructionFilePath, "<!-- one-shot-installer:start -->");
6089
5939
  const mcpMode = detectMCPFileMode(mcpConfigFilePath);
6090
5940
  const gitignoreMode = detectMarkerFileMode(gitignorePath, "# one-shot-installer:start");
@@ -6114,11 +5964,11 @@ async function previewAndConfirm(config, options) {
6114
5964
  console.log(` ${mcpConfigFile.padEnd(domainColWidth + 14)}${mcpMode}`);
6115
5965
  console.log(` ${".gitignore".padEnd(domainColWidth + 14)}${gitignoreMode}`);
6116
5966
  if (config.installFactory || config.installAbapHooks) {
6117
- const claudeDir = (0, import_path17.join)(config.projectPath, ".claude");
6118
- const claudeMode = (0, import_fs17.existsSync)(claudeDir) ? yellow2("merge") : green2("create");
5967
+ const claudeDir = (0, import_path18.join)(config.projectPath, ".claude");
5968
+ const claudeMode = (0, import_fs18.existsSync)(claudeDir) ? yellow2("merge") : green2("create");
6119
5969
  console.log(` ${".claude/".padEnd(domainColWidth + 14)}${claudeMode}`);
6120
- const settingsPath = (0, import_path17.join)(config.projectPath, ".claude", "settings.json");
6121
- const settingsMode = (0, import_fs17.existsSync)(settingsPath) ? yellow2("merge") : green2("create");
5970
+ const settingsPath = (0, import_path18.join)(config.projectPath, ".claude", "settings.json");
5971
+ const settingsMode = (0, import_fs18.existsSync)(settingsPath) ? yellow2("merge") : green2("create");
6122
5972
  console.log(` ${".claude/settings.json".padEnd(domainColWidth + 14)}${settingsMode}`);
6123
5973
  }
6124
5974
  if (serverEntries.length > 0) {
@@ -6131,7 +5981,7 @@ async function previewAndConfirm(config, options) {
6131
5981
  }
6132
5982
  }
6133
5983
  console.log("\n" + "\u2500".repeat(48));
6134
- return esm_default3({ message: "Proceed?", default: true });
5984
+ return esm_default2({ message: "Proceed?", default: true });
6135
5985
  }
6136
5986
  function printSummary2(result, config) {
6137
5987
  const failed = result.entries.filter((e) => e.result.status === "failed");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dlw-machine-setup",
3
- "version": "0.11.0",
3
+ "version": "0.12.0-canary.1",
4
4
  "description": "One-shot installer for The Machine toolchain",
5
5
  "bin": {
6
6
  "dlw-machine-setup": "bin/installer.js"
@@ -16,7 +16,8 @@
16
16
  "license": "UNLICENSED",
17
17
  "publishConfig": {
18
18
  "access": "public",
19
- "registry": "https://registry.npmjs.org"
19
+ "registry": "https://registry.npmjs.org",
20
+ "tag": "canary"
20
21
  },
21
22
  "engines": {
22
23
  "node": ">=18.0.0"