maxsimcli 4.7.1 → 4.8.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/assets/CHANGELOG.md +7 -0
- package/dist/install.cjs +40 -338
- package/dist/install.cjs.map +1 -1
- package/dist/mcp-server.cjs +5192 -2246
- package/dist/mcp-server.cjs.map +1 -1
- package/package.json +4 -1
package/dist/assets/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [4.7.1](https://github.com/maystudios/maxsimcli/compare/v4.7.0...v4.7.1) (2026-03-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **infra:** remove dashboard package and backend server [INFRA-01, INFRA-02, INFRA-03] ([eb25801](https://github.com/maystudios/maxsimcli/commit/eb25801a251d9b346e0fa3e38d4566efbff1c701))
|
|
7
|
+
|
|
1
8
|
# [4.7.0](https://github.com/maystudios/maxsimcli/compare/v4.6.0...v4.7.0) (2026-03-09)
|
|
2
9
|
|
|
3
10
|
|
package/dist/install.cjs
CHANGED
|
@@ -32,10 +32,10 @@ let node_fs = require("node:fs");
|
|
|
32
32
|
node_fs = __toESM(node_fs);
|
|
33
33
|
let node_path = require("node:path");
|
|
34
34
|
node_path = __toESM(node_path);
|
|
35
|
-
let node_os = require("node:os");
|
|
36
|
-
node_os = __toESM(node_os);
|
|
37
35
|
let node_process = require("node:process");
|
|
38
36
|
node_process = __toESM(node_process);
|
|
37
|
+
let node_os = require("node:os");
|
|
38
|
+
node_os = __toESM(node_os);
|
|
39
39
|
let node_tty = require("node:tty");
|
|
40
40
|
node_tty = __toESM(node_tty);
|
|
41
41
|
let figlet = require("figlet");
|
|
@@ -5643,11 +5643,7 @@ function ora(options) {
|
|
|
5643
5643
|
|
|
5644
5644
|
//#endregion
|
|
5645
5645
|
//#region ../../node_modules/@inquirer/core/dist/lib/key.js
|
|
5646
|
-
const isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
|
|
5647
|
-
const isDownKey = (key, keybindings = []) => key.name === "down" || keybindings.includes("vim") && key.name === "j" || keybindings.includes("emacs") && key.ctrl && key.name === "n";
|
|
5648
|
-
const isBackspaceKey = (key) => key.name === "backspace";
|
|
5649
5646
|
const isTabKey = (key) => key.name === "tab";
|
|
5650
|
-
const isNumberKey = (key) => "1234567890".includes(key.name);
|
|
5651
5647
|
const isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
5652
5648
|
|
|
5653
5649
|
//#endregion
|
|
@@ -6164,23 +6160,6 @@ function usePrefix({ status = "idle", theme }) {
|
|
|
6164
6160
|
return typeof prefix === "string" ? prefix : prefix[status === "loading" ? "idle" : status] ?? prefix["idle"];
|
|
6165
6161
|
}
|
|
6166
6162
|
|
|
6167
|
-
//#endregion
|
|
6168
|
-
//#region ../../node_modules/@inquirer/core/dist/lib/use-memo.js
|
|
6169
|
-
function useMemo(fn, dependencies) {
|
|
6170
|
-
return withPointer((pointer) => {
|
|
6171
|
-
const prev = pointer.get();
|
|
6172
|
-
if (!prev || prev.dependencies.length !== dependencies.length || prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
|
|
6173
|
-
const value = fn();
|
|
6174
|
-
pointer.set({
|
|
6175
|
-
value,
|
|
6176
|
-
dependencies
|
|
6177
|
-
});
|
|
6178
|
-
return value;
|
|
6179
|
-
}
|
|
6180
|
-
return prev.value;
|
|
6181
|
-
});
|
|
6182
|
-
}
|
|
6183
|
-
|
|
6184
6163
|
//#endregion
|
|
6185
6164
|
//#region ../../node_modules/@inquirer/core/dist/lib/use-ref.js
|
|
6186
6165
|
function useRef(val) {
|
|
@@ -6548,90 +6527,6 @@ function readlineWidth() {
|
|
|
6548
6527
|
});
|
|
6549
6528
|
}
|
|
6550
6529
|
|
|
6551
|
-
//#endregion
|
|
6552
|
-
//#region ../../node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
|
|
6553
|
-
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
6554
|
-
const state = useRef({
|
|
6555
|
-
lastPointer: active,
|
|
6556
|
-
lastActive: void 0
|
|
6557
|
-
});
|
|
6558
|
-
const { lastPointer, lastActive } = state.current;
|
|
6559
|
-
const middle = Math.floor(pageSize / 2);
|
|
6560
|
-
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
6561
|
-
const defaultPointerPosition = renderedItems.slice(0, active).reduce((acc, item) => acc + item.length, 0);
|
|
6562
|
-
let pointer = defaultPointerPosition;
|
|
6563
|
-
if (renderedLength > pageSize) if (loop) {
|
|
6564
|
-
/**
|
|
6565
|
-
* Creates the next position for the pointer considering an infinitely
|
|
6566
|
-
* looping list of items to be rendered on the page.
|
|
6567
|
-
*
|
|
6568
|
-
* The goal is to progressively move the cursor to the middle position as the user move down, and then keep
|
|
6569
|
-
* the cursor there. When the user move up, maintain the cursor position.
|
|
6570
|
-
*/
|
|
6571
|
-
pointer = lastPointer;
|
|
6572
|
-
if (lastActive != null && lastActive < active && active - lastActive < pageSize) pointer = Math.min(middle, Math.abs(active - lastActive) === 1 ? Math.min(lastPointer + (renderedItems[lastActive]?.length ?? 0), Math.max(defaultPointerPosition, lastPointer)) : lastPointer + active - lastActive);
|
|
6573
|
-
} else {
|
|
6574
|
-
/**
|
|
6575
|
-
* Creates the next position for the pointer considering a finite list of
|
|
6576
|
-
* items to be rendered on a page.
|
|
6577
|
-
*
|
|
6578
|
-
* The goal is to keep the pointer in the middle of the page whenever possible, until
|
|
6579
|
-
* we reach the bounds of the list (top or bottom). In which case, the cursor moves progressively
|
|
6580
|
-
* to the bottom or top of the list.
|
|
6581
|
-
*/
|
|
6582
|
-
const spaceUnderActive = renderedItems.slice(active).reduce((acc, item) => acc + item.length, 0);
|
|
6583
|
-
pointer = spaceUnderActive < pageSize - middle ? pageSize - spaceUnderActive : Math.min(defaultPointerPosition, middle);
|
|
6584
|
-
}
|
|
6585
|
-
state.current.lastPointer = pointer;
|
|
6586
|
-
state.current.lastActive = active;
|
|
6587
|
-
return pointer;
|
|
6588
|
-
}
|
|
6589
|
-
function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
6590
|
-
const width = readlineWidth();
|
|
6591
|
-
const bound = (num) => (num % items.length + items.length) % items.length;
|
|
6592
|
-
const renderedItems = items.map((item, index) => {
|
|
6593
|
-
if (item == null) return [];
|
|
6594
|
-
return breakLines(renderItem({
|
|
6595
|
-
item,
|
|
6596
|
-
index,
|
|
6597
|
-
isActive: index === active
|
|
6598
|
-
}), width).split("\n");
|
|
6599
|
-
});
|
|
6600
|
-
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
6601
|
-
const renderItemAtIndex = (index) => renderedItems[index] ?? [];
|
|
6602
|
-
const pointer = usePointerPosition({
|
|
6603
|
-
active,
|
|
6604
|
-
renderedItems,
|
|
6605
|
-
pageSize,
|
|
6606
|
-
loop
|
|
6607
|
-
});
|
|
6608
|
-
const activeItem = renderItemAtIndex(active).slice(0, pageSize);
|
|
6609
|
-
const activeItemPosition = pointer + activeItem.length <= pageSize ? pointer : pageSize - activeItem.length;
|
|
6610
|
-
const pageBuffer = Array.from({ length: pageSize });
|
|
6611
|
-
pageBuffer.splice(activeItemPosition, activeItem.length, ...activeItem);
|
|
6612
|
-
const itemVisited = new Set([active]);
|
|
6613
|
-
let bufferPointer = activeItemPosition + activeItem.length;
|
|
6614
|
-
let itemPointer = bound(active + 1);
|
|
6615
|
-
while (bufferPointer < pageSize && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer > active)) {
|
|
6616
|
-
const linesToAdd = renderItemAtIndex(itemPointer).slice(0, pageSize - bufferPointer);
|
|
6617
|
-
pageBuffer.splice(bufferPointer, linesToAdd.length, ...linesToAdd);
|
|
6618
|
-
itemVisited.add(itemPointer);
|
|
6619
|
-
bufferPointer += linesToAdd.length;
|
|
6620
|
-
itemPointer = bound(itemPointer + 1);
|
|
6621
|
-
}
|
|
6622
|
-
bufferPointer = activeItemPosition - 1;
|
|
6623
|
-
itemPointer = bound(active - 1);
|
|
6624
|
-
while (bufferPointer >= 0 && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer < active)) {
|
|
6625
|
-
const lines = renderItemAtIndex(itemPointer);
|
|
6626
|
-
const linesToAdd = lines.slice(Math.max(0, lines.length - bufferPointer - 1));
|
|
6627
|
-
pageBuffer.splice(bufferPointer - linesToAdd.length + 1, linesToAdd.length, ...linesToAdd);
|
|
6628
|
-
itemVisited.add(itemPointer);
|
|
6629
|
-
bufferPointer -= linesToAdd.length;
|
|
6630
|
-
itemPointer = bound(itemPointer - 1);
|
|
6631
|
-
}
|
|
6632
|
-
return pageBuffer.filter((line) => typeof line === "string").join("\n");
|
|
6633
|
-
}
|
|
6634
|
-
|
|
6635
6530
|
//#endregion
|
|
6636
6531
|
//#region ../../node_modules/mute-stream/lib/index.js
|
|
6637
6532
|
var require_lib = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -7119,23 +7014,6 @@ function createPrompt(view) {
|
|
|
7119
7014
|
return prompt;
|
|
7120
7015
|
}
|
|
7121
7016
|
|
|
7122
|
-
//#endregion
|
|
7123
|
-
//#region ../../node_modules/@inquirer/core/dist/lib/Separator.js
|
|
7124
|
-
/**
|
|
7125
|
-
* Separator object
|
|
7126
|
-
* Used to space/separate choices group
|
|
7127
|
-
*/
|
|
7128
|
-
var Separator = class {
|
|
7129
|
-
separator = (0, node_util.styleText)("dim", Array.from({ length: 15 }).join(figures.line));
|
|
7130
|
-
type = "separator";
|
|
7131
|
-
constructor(separator) {
|
|
7132
|
-
if (separator) this.separator = separator;
|
|
7133
|
-
}
|
|
7134
|
-
static isSeparator(choice) {
|
|
7135
|
-
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
7136
|
-
}
|
|
7137
|
-
};
|
|
7138
|
-
|
|
7139
7017
|
//#endregion
|
|
7140
7018
|
//#region ../../node_modules/@inquirer/confirm/dist/index.js
|
|
7141
7019
|
function getBooleanValue(value, defaultValue) {
|
|
@@ -7147,7 +7025,7 @@ function getBooleanValue(value, defaultValue) {
|
|
|
7147
7025
|
function boolToString(value) {
|
|
7148
7026
|
return value ? "Yes" : "No";
|
|
7149
7027
|
}
|
|
7150
|
-
var dist_default
|
|
7028
|
+
var dist_default = createPrompt((config, done) => {
|
|
7151
7029
|
const { transformer = boolToString } = config;
|
|
7152
7030
|
const [status, setStatus] = useState("idle");
|
|
7153
7031
|
const [value, setValue] = useState("");
|
|
@@ -7177,162 +7055,6 @@ var dist_default$1 = createPrompt((config, done) => {
|
|
|
7177
7055
|
return `${prefix} ${theme.style.message(config.message, status)}${defaultValue} ${formattedValue}`;
|
|
7178
7056
|
});
|
|
7179
7057
|
|
|
7180
|
-
//#endregion
|
|
7181
|
-
//#region ../../node_modules/@inquirer/select/dist/index.js
|
|
7182
|
-
const selectTheme = {
|
|
7183
|
-
icon: { cursor: figures.pointer },
|
|
7184
|
-
style: {
|
|
7185
|
-
disabled: (text) => (0, node_util.styleText)("dim", text),
|
|
7186
|
-
description: (text) => (0, node_util.styleText)("cyan", text),
|
|
7187
|
-
keysHelpTip: (keys) => keys.map(([key, action]) => `${(0, node_util.styleText)("bold", key)} ${(0, node_util.styleText)("dim", action)}`).join((0, node_util.styleText)("dim", " • "))
|
|
7188
|
-
},
|
|
7189
|
-
i18n: { disabledError: "This option is disabled and cannot be selected." },
|
|
7190
|
-
indexMode: "hidden",
|
|
7191
|
-
keybindings: []
|
|
7192
|
-
};
|
|
7193
|
-
function isSelectable(item) {
|
|
7194
|
-
return !Separator.isSeparator(item) && !item.disabled;
|
|
7195
|
-
}
|
|
7196
|
-
function isNavigable(item) {
|
|
7197
|
-
return !Separator.isSeparator(item);
|
|
7198
|
-
}
|
|
7199
|
-
function normalizeChoices(choices) {
|
|
7200
|
-
return choices.map((choice) => {
|
|
7201
|
-
if (Separator.isSeparator(choice)) return choice;
|
|
7202
|
-
if (typeof choice !== "object" || choice === null || !("value" in choice)) {
|
|
7203
|
-
const name = String(choice);
|
|
7204
|
-
return {
|
|
7205
|
-
value: choice,
|
|
7206
|
-
name,
|
|
7207
|
-
short: name,
|
|
7208
|
-
disabled: false
|
|
7209
|
-
};
|
|
7210
|
-
}
|
|
7211
|
-
const name = choice.name ?? String(choice.value);
|
|
7212
|
-
const normalizedChoice = {
|
|
7213
|
-
value: choice.value,
|
|
7214
|
-
name,
|
|
7215
|
-
short: choice.short ?? name,
|
|
7216
|
-
disabled: choice.disabled ?? false
|
|
7217
|
-
};
|
|
7218
|
-
if (choice.description) normalizedChoice.description = choice.description;
|
|
7219
|
-
return normalizedChoice;
|
|
7220
|
-
});
|
|
7221
|
-
}
|
|
7222
|
-
var dist_default = createPrompt((config, done) => {
|
|
7223
|
-
const { loop = true, pageSize = 7 } = config;
|
|
7224
|
-
const theme = makeTheme(selectTheme, config.theme);
|
|
7225
|
-
const { keybindings } = theme;
|
|
7226
|
-
const [status, setStatus] = useState("idle");
|
|
7227
|
-
const prefix = usePrefix({
|
|
7228
|
-
status,
|
|
7229
|
-
theme
|
|
7230
|
-
});
|
|
7231
|
-
const searchTimeoutRef = useRef();
|
|
7232
|
-
const searchEnabled = !keybindings.includes("vim");
|
|
7233
|
-
const items = useMemo(() => normalizeChoices(config.choices), [config.choices]);
|
|
7234
|
-
const bounds = useMemo(() => {
|
|
7235
|
-
const first = items.findIndex(isNavigable);
|
|
7236
|
-
const last = items.findLastIndex(isNavigable);
|
|
7237
|
-
if (first === -1) throw new ValidationError("[select prompt] No selectable choices. All choices are disabled.");
|
|
7238
|
-
return {
|
|
7239
|
-
first,
|
|
7240
|
-
last
|
|
7241
|
-
};
|
|
7242
|
-
}, [items]);
|
|
7243
|
-
const defaultItemIndex = useMemo(() => {
|
|
7244
|
-
if (!("default" in config)) return -1;
|
|
7245
|
-
return items.findIndex((item) => isSelectable(item) && item.value === config.default);
|
|
7246
|
-
}, [config.default, items]);
|
|
7247
|
-
const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
|
|
7248
|
-
const selectedChoice = items[active];
|
|
7249
|
-
const [errorMsg, setError] = useState();
|
|
7250
|
-
useKeypress((key, rl) => {
|
|
7251
|
-
clearTimeout(searchTimeoutRef.current);
|
|
7252
|
-
if (errorMsg) setError(void 0);
|
|
7253
|
-
if (isEnterKey(key)) if (selectedChoice.disabled) setError(theme.i18n.disabledError);
|
|
7254
|
-
else {
|
|
7255
|
-
setStatus("done");
|
|
7256
|
-
done(selectedChoice.value);
|
|
7257
|
-
}
|
|
7258
|
-
else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
|
|
7259
|
-
rl.clearLine(0);
|
|
7260
|
-
if (loop || isUpKey(key, keybindings) && active !== bounds.first || isDownKey(key, keybindings) && active !== bounds.last) {
|
|
7261
|
-
const offset = isUpKey(key, keybindings) ? -1 : 1;
|
|
7262
|
-
let next = active;
|
|
7263
|
-
do
|
|
7264
|
-
next = (next + offset + items.length) % items.length;
|
|
7265
|
-
while (!isNavigable(items[next]));
|
|
7266
|
-
setActive(next);
|
|
7267
|
-
}
|
|
7268
|
-
} else if (isNumberKey(key) && !Number.isNaN(Number(rl.line))) {
|
|
7269
|
-
const selectedIndex = Number(rl.line) - 1;
|
|
7270
|
-
let selectableIndex = -1;
|
|
7271
|
-
const position = items.findIndex((item) => {
|
|
7272
|
-
if (Separator.isSeparator(item)) return false;
|
|
7273
|
-
selectableIndex++;
|
|
7274
|
-
return selectableIndex === selectedIndex;
|
|
7275
|
-
});
|
|
7276
|
-
const item = items[position];
|
|
7277
|
-
if (item != null && isSelectable(item)) setActive(position);
|
|
7278
|
-
searchTimeoutRef.current = setTimeout(() => {
|
|
7279
|
-
rl.clearLine(0);
|
|
7280
|
-
}, 700);
|
|
7281
|
-
} else if (isBackspaceKey(key)) rl.clearLine(0);
|
|
7282
|
-
else if (searchEnabled) {
|
|
7283
|
-
const searchTerm = rl.line.toLowerCase();
|
|
7284
|
-
const matchIndex = items.findIndex((item) => {
|
|
7285
|
-
if (Separator.isSeparator(item) || !isSelectable(item)) return false;
|
|
7286
|
-
return item.name.toLowerCase().startsWith(searchTerm);
|
|
7287
|
-
});
|
|
7288
|
-
if (matchIndex !== -1) setActive(matchIndex);
|
|
7289
|
-
searchTimeoutRef.current = setTimeout(() => {
|
|
7290
|
-
rl.clearLine(0);
|
|
7291
|
-
}, 700);
|
|
7292
|
-
}
|
|
7293
|
-
});
|
|
7294
|
-
useEffect(() => () => {
|
|
7295
|
-
clearTimeout(searchTimeoutRef.current);
|
|
7296
|
-
}, []);
|
|
7297
|
-
const message = theme.style.message(config.message, status);
|
|
7298
|
-
const helpLine = theme.style.keysHelpTip([["↑↓", "navigate"], ["⏎", "select"]]);
|
|
7299
|
-
let separatorCount = 0;
|
|
7300
|
-
const page = usePagination({
|
|
7301
|
-
items,
|
|
7302
|
-
active,
|
|
7303
|
-
renderItem({ item, isActive, index }) {
|
|
7304
|
-
if (Separator.isSeparator(item)) {
|
|
7305
|
-
separatorCount++;
|
|
7306
|
-
return ` ${item.separator}`;
|
|
7307
|
-
}
|
|
7308
|
-
const cursor = isActive ? theme.icon.cursor : " ";
|
|
7309
|
-
const indexLabel = theme.indexMode === "number" ? `${index + 1 - separatorCount}. ` : "";
|
|
7310
|
-
if (item.disabled) {
|
|
7311
|
-
const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
|
|
7312
|
-
const disabledCursor = isActive ? theme.icon.cursor : "-";
|
|
7313
|
-
return theme.style.disabled(`${disabledCursor} ${indexLabel}${item.name} ${disabledLabel}`);
|
|
7314
|
-
}
|
|
7315
|
-
return (isActive ? theme.style.highlight : (x) => x)(`${cursor} ${indexLabel}${item.name}`);
|
|
7316
|
-
},
|
|
7317
|
-
pageSize,
|
|
7318
|
-
loop
|
|
7319
|
-
});
|
|
7320
|
-
if (status === "done") return [
|
|
7321
|
-
prefix,
|
|
7322
|
-
message,
|
|
7323
|
-
theme.style.answer(selectedChoice.short)
|
|
7324
|
-
].filter(Boolean).join(" ");
|
|
7325
|
-
const { description } = selectedChoice;
|
|
7326
|
-
return `${[
|
|
7327
|
-
[prefix, message].filter(Boolean).join(" "),
|
|
7328
|
-
page,
|
|
7329
|
-
" ",
|
|
7330
|
-
description ? theme.style.description(description) : "",
|
|
7331
|
-
errorMsg ? theme.style.error(errorMsg) : "",
|
|
7332
|
-
helpLine
|
|
7333
|
-
].filter(Boolean).join("\n").trimEnd()}${cursorHide}`;
|
|
7334
|
-
});
|
|
7335
|
-
|
|
7336
7058
|
//#endregion
|
|
7337
7059
|
//#region ../../node_modules/minimist/index.js
|
|
7338
7060
|
var require_minimist = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -7573,6 +7295,10 @@ const builtInSkills = [
|
|
|
7573
7295
|
/**
|
|
7574
7296
|
* Get the global config directory for Claude Code.
|
|
7575
7297
|
* Priority: explicitDir > CLAUDE_CONFIG_DIR env > ~/.claude
|
|
7298
|
+
*
|
|
7299
|
+
* @deprecated Global install is no longer supported in v5.0+.
|
|
7300
|
+
* Kept for uninstall.ts (cleaning up old global installs) and adapters.ts.
|
|
7301
|
+
* TODO: Remove when global install cleanup path is no longer needed.
|
|
7576
7302
|
*/
|
|
7577
7303
|
function getGlobalDir(explicitDir = null) {
|
|
7578
7304
|
if (explicitDir) return expandTilde(explicitDir);
|
|
@@ -7582,6 +7308,9 @@ function getGlobalDir(explicitDir = null) {
|
|
|
7582
7308
|
/**
|
|
7583
7309
|
* Get the config directory path relative to home for hook templating.
|
|
7584
7310
|
* Used for path.join(homeDir, '<configDir>', ...) replacement in hooks.
|
|
7311
|
+
*
|
|
7312
|
+
* @deprecated Global install is no longer supported in v5.0+.
|
|
7313
|
+
* TODO: Remove when hooks.ts no longer needs global/local distinction.
|
|
7585
7314
|
*/
|
|
7586
7315
|
function getConfigDirFromHome(_isGlobal) {
|
|
7587
7316
|
return "'.claude'";
|
|
@@ -7835,7 +7564,7 @@ async function handleStatusline(settings, isInteractive, forceStatusline) {
|
|
|
7835
7564
|
console.log(" • Current task (from todo list)");
|
|
7836
7565
|
console.log(" • Context window usage (color-coded)");
|
|
7837
7566
|
console.log();
|
|
7838
|
-
return await dist_default
|
|
7567
|
+
return await dist_default({
|
|
7839
7568
|
message: "Replace with MAXSIM statusline?",
|
|
7840
7569
|
default: false
|
|
7841
7570
|
});
|
|
@@ -8158,7 +7887,6 @@ function uninstall(isGlobal, explicitConfigDir = null) {
|
|
|
8158
7887
|
var import_lib = /* @__PURE__ */ __toESM(require_lib$1());
|
|
8159
7888
|
const argv = (0, import_minimist.default)(process.argv.slice(2), {
|
|
8160
7889
|
boolean: [
|
|
8161
|
-
"global",
|
|
8162
7890
|
"local",
|
|
8163
7891
|
"claude",
|
|
8164
7892
|
"uninstall",
|
|
@@ -8169,14 +7897,12 @@ const argv = (0, import_minimist.default)(process.argv.slice(2), {
|
|
|
8169
7897
|
],
|
|
8170
7898
|
string: ["config-dir"],
|
|
8171
7899
|
alias: {
|
|
8172
|
-
g: "global",
|
|
8173
7900
|
l: "local",
|
|
8174
7901
|
u: "uninstall",
|
|
8175
7902
|
h: "help",
|
|
8176
7903
|
c: "config-dir"
|
|
8177
7904
|
}
|
|
8178
7905
|
});
|
|
8179
|
-
const hasGlobal = !!argv["global"];
|
|
8180
7906
|
const hasLocal = !!argv["local"];
|
|
8181
7907
|
const hasUninstall = !!argv["uninstall"];
|
|
8182
7908
|
const banner = "\n" + chalk.cyan(figlet.default.textSync("MAXSIM", { font: "ANSI Shadow" }).split("\n").map((line) => " " + line).join("\n")) + "\n\n MAXSIM " + chalk.dim("v" + pkg.version) + "\n A meta-prompting, context engineering and spec-driven\n development system for Claude Code.\n";
|
|
@@ -8194,29 +7920,35 @@ for (const flag of [
|
|
|
8194
7920
|
console.error(`Error: The --${flag} flag is no longer supported. MAXSIM v2.0 is Claude Code only.`);
|
|
8195
7921
|
process.exit(1);
|
|
8196
7922
|
}
|
|
7923
|
+
if (argv["global"] || argv["g"]) {
|
|
7924
|
+
console.error(chalk.red("Error: Global install is no longer supported."));
|
|
7925
|
+
console.error("MAXSIM v5.0+ installs locally to .claude/ in your project directory.");
|
|
7926
|
+
console.error("Run: npx maxsimcli --local");
|
|
7927
|
+
process.exit(1);
|
|
7928
|
+
}
|
|
8197
7929
|
if (hasVersion) {
|
|
8198
7930
|
console.log(pkg.version);
|
|
8199
7931
|
process.exit(0);
|
|
8200
7932
|
}
|
|
8201
7933
|
console.log(banner);
|
|
8202
7934
|
if (hasHelp) {
|
|
8203
|
-
console.log(` ${chalk.yellow("Usage:")} npx maxsimcli [options]\n\n ${chalk.yellow("Options:")}\n ${chalk.cyan("-
|
|
7935
|
+
console.log(` ${chalk.yellow("Usage:")} npx maxsimcli [options]\n\n ${chalk.yellow("Options:")}\n ${chalk.cyan("-l, --local")} Install to current project directory (default)\n ${chalk.cyan("-u, --uninstall")} Uninstall MAXSIM (remove all MAXSIM files)\n ${chalk.cyan("-c, --config-dir <path>")} Specify custom local directory name\n ${chalk.cyan("-h, --help")} Show this help message\n ${chalk.cyan("--force-statusline")} Replace existing statusline config\n\n ${chalk.yellow("Examples:")}\n ${chalk.dim("# Install to current project")}\n npx maxsimcli\n\n ${chalk.dim("# Explicit local install")}\n npx maxsimcli --local\n\n ${chalk.dim("# Uninstall MAXSIM")}\n npx maxsimcli --local --uninstall\n\n ${chalk.yellow("Notes:")}\n MAXSIM installs to .claude/ in your project directory.\n The --config-dir option specifies a custom directory name (relative to CWD).\n`);
|
|
8204
7936
|
process.exit(0);
|
|
8205
7937
|
}
|
|
8206
|
-
async function install(
|
|
7938
|
+
async function install() {
|
|
8207
7939
|
const dirName = getDirName();
|
|
8208
7940
|
const src = templatesRoot;
|
|
8209
|
-
const targetDir =
|
|
8210
|
-
const locationLabel =
|
|
8211
|
-
const pathPrefix =
|
|
7941
|
+
const targetDir = explicitConfigDir ? node_path.resolve(process.cwd(), explicitConfigDir) : node_path.join(process.cwd(), dirName);
|
|
7942
|
+
const locationLabel = targetDir.replace(process.cwd(), ".");
|
|
7943
|
+
const pathPrefix = `./${dirName}/`;
|
|
8212
7944
|
console.log(` Installing for ${chalk.cyan("Claude Code")} to ${chalk.cyan(locationLabel)}\n`);
|
|
8213
7945
|
const failures = [];
|
|
8214
7946
|
const existingManifest = readManifest(targetDir);
|
|
8215
7947
|
const isAlreadyCurrent = existingManifest !== null && existingManifest.version === pkg.version;
|
|
8216
7948
|
if (existingManifest !== null) {
|
|
8217
7949
|
const { complete, missing } = verifyInstallComplete(targetDir, existingManifest);
|
|
8218
|
-
if (!complete) console.log(` ${chalk.yellow("!")} Previous install (v${existingManifest.version}) is incomplete
|
|
8219
|
-
else if (isAlreadyCurrent) console.log(` ${chalk.dim(`Version ${pkg.version} already installed
|
|
7950
|
+
if (!complete) console.log(` ${chalk.yellow("!")} Previous install (v${existingManifest.version}) is incomplete -- ${missing.length} missing file(s). Re-installing.`);
|
|
7951
|
+
else if (isAlreadyCurrent) console.log(` ${chalk.dim(`Version ${pkg.version} already installed -- upgrading in place`)}`);
|
|
8220
7952
|
}
|
|
8221
7953
|
saveLocalPatches(targetDir);
|
|
8222
7954
|
cleanupOrphanedFiles(targetDir);
|
|
@@ -8356,7 +8088,7 @@ async function install(isGlobal) {
|
|
|
8356
8088
|
node_fs.copyFileSync(toolSrc, toolDest);
|
|
8357
8089
|
console.log(` ${chalk.green("✓")} Installed maxsim-tools.cjs`);
|
|
8358
8090
|
} else {
|
|
8359
|
-
console.warn(` ${chalk.yellow("!")} cli.cjs not found at ${toolSrc}
|
|
8091
|
+
console.warn(` ${chalk.yellow("!")} cli.cjs not found at ${toolSrc} -- maxsim-tools.cjs not installed`);
|
|
8360
8092
|
failures.push("maxsim-tools.cjs");
|
|
8361
8093
|
}
|
|
8362
8094
|
const mcpSrc = node_path.resolve(__dirname, "mcp-server.cjs");
|
|
@@ -8365,9 +8097,9 @@ async function install(isGlobal) {
|
|
|
8365
8097
|
node_fs.mkdirSync(binDir, { recursive: true });
|
|
8366
8098
|
node_fs.copyFileSync(mcpSrc, mcpDest);
|
|
8367
8099
|
console.log(` ${chalk.green("✓")} Installed mcp-server.cjs`);
|
|
8368
|
-
} else console.warn(` ${chalk.yellow("!")} mcp-server.cjs not found
|
|
8369
|
-
installHookFiles(targetDir,
|
|
8370
|
-
const mcpJsonPath =
|
|
8100
|
+
} else console.warn(` ${chalk.yellow("!")} mcp-server.cjs not found -- MCP server not installed`);
|
|
8101
|
+
installHookFiles(targetDir, false, failures);
|
|
8102
|
+
const mcpJsonPath = node_path.join(process.cwd(), ".mcp.json");
|
|
8371
8103
|
let mcpConfig = {};
|
|
8372
8104
|
let skipMcpConfig = false;
|
|
8373
8105
|
if (node_fs.existsSync(mcpJsonPath)) {
|
|
@@ -8378,7 +8110,7 @@ async function install(isGlobal) {
|
|
|
8378
8110
|
console.warn(` ${chalk.yellow("!")} .mcp.json is corrupted (invalid JSON). Backup saved to .mcp.json.bak`);
|
|
8379
8111
|
let startFresh = true;
|
|
8380
8112
|
try {
|
|
8381
|
-
startFresh = await dist_default
|
|
8113
|
+
startFresh = await dist_default({
|
|
8382
8114
|
message: ".mcp.json is corrupted. Start with a fresh config? (No = abort MCP setup)",
|
|
8383
8115
|
default: true
|
|
8384
8116
|
});
|
|
@@ -8407,7 +8139,7 @@ async function install(isGlobal) {
|
|
|
8407
8139
|
writeManifest(targetDir);
|
|
8408
8140
|
console.log(` ${chalk.green("✓")} Wrote file manifest (${MANIFEST_NAME})`);
|
|
8409
8141
|
reportLocalPatches(targetDir);
|
|
8410
|
-
const { settingsPath, settings, statuslineCommand } = configureSettingsHooks(targetDir,
|
|
8142
|
+
const { settingsPath, settings, statuslineCommand } = configureSettingsHooks(targetDir, false);
|
|
8411
8143
|
return {
|
|
8412
8144
|
settingsPath,
|
|
8413
8145
|
settings,
|
|
@@ -8415,26 +8147,6 @@ async function install(isGlobal) {
|
|
|
8415
8147
|
};
|
|
8416
8148
|
}
|
|
8417
8149
|
/**
|
|
8418
|
-
* Prompt for install location
|
|
8419
|
-
*/
|
|
8420
|
-
async function promptLocation() {
|
|
8421
|
-
if (!process.stdin.isTTY) {
|
|
8422
|
-
console.log(chalk.yellow("Non-interactive terminal detected, defaulting to global install") + "\n");
|
|
8423
|
-
return true;
|
|
8424
|
-
}
|
|
8425
|
-
const globalPath = getGlobalDir(explicitConfigDir).replace(node_os.homedir(), "~");
|
|
8426
|
-
return await dist_default({
|
|
8427
|
-
message: "Where would you like to install?",
|
|
8428
|
-
choices: [{
|
|
8429
|
-
name: "Global " + chalk.dim(`(${globalPath})`) + " — available in all projects",
|
|
8430
|
-
value: "global"
|
|
8431
|
-
}, {
|
|
8432
|
-
name: "Local " + chalk.dim("(./.claude)") + " — this project only",
|
|
8433
|
-
value: "local"
|
|
8434
|
-
}]
|
|
8435
|
-
}) === "global";
|
|
8436
|
-
}
|
|
8437
|
-
/**
|
|
8438
8150
|
* Prompt whether to enable Agent Teams (experimental feature)
|
|
8439
8151
|
*/
|
|
8440
8152
|
async function promptAgentTeams() {
|
|
@@ -8443,16 +8155,16 @@ async function promptAgentTeams() {
|
|
|
8443
8155
|
console.log(chalk.dim(" Coordinate multiple Claude Code instances working in parallel."));
|
|
8444
8156
|
console.log(chalk.dim(" Enables CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS in settings.json."));
|
|
8445
8157
|
console.log();
|
|
8446
|
-
return dist_default
|
|
8158
|
+
return dist_default({
|
|
8447
8159
|
message: "Enable Agent Teams?",
|
|
8448
8160
|
default: false
|
|
8449
8161
|
});
|
|
8450
8162
|
}
|
|
8451
8163
|
/**
|
|
8452
|
-
* Install MAXSIM for Claude Code
|
|
8164
|
+
* Install MAXSIM for Claude Code (always local)
|
|
8453
8165
|
*/
|
|
8454
|
-
async function installForClaude(
|
|
8455
|
-
const result = await install(
|
|
8166
|
+
async function installForClaude(isInteractive) {
|
|
8167
|
+
const result = await install();
|
|
8456
8168
|
let shouldInstallStatusline = false;
|
|
8457
8169
|
if (result.settings) shouldInstallStatusline = await handleStatusline(result.settings, isInteractive, forceStatusline);
|
|
8458
8170
|
let enableAgentTeams = false;
|
|
@@ -8462,7 +8174,7 @@ async function installForClaude(isGlobal, isInteractive) {
|
|
|
8462
8174
|
env["CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS"] = "1";
|
|
8463
8175
|
result.settings.env = env;
|
|
8464
8176
|
}
|
|
8465
|
-
finishInstall(result.settingsPath, result.settings, result.statuslineCommand, shouldInstallStatusline,
|
|
8177
|
+
finishInstall(result.settingsPath, result.settings, result.statuslineCommand, shouldInstallStatusline, false);
|
|
8466
8178
|
}
|
|
8467
8179
|
const subcommand = argv._[0];
|
|
8468
8180
|
(async () => {
|
|
@@ -8487,23 +8199,13 @@ const subcommand = argv._[0];
|
|
|
8487
8199
|
}
|
|
8488
8200
|
return;
|
|
8489
8201
|
}
|
|
8490
|
-
if (
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
} else if (explicitConfigDir && hasLocal) {
|
|
8494
|
-
console.error(chalk.yellow("Cannot use --config-dir with --local"));
|
|
8495
|
-
process.exit(1);
|
|
8496
|
-
} else if (hasUninstall) {
|
|
8497
|
-
if (!hasGlobal && !hasLocal) {
|
|
8498
|
-
console.error(chalk.yellow("--uninstall requires --global or --local"));
|
|
8202
|
+
if (hasUninstall) {
|
|
8203
|
+
if (!hasLocal) {
|
|
8204
|
+
console.error(chalk.yellow("--uninstall requires --local"));
|
|
8499
8205
|
process.exit(1);
|
|
8500
8206
|
}
|
|
8501
|
-
uninstall(
|
|
8502
|
-
} else
|
|
8503
|
-
else if (!process.stdin.isTTY) {
|
|
8504
|
-
console.log(chalk.yellow("Non-interactive terminal detected, defaulting to global install") + "\n");
|
|
8505
|
-
await installForClaude(true, false);
|
|
8506
|
-
} else await installForClaude(await promptLocation(), true);
|
|
8207
|
+
uninstall(false, explicitConfigDir);
|
|
8208
|
+
} else await installForClaude(process.stdin.isTTY === true);
|
|
8507
8209
|
})().catch((err) => {
|
|
8508
8210
|
if (err instanceof Error && err.message.includes("User force closed")) {
|
|
8509
8211
|
console.log("\n" + chalk.yellow("Installation cancelled") + "\n");
|