maxsimcli 4.7.1 → 4.9.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 +20 -0
- package/dist/assets/hooks/maxsim-check-update.cjs +38 -0
- package/dist/assets/hooks/maxsim-check-update.cjs.map +1 -1
- package/dist/assets/hooks/maxsim-statusline.cjs +116 -48
- package/dist/assets/hooks/maxsim-statusline.cjs.map +1 -1
- package/dist/assets/hooks/maxsim-sync-reminder.cjs +117 -0
- package/dist/assets/hooks/maxsim-sync-reminder.cjs.map +1 -0
- package/dist/assets/templates/agents/AGENTS.md +78 -106
- package/dist/assets/templates/agents/executor.md +101 -0
- package/dist/assets/templates/agents/planner.md +86 -0
- package/dist/assets/templates/agents/researcher.md +71 -0
- package/dist/assets/templates/agents/verifier.md +88 -0
- package/dist/assets/templates/commands/maxsim/debug.md +7 -7
- package/dist/assets/templates/commands/maxsim/execute.md +45 -0
- package/dist/assets/templates/commands/maxsim/go.md +29 -0
- package/dist/assets/templates/commands/maxsim/help.md +2 -2
- package/dist/assets/templates/commands/maxsim/init.md +52 -0
- package/dist/assets/templates/commands/maxsim/plan.md +50 -0
- package/dist/assets/templates/commands/maxsim/progress.md +4 -3
- package/dist/assets/templates/commands/maxsim/quick.md +6 -4
- package/dist/assets/templates/commands/maxsim/settings.md +4 -3
- package/dist/assets/templates/references/continuation-format.md +16 -16
- package/dist/assets/templates/references/model-profile-resolution.md +1 -1
- package/dist/assets/templates/references/model-profiles.md +12 -19
- package/dist/assets/templates/rules/conventions.md +51 -0
- package/dist/assets/templates/rules/verification-protocol.md +57 -0
- package/dist/assets/templates/skills/agent-system-map/SKILL.md +92 -0
- package/dist/assets/templates/skills/brainstorming/SKILL.md +48 -36
- package/dist/assets/templates/skills/code-review/SKILL.md +40 -61
- package/dist/assets/templates/skills/commit-conventions/SKILL.md +75 -0
- package/dist/assets/templates/skills/evidence-collection/SKILL.md +87 -0
- package/dist/assets/templates/skills/handoff-contract/SKILL.md +70 -0
- package/dist/assets/templates/skills/input-validation/SKILL.md +51 -0
- package/dist/assets/templates/skills/maxsim-batch/SKILL.md +41 -45
- package/dist/assets/templates/skills/maxsim-simplify/SKILL.md +37 -90
- package/dist/assets/templates/skills/memory-management/SKILL.md +32 -67
- package/dist/assets/templates/skills/research-methodology/SKILL.md +137 -0
- package/dist/assets/templates/skills/roadmap-writing/SKILL.md +40 -58
- package/dist/assets/templates/skills/sdd/SKILL.md +34 -69
- package/dist/assets/templates/skills/systematic-debugging/SKILL.md +20 -26
- package/dist/assets/templates/skills/tdd/SKILL.md +25 -33
- package/dist/assets/templates/skills/tool-priority-guide/SKILL.md +80 -0
- package/dist/assets/templates/skills/using-maxsim/SKILL.md +42 -73
- package/dist/assets/templates/skills/verification-before-completion/SKILL.md +12 -24
- package/dist/assets/templates/skills/verification-gates/SKILL.md +169 -0
- package/dist/assets/templates/templates/UAT.md +3 -3
- package/dist/assets/templates/templates/VALIDATION.md +1 -1
- package/dist/assets/templates/templates/context.md +4 -4
- package/dist/assets/templates/templates/debug-subagent-prompt.md +3 -3
- package/dist/assets/templates/templates/discovery.md +2 -2
- package/dist/assets/templates/templates/phase-prompt.md +2 -2
- package/dist/assets/templates/templates/planner-subagent-prompt.md +7 -7
- package/dist/assets/templates/templates/project.md +1 -1
- package/dist/assets/templates/templates/research.md +1 -1
- package/dist/assets/templates/templates/state.md +2 -2
- package/dist/assets/templates/templates/summary.md +41 -0
- package/dist/assets/templates/workflows/batch.md +5 -5
- package/dist/assets/templates/workflows/diagnose-issues.md +2 -2
- package/dist/assets/templates/workflows/discovery-phase.md +3 -3
- package/dist/assets/templates/workflows/discuss-phase.md +11 -11
- package/dist/assets/templates/workflows/execute-phase.md +205 -11
- package/dist/assets/templates/workflows/execute-plan.md +299 -34
- package/dist/assets/templates/workflows/execute.md +421 -0
- package/dist/assets/templates/workflows/go.md +250 -0
- package/dist/assets/templates/workflows/health.md +5 -5
- package/dist/assets/templates/workflows/help.md +165 -435
- package/dist/assets/templates/workflows/init-existing.md +23 -23
- package/dist/assets/templates/workflows/init.md +205 -0
- package/dist/assets/templates/workflows/new-milestone.md +9 -9
- package/dist/assets/templates/workflows/new-project.md +26 -26
- package/dist/assets/templates/workflows/plan-create.md +298 -0
- package/dist/assets/templates/workflows/plan-discuss.md +347 -0
- package/dist/assets/templates/workflows/plan-phase.md +29 -29
- package/dist/assets/templates/workflows/plan-research.md +177 -0
- package/dist/assets/templates/workflows/plan.md +231 -0
- package/dist/assets/templates/workflows/progress.md +46 -42
- package/dist/assets/templates/workflows/quick.md +195 -14
- package/dist/assets/templates/workflows/research-phase.md +5 -5
- package/dist/assets/templates/workflows/sdd.md +20 -12
- package/dist/assets/templates/workflows/settings.md +18 -14
- package/dist/assets/templates/workflows/verify-phase.md +1 -1
- package/dist/assets/templates/workflows/verify-work.md +16 -16
- package/dist/cli.cjs +496 -91
- package/dist/cli.cjs.map +1 -1
- package/dist/core-D5zUr9cb.cjs.map +1 -1
- package/dist/install.cjs +274 -355
- package/dist/install.cjs.map +1 -1
- package/dist/mcp-server.cjs +5213 -2248
- package/dist/mcp-server.cjs.map +1 -1
- package/dist/skills-CjFWZIGM.cjs.map +1 -1
- package/package.json +4 -1
- package/dist/assets/hooks/maxsim-context-monitor.cjs +0 -121
- package/dist/assets/hooks/maxsim-context-monitor.cjs.map +0 -1
- package/dist/assets/templates/agents/maxsim-code-reviewer.md +0 -239
- package/dist/assets/templates/agents/maxsim-codebase-mapper.md +0 -214
- package/dist/assets/templates/agents/maxsim-debugger.md +0 -572
- package/dist/assets/templates/agents/maxsim-drift-checker.md +0 -522
- package/dist/assets/templates/agents/maxsim-executor.md +0 -504
- package/dist/assets/templates/agents/maxsim-integration-checker.md +0 -273
- package/dist/assets/templates/agents/maxsim-phase-researcher.md +0 -305
- package/dist/assets/templates/agents/maxsim-plan-checker.md +0 -343
- package/dist/assets/templates/agents/maxsim-planner.md +0 -610
- package/dist/assets/templates/agents/maxsim-project-researcher.md +0 -359
- package/dist/assets/templates/agents/maxsim-research-synthesizer.md +0 -263
- package/dist/assets/templates/agents/maxsim-roadmapper.md +0 -324
- package/dist/assets/templates/agents/maxsim-spec-reviewer.md +0 -245
- package/dist/assets/templates/agents/maxsim-verifier.md +0 -393
- package/dist/assets/templates/commands/maxsim/add-phase.md +0 -43
- package/dist/assets/templates/commands/maxsim/add-tests.md +0 -41
- package/dist/assets/templates/commands/maxsim/add-todo.md +0 -57
- package/dist/assets/templates/commands/maxsim/artefakte.md +0 -122
- package/dist/assets/templates/commands/maxsim/audit-milestone.md +0 -36
- package/dist/assets/templates/commands/maxsim/batch.md +0 -42
- package/dist/assets/templates/commands/maxsim/check-drift.md +0 -56
- package/dist/assets/templates/commands/maxsim/check-todos.md +0 -46
- package/dist/assets/templates/commands/maxsim/cleanup.md +0 -18
- package/dist/assets/templates/commands/maxsim/complete-milestone.md +0 -136
- package/dist/assets/templates/commands/maxsim/discuss-phase.md +0 -87
- package/dist/assets/templates/commands/maxsim/discuss.md +0 -70
- package/dist/assets/templates/commands/maxsim/execute-phase.md +0 -41
- package/dist/assets/templates/commands/maxsim/health.md +0 -22
- package/dist/assets/templates/commands/maxsim/init-existing.md +0 -46
- package/dist/assets/templates/commands/maxsim/insert-phase.md +0 -32
- package/dist/assets/templates/commands/maxsim/list-phase-assumptions.md +0 -46
- package/dist/assets/templates/commands/maxsim/map-codebase.md +0 -71
- package/dist/assets/templates/commands/maxsim/new-milestone.md +0 -44
- package/dist/assets/templates/commands/maxsim/new-project.md +0 -46
- package/dist/assets/templates/commands/maxsim/pause-work.md +0 -38
- package/dist/assets/templates/commands/maxsim/plan-milestone-gaps.md +0 -34
- package/dist/assets/templates/commands/maxsim/plan-phase.md +0 -44
- package/dist/assets/templates/commands/maxsim/realign.md +0 -39
- package/dist/assets/templates/commands/maxsim/reapply-patches.md +0 -110
- package/dist/assets/templates/commands/maxsim/remove-phase.md +0 -31
- package/dist/assets/templates/commands/maxsim/research-phase.md +0 -189
- package/dist/assets/templates/commands/maxsim/resume-work.md +0 -40
- package/dist/assets/templates/commands/maxsim/roadmap.md +0 -19
- package/dist/assets/templates/commands/maxsim/sdd.md +0 -39
- package/dist/assets/templates/commands/maxsim/set-profile.md +0 -34
- package/dist/assets/templates/commands/maxsim/update.md +0 -37
- package/dist/assets/templates/commands/maxsim/verify-work.md +0 -38
- package/dist/assets/templates/workflows/add-phase.md +0 -111
- package/dist/assets/templates/workflows/add-tests.md +0 -351
- package/dist/assets/templates/workflows/add-todo.md +0 -247
- package/dist/assets/templates/workflows/audit-milestone.md +0 -297
- package/dist/assets/templates/workflows/check-drift.md +0 -248
- package/dist/assets/templates/workflows/check-todos.md +0 -261
- package/dist/assets/templates/workflows/cleanup.md +0 -153
- package/dist/assets/templates/workflows/complete-milestone.md +0 -701
- package/dist/assets/templates/workflows/discuss.md +0 -343
- package/dist/assets/templates/workflows/insert-phase.md +0 -129
- package/dist/assets/templates/workflows/list-phase-assumptions.md +0 -178
- package/dist/assets/templates/workflows/map-codebase.md +0 -315
- package/dist/assets/templates/workflows/pause-work.md +0 -122
- package/dist/assets/templates/workflows/plan-milestone-gaps.md +0 -274
- package/dist/assets/templates/workflows/realign.md +0 -288
- package/dist/assets/templates/workflows/remove-phase.md +0 -154
- package/dist/assets/templates/workflows/resume-project.md +0 -306
- package/dist/assets/templates/workflows/roadmap.md +0 -130
- package/dist/assets/templates/workflows/set-profile.md +0 -81
- package/dist/assets/templates/workflows/transition.md +0 -544
- package/dist/assets/templates/workflows/update.md +0 -220
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");
|
|
@@ -46,6 +46,7 @@ let node_readline = require("node:readline");
|
|
|
46
46
|
node_readline = __toESM(node_readline);
|
|
47
47
|
let node_crypto = require("node:crypto");
|
|
48
48
|
node_crypto = __toESM(node_crypto);
|
|
49
|
+
let node_child_process = require("node:child_process");
|
|
49
50
|
|
|
50
51
|
//#region ../../node_modules/universalify/index.js
|
|
51
52
|
var require_universalify = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
@@ -5643,11 +5644,7 @@ function ora(options) {
|
|
|
5643
5644
|
|
|
5644
5645
|
//#endregion
|
|
5645
5646
|
//#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
5647
|
const isTabKey = (key) => key.name === "tab";
|
|
5650
|
-
const isNumberKey = (key) => "1234567890".includes(key.name);
|
|
5651
5648
|
const isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
5652
5649
|
|
|
5653
5650
|
//#endregion
|
|
@@ -6164,23 +6161,6 @@ function usePrefix({ status = "idle", theme }) {
|
|
|
6164
6161
|
return typeof prefix === "string" ? prefix : prefix[status === "loading" ? "idle" : status] ?? prefix["idle"];
|
|
6165
6162
|
}
|
|
6166
6163
|
|
|
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
6164
|
//#endregion
|
|
6185
6165
|
//#region ../../node_modules/@inquirer/core/dist/lib/use-ref.js
|
|
6186
6166
|
function useRef(val) {
|
|
@@ -6548,90 +6528,6 @@ function readlineWidth() {
|
|
|
6548
6528
|
});
|
|
6549
6529
|
}
|
|
6550
6530
|
|
|
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
6531
|
//#endregion
|
|
6636
6532
|
//#region ../../node_modules/mute-stream/lib/index.js
|
|
6637
6533
|
var require_lib = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -7119,23 +7015,6 @@ function createPrompt(view) {
|
|
|
7119
7015
|
return prompt;
|
|
7120
7016
|
}
|
|
7121
7017
|
|
|
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
7018
|
//#endregion
|
|
7140
7019
|
//#region ../../node_modules/@inquirer/confirm/dist/index.js
|
|
7141
7020
|
function getBooleanValue(value, defaultValue) {
|
|
@@ -7147,7 +7026,7 @@ function getBooleanValue(value, defaultValue) {
|
|
|
7147
7026
|
function boolToString(value) {
|
|
7148
7027
|
return value ? "Yes" : "No";
|
|
7149
7028
|
}
|
|
7150
|
-
var dist_default
|
|
7029
|
+
var dist_default = createPrompt((config, done) => {
|
|
7151
7030
|
const { transformer = boolToString } = config;
|
|
7152
7031
|
const [status, setStatus] = useState("idle");
|
|
7153
7032
|
const [value, setValue] = useState("");
|
|
@@ -7177,162 +7056,6 @@ var dist_default$1 = createPrompt((config, done) => {
|
|
|
7177
7056
|
return `${prefix} ${theme.style.message(config.message, status)}${defaultValue} ${formattedValue}`;
|
|
7178
7057
|
});
|
|
7179
7058
|
|
|
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
7059
|
//#endregion
|
|
7337
7060
|
//#region ../../node_modules/minimist/index.js
|
|
7338
7061
|
var require_minimist = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -7568,11 +7291,23 @@ const builtInSkills = [
|
|
|
7568
7291
|
"brainstorming",
|
|
7569
7292
|
"roadmap-writing",
|
|
7570
7293
|
"sdd",
|
|
7571
|
-
"maxsim-batch"
|
|
7294
|
+
"maxsim-batch",
|
|
7295
|
+
"agent-system-map",
|
|
7296
|
+
"commit-conventions",
|
|
7297
|
+
"evidence-collection",
|
|
7298
|
+
"handoff-contract",
|
|
7299
|
+
"input-validation",
|
|
7300
|
+
"research-methodology",
|
|
7301
|
+
"tool-priority-guide",
|
|
7302
|
+
"verification-gates"
|
|
7572
7303
|
];
|
|
7573
7304
|
/**
|
|
7574
7305
|
* Get the global config directory for Claude Code.
|
|
7575
7306
|
* Priority: explicitDir > CLAUDE_CONFIG_DIR env > ~/.claude
|
|
7307
|
+
*
|
|
7308
|
+
* @deprecated Global install is no longer supported in v5.0+.
|
|
7309
|
+
* Kept for uninstall.ts (cleaning up old global installs) and adapters.ts.
|
|
7310
|
+
* TODO: Remove when global install cleanup path is no longer needed.
|
|
7576
7311
|
*/
|
|
7577
7312
|
function getGlobalDir(explicitDir = null) {
|
|
7578
7313
|
if (explicitDir) return expandTilde(explicitDir);
|
|
@@ -7582,6 +7317,9 @@ function getGlobalDir(explicitDir = null) {
|
|
|
7582
7317
|
/**
|
|
7583
7318
|
* Get the config directory path relative to home for hook templating.
|
|
7584
7319
|
* Used for path.join(homeDir, '<configDir>', ...) replacement in hooks.
|
|
7320
|
+
*
|
|
7321
|
+
* @deprecated Global install is no longer supported in v5.0+.
|
|
7322
|
+
* TODO: Remove when hooks.ts no longer needs global/local distinction.
|
|
7585
7323
|
*/
|
|
7586
7324
|
function getConfigDirFromHome(_isGlobal) {
|
|
7587
7325
|
return "'.claude'";
|
|
@@ -7700,7 +7438,79 @@ function getCommitAttribution(explicitConfigDir) {
|
|
|
7700
7438
|
* Clean up orphaned files from previous MAXSIM versions
|
|
7701
7439
|
*/
|
|
7702
7440
|
function cleanupOrphanedFiles(configDir) {
|
|
7703
|
-
for (const relPath of [
|
|
7441
|
+
for (const relPath of [
|
|
7442
|
+
"hooks/maxsim-notify.sh",
|
|
7443
|
+
"hooks/statusline.js",
|
|
7444
|
+
"commands/maxsim/add-phase.md",
|
|
7445
|
+
"commands/maxsim/add-tests.md",
|
|
7446
|
+
"commands/maxsim/add-todo.md",
|
|
7447
|
+
"commands/maxsim/artefakte.md",
|
|
7448
|
+
"commands/maxsim/audit-milestone.md",
|
|
7449
|
+
"commands/maxsim/batch.md",
|
|
7450
|
+
"commands/maxsim/check-drift.md",
|
|
7451
|
+
"commands/maxsim/check-todos.md",
|
|
7452
|
+
"commands/maxsim/cleanup.md",
|
|
7453
|
+
"commands/maxsim/complete-milestone.md",
|
|
7454
|
+
"commands/maxsim/discuss-phase.md",
|
|
7455
|
+
"commands/maxsim/discuss.md",
|
|
7456
|
+
"commands/maxsim/execute-phase.md",
|
|
7457
|
+
"commands/maxsim/health.md",
|
|
7458
|
+
"commands/maxsim/init-existing.md",
|
|
7459
|
+
"commands/maxsim/insert-phase.md",
|
|
7460
|
+
"commands/maxsim/list-phase-assumptions.md",
|
|
7461
|
+
"commands/maxsim/map-codebase.md",
|
|
7462
|
+
"commands/maxsim/new-milestone.md",
|
|
7463
|
+
"commands/maxsim/new-project.md",
|
|
7464
|
+
"commands/maxsim/pause-work.md",
|
|
7465
|
+
"commands/maxsim/plan-milestone-gaps.md",
|
|
7466
|
+
"commands/maxsim/plan-phase.md",
|
|
7467
|
+
"commands/maxsim/realign.md",
|
|
7468
|
+
"commands/maxsim/reapply-patches.md",
|
|
7469
|
+
"commands/maxsim/remove-phase.md",
|
|
7470
|
+
"commands/maxsim/research-phase.md",
|
|
7471
|
+
"commands/maxsim/resume-work.md",
|
|
7472
|
+
"commands/maxsim/roadmap.md",
|
|
7473
|
+
"commands/maxsim/sdd.md",
|
|
7474
|
+
"commands/maxsim/set-profile.md",
|
|
7475
|
+
"commands/maxsim/update.md",
|
|
7476
|
+
"commands/maxsim/verify-work.md",
|
|
7477
|
+
"agents/maxsim-code-reviewer.md",
|
|
7478
|
+
"agents/maxsim-codebase-mapper.md",
|
|
7479
|
+
"agents/maxsim-debugger.md",
|
|
7480
|
+
"agents/maxsim-drift-checker.md",
|
|
7481
|
+
"agents/maxsim-executor.md",
|
|
7482
|
+
"agents/maxsim-integration-checker.md",
|
|
7483
|
+
"agents/maxsim-phase-researcher.md",
|
|
7484
|
+
"agents/maxsim-plan-checker.md",
|
|
7485
|
+
"agents/maxsim-planner.md",
|
|
7486
|
+
"agents/maxsim-project-researcher.md",
|
|
7487
|
+
"agents/maxsim-research-synthesizer.md",
|
|
7488
|
+
"agents/maxsim-roadmapper.md",
|
|
7489
|
+
"agents/maxsim-spec-reviewer.md",
|
|
7490
|
+
"agents/maxsim-verifier.md",
|
|
7491
|
+
"hooks/maxsim-context-monitor.js",
|
|
7492
|
+
"maxsim/workflows/add-phase.md",
|
|
7493
|
+
"maxsim/workflows/add-tests.md",
|
|
7494
|
+
"maxsim/workflows/add-todo.md",
|
|
7495
|
+
"maxsim/workflows/audit-milestone.md",
|
|
7496
|
+
"maxsim/workflows/check-drift.md",
|
|
7497
|
+
"maxsim/workflows/check-todos.md",
|
|
7498
|
+
"maxsim/workflows/cleanup.md",
|
|
7499
|
+
"maxsim/workflows/complete-milestone.md",
|
|
7500
|
+
"maxsim/workflows/discuss.md",
|
|
7501
|
+
"maxsim/workflows/insert-phase.md",
|
|
7502
|
+
"maxsim/workflows/list-phase-assumptions.md",
|
|
7503
|
+
"maxsim/workflows/map-codebase.md",
|
|
7504
|
+
"maxsim/workflows/pause-work.md",
|
|
7505
|
+
"maxsim/workflows/plan-milestone-gaps.md",
|
|
7506
|
+
"maxsim/workflows/realign.md",
|
|
7507
|
+
"maxsim/workflows/remove-phase.md",
|
|
7508
|
+
"maxsim/workflows/resume-project.md",
|
|
7509
|
+
"maxsim/workflows/roadmap.md",
|
|
7510
|
+
"maxsim/workflows/set-profile.md",
|
|
7511
|
+
"maxsim/workflows/transition.md",
|
|
7512
|
+
"maxsim/workflows/update.md"
|
|
7513
|
+
]) {
|
|
7704
7514
|
const fullPath = node_path.join(configDir, relPath);
|
|
7705
7515
|
if (node_fs.existsSync(fullPath)) {
|
|
7706
7516
|
node_fs.unlinkSync(fullPath);
|
|
@@ -7717,7 +7527,8 @@ function cleanupOrphanedHooks(settings) {
|
|
|
7717
7527
|
"hooks/statusline.js",
|
|
7718
7528
|
"maxsim-intel-index.js",
|
|
7719
7529
|
"maxsim-intel-session.js",
|
|
7720
|
-
"maxsim-intel-prune.js"
|
|
7530
|
+
"maxsim-intel-prune.js",
|
|
7531
|
+
"maxsim-context-monitor"
|
|
7721
7532
|
];
|
|
7722
7533
|
let cleanedHooks = false;
|
|
7723
7534
|
const hooks = settings.hooks;
|
|
@@ -7784,7 +7595,7 @@ function configureSettingsHooks(targetDir, isGlobal) {
|
|
|
7784
7595
|
const settings = cleanupOrphanedHooks(readSettings(settingsPath));
|
|
7785
7596
|
const statuslineCommand = isGlobal ? buildHookCommand(targetDir, "maxsim-statusline.js") : "node " + dirName + "/hooks/maxsim-statusline.js";
|
|
7786
7597
|
const updateCheckCommand = isGlobal ? buildHookCommand(targetDir, "maxsim-check-update.js") : "node " + dirName + "/hooks/maxsim-check-update.js";
|
|
7787
|
-
const
|
|
7598
|
+
const syncReminderCommand = isGlobal ? buildHookCommand(targetDir, "maxsim-sync-reminder.js") : "node " + dirName + "/hooks/maxsim-sync-reminder.js";
|
|
7788
7599
|
if (!settings.hooks) settings.hooks = {};
|
|
7789
7600
|
const installHooks = settings.hooks;
|
|
7790
7601
|
if (!installHooks.SessionStart) installHooks.SessionStart = [];
|
|
@@ -7796,19 +7607,22 @@ function configureSettingsHooks(targetDir, isGlobal) {
|
|
|
7796
7607
|
console.log(` ${chalk.green("✓")} Configured update check hook`);
|
|
7797
7608
|
}
|
|
7798
7609
|
if (!installHooks.PostToolUse) installHooks.PostToolUse = [];
|
|
7799
|
-
if (!installHooks.PostToolUse.some((entry) => entry.hooks && entry.hooks.some((h) => h.command && h.command.includes("maxsim-
|
|
7800
|
-
installHooks.PostToolUse.push({
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7610
|
+
if (!installHooks.PostToolUse.some((entry) => entry.hooks && entry.hooks.some((h) => h.command && h.command.includes("maxsim-sync-reminder")))) {
|
|
7611
|
+
installHooks.PostToolUse.push({
|
|
7612
|
+
matcher: "Write|Edit",
|
|
7613
|
+
hooks: [{
|
|
7614
|
+
type: "command",
|
|
7615
|
+
command: syncReminderCommand
|
|
7616
|
+
}]
|
|
7617
|
+
});
|
|
7618
|
+
console.log(` ${chalk.green("✓")} Configured sync reminder hook`);
|
|
7805
7619
|
}
|
|
7806
7620
|
return {
|
|
7807
7621
|
settingsPath,
|
|
7808
7622
|
settings,
|
|
7809
7623
|
statuslineCommand,
|
|
7810
7624
|
updateCheckCommand,
|
|
7811
|
-
|
|
7625
|
+
syncReminderCommand
|
|
7812
7626
|
};
|
|
7813
7627
|
}
|
|
7814
7628
|
/**
|
|
@@ -7832,10 +7646,10 @@ async function handleStatusline(settings, isInteractive, forceStatusline) {
|
|
|
7832
7646
|
console.log();
|
|
7833
7647
|
console.log(" MAXSIM includes a statusline showing:");
|
|
7834
7648
|
console.log(" • Model name");
|
|
7835
|
-
console.log(" • Current
|
|
7836
|
-
console.log(" •
|
|
7649
|
+
console.log(" • Current phase number");
|
|
7650
|
+
console.log(" • Milestone progress percentage");
|
|
7837
7651
|
console.log();
|
|
7838
|
-
return await dist_default
|
|
7652
|
+
return await dist_default({
|
|
7839
7653
|
message: "Replace with MAXSIM statusline?",
|
|
7840
7654
|
default: false
|
|
7841
7655
|
});
|
|
@@ -7859,6 +7673,103 @@ function finishInstall(settingsPath, settings, statuslineCommand, shouldInstallS
|
|
|
7859
7673
|
`);
|
|
7860
7674
|
}
|
|
7861
7675
|
|
|
7676
|
+
//#endregion
|
|
7677
|
+
//#region src/hooks/shared.ts
|
|
7678
|
+
/** The '.claude' path segment -- template marker replaced during install. */
|
|
7679
|
+
const CLAUDE_DIR = ".claude";
|
|
7680
|
+
|
|
7681
|
+
//#endregion
|
|
7682
|
+
//#region src/hooks/maxsim-check-update.ts
|
|
7683
|
+
/**
|
|
7684
|
+
* Check for MAXSIM updates in background, write result to cache.
|
|
7685
|
+
* Called by SessionStart hook - runs once per session.
|
|
7686
|
+
*/
|
|
7687
|
+
function checkForUpdate(options) {
|
|
7688
|
+
const { homeDir, cwd } = options;
|
|
7689
|
+
const cacheDir = node_path.join(homeDir, CLAUDE_DIR, "cache");
|
|
7690
|
+
const cacheFile = node_path.join(cacheDir, "maxsim-update-check.json");
|
|
7691
|
+
const projectVersionFile = node_path.join(cwd, CLAUDE_DIR, "maxsim", "VERSION");
|
|
7692
|
+
const globalVersionFile = node_path.join(homeDir, CLAUDE_DIR, "maxsim", "VERSION");
|
|
7693
|
+
if (!node_fs.existsSync(cacheDir)) node_fs.mkdirSync(cacheDir, { recursive: true });
|
|
7694
|
+
(0, node_child_process.spawn)(process.execPath, ["-e", `
|
|
7695
|
+
const fs = require('fs');
|
|
7696
|
+
const { execSync } = require('child_process');
|
|
7697
|
+
|
|
7698
|
+
const cacheFile = ${JSON.stringify(cacheFile)};
|
|
7699
|
+
const projectVersionFile = ${JSON.stringify(projectVersionFile)};
|
|
7700
|
+
const globalVersionFile = ${JSON.stringify(globalVersionFile)};
|
|
7701
|
+
|
|
7702
|
+
// Check project directory first (local install), then global
|
|
7703
|
+
let installed = '0.0.0';
|
|
7704
|
+
try {
|
|
7705
|
+
if (fs.existsSync(projectVersionFile)) {
|
|
7706
|
+
installed = fs.readFileSync(projectVersionFile, 'utf8').trim();
|
|
7707
|
+
} else if (fs.existsSync(globalVersionFile)) {
|
|
7708
|
+
installed = fs.readFileSync(globalVersionFile, 'utf8').trim();
|
|
7709
|
+
}
|
|
7710
|
+
} catch (e) {}
|
|
7711
|
+
|
|
7712
|
+
let latest = null;
|
|
7713
|
+
try {
|
|
7714
|
+
latest = execSync('npm view maxsimcli version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
|
|
7715
|
+
} catch (e) {}
|
|
7716
|
+
|
|
7717
|
+
const result = {
|
|
7718
|
+
update_available: latest && installed !== latest,
|
|
7719
|
+
installed,
|
|
7720
|
+
latest: latest || 'unknown',
|
|
7721
|
+
checked: Math.floor(Date.now() / 1000)
|
|
7722
|
+
};
|
|
7723
|
+
|
|
7724
|
+
fs.writeFileSync(cacheFile, JSON.stringify(result));
|
|
7725
|
+
`], {
|
|
7726
|
+
stdio: "ignore",
|
|
7727
|
+
windowsHide: true,
|
|
7728
|
+
detached: true
|
|
7729
|
+
}).unref();
|
|
7730
|
+
}
|
|
7731
|
+
/**
|
|
7732
|
+
* Create a backup of the current MAXSIM installation before an update.
|
|
7733
|
+
* Called by the installer (not by the SessionStart hook).
|
|
7734
|
+
*
|
|
7735
|
+
* @param cwd - The project working directory containing .claude/
|
|
7736
|
+
* @returns The backup directory path on success, null on failure.
|
|
7737
|
+
*/
|
|
7738
|
+
function createBackupBeforeUpdate(cwd) {
|
|
7739
|
+
try {
|
|
7740
|
+
const sourceDir = node_path.join(cwd, CLAUDE_DIR);
|
|
7741
|
+
const backupDir = node_path.join(sourceDir, "maxsim-backup");
|
|
7742
|
+
node_fs.mkdirSync(backupDir, { recursive: true });
|
|
7743
|
+
for (const relDir of [
|
|
7744
|
+
"commands/maxsim",
|
|
7745
|
+
"maxsim",
|
|
7746
|
+
"hooks",
|
|
7747
|
+
"agents",
|
|
7748
|
+
"skills"
|
|
7749
|
+
]) {
|
|
7750
|
+
const src = node_path.join(sourceDir, relDir);
|
|
7751
|
+
if (!node_fs.existsSync(src)) continue;
|
|
7752
|
+
const dest = node_path.join(backupDir, relDir);
|
|
7753
|
+
node_fs.mkdirSync(node_path.dirname(dest), { recursive: true });
|
|
7754
|
+
node_fs.cpSync(src, dest, { recursive: true });
|
|
7755
|
+
}
|
|
7756
|
+
let version = "unknown";
|
|
7757
|
+
const versionFile = node_path.join(sourceDir, "maxsim", "VERSION");
|
|
7758
|
+
if (node_fs.existsSync(versionFile)) version = node_fs.readFileSync(versionFile, "utf8").trim();
|
|
7759
|
+
node_fs.writeFileSync(node_path.join(backupDir, "backup-meta.json"), JSON.stringify({
|
|
7760
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7761
|
+
version
|
|
7762
|
+
}, null, 2));
|
|
7763
|
+
return backupDir;
|
|
7764
|
+
} catch {
|
|
7765
|
+
return null;
|
|
7766
|
+
}
|
|
7767
|
+
}
|
|
7768
|
+
if (require.main === module) checkForUpdate({
|
|
7769
|
+
homeDir: node_os.homedir(),
|
|
7770
|
+
cwd: process.cwd()
|
|
7771
|
+
});
|
|
7772
|
+
|
|
7862
7773
|
//#endregion
|
|
7863
7774
|
//#region src/install/manifest.ts
|
|
7864
7775
|
const MANIFEST_NAME = "maxsim-file-manifest.json";
|
|
@@ -8082,7 +7993,8 @@ function uninstall(isGlobal, explicitConfigDir = null) {
|
|
|
8082
7993
|
"maxsim-statusline.js",
|
|
8083
7994
|
"maxsim-check-update.js",
|
|
8084
7995
|
"maxsim-check-update.sh",
|
|
8085
|
-
"maxsim-context-monitor.js"
|
|
7996
|
+
"maxsim-context-monitor.js",
|
|
7997
|
+
"maxsim-sync-reminder.js"
|
|
8086
7998
|
];
|
|
8087
7999
|
let hookCount = 0;
|
|
8088
8000
|
for (const hook of maxsimHooks) {
|
|
@@ -8131,7 +8043,7 @@ function uninstall(isGlobal, explicitConfigDir = null) {
|
|
|
8131
8043
|
if (settingsHooks && settingsHooks.PostToolUse) {
|
|
8132
8044
|
const before = settingsHooks.PostToolUse.length;
|
|
8133
8045
|
settingsHooks.PostToolUse = settingsHooks.PostToolUse.filter((entry) => {
|
|
8134
|
-
if (entry.hooks && Array.isArray(entry.hooks)) return !entry.hooks.some((h) => h.command && h.command.includes("maxsim-context-monitor"));
|
|
8046
|
+
if (entry.hooks && Array.isArray(entry.hooks)) return !entry.hooks.some((h) => h.command && (h.command.includes("maxsim-context-monitor") || h.command.includes("maxsim-sync-reminder")));
|
|
8135
8047
|
return true;
|
|
8136
8048
|
});
|
|
8137
8049
|
if (settingsHooks.PostToolUse.length < before) {
|
|
@@ -8158,7 +8070,6 @@ function uninstall(isGlobal, explicitConfigDir = null) {
|
|
|
8158
8070
|
var import_lib = /* @__PURE__ */ __toESM(require_lib$1());
|
|
8159
8071
|
const argv = (0, import_minimist.default)(process.argv.slice(2), {
|
|
8160
8072
|
boolean: [
|
|
8161
|
-
"global",
|
|
8162
8073
|
"local",
|
|
8163
8074
|
"claude",
|
|
8164
8075
|
"uninstall",
|
|
@@ -8169,14 +8080,12 @@ const argv = (0, import_minimist.default)(process.argv.slice(2), {
|
|
|
8169
8080
|
],
|
|
8170
8081
|
string: ["config-dir"],
|
|
8171
8082
|
alias: {
|
|
8172
|
-
g: "global",
|
|
8173
8083
|
l: "local",
|
|
8174
8084
|
u: "uninstall",
|
|
8175
8085
|
h: "help",
|
|
8176
8086
|
c: "config-dir"
|
|
8177
8087
|
}
|
|
8178
8088
|
});
|
|
8179
|
-
const hasGlobal = !!argv["global"];
|
|
8180
8089
|
const hasLocal = !!argv["local"];
|
|
8181
8090
|
const hasUninstall = !!argv["uninstall"];
|
|
8182
8091
|
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,30 +8103,37 @@ for (const flag of [
|
|
|
8194
8103
|
console.error(`Error: The --${flag} flag is no longer supported. MAXSIM v2.0 is Claude Code only.`);
|
|
8195
8104
|
process.exit(1);
|
|
8196
8105
|
}
|
|
8106
|
+
if (argv["global"] || argv["g"]) {
|
|
8107
|
+
console.error(chalk.red("Error: Global install is no longer supported."));
|
|
8108
|
+
console.error("MAXSIM v5.0+ installs locally to .claude/ in your project directory.");
|
|
8109
|
+
console.error("Run: npx maxsimcli --local");
|
|
8110
|
+
process.exit(1);
|
|
8111
|
+
}
|
|
8197
8112
|
if (hasVersion) {
|
|
8198
8113
|
console.log(pkg.version);
|
|
8199
8114
|
process.exit(0);
|
|
8200
8115
|
}
|
|
8201
8116
|
console.log(banner);
|
|
8202
8117
|
if (hasHelp) {
|
|
8203
|
-
console.log(` ${chalk.yellow("Usage:")} npx maxsimcli [options]\n\n ${chalk.yellow("Options:")}\n ${chalk.cyan("-
|
|
8118
|
+
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
8119
|
process.exit(0);
|
|
8205
8120
|
}
|
|
8206
|
-
async function install(
|
|
8121
|
+
async function install() {
|
|
8207
8122
|
const dirName = getDirName();
|
|
8208
8123
|
const src = templatesRoot;
|
|
8209
|
-
const targetDir =
|
|
8210
|
-
const locationLabel =
|
|
8211
|
-
const pathPrefix =
|
|
8124
|
+
const targetDir = explicitConfigDir ? node_path.resolve(process.cwd(), explicitConfigDir) : node_path.join(process.cwd(), dirName);
|
|
8125
|
+
const locationLabel = targetDir.replace(process.cwd(), ".");
|
|
8126
|
+
const pathPrefix = `./${dirName}/`;
|
|
8212
8127
|
console.log(` Installing for ${chalk.cyan("Claude Code")} to ${chalk.cyan(locationLabel)}\n`);
|
|
8213
8128
|
const failures = [];
|
|
8214
8129
|
const existingManifest = readManifest(targetDir);
|
|
8215
8130
|
const isAlreadyCurrent = existingManifest !== null && existingManifest.version === pkg.version;
|
|
8216
8131
|
if (existingManifest !== null) {
|
|
8217
8132
|
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
|
|
8133
|
+
if (!complete) console.log(` ${chalk.yellow("!")} Previous install (v${existingManifest.version}) is incomplete -- ${missing.length} missing file(s). Re-installing.`);
|
|
8134
|
+
else if (isAlreadyCurrent) console.log(` ${chalk.dim(`Version ${pkg.version} already installed -- upgrading in place`)}`);
|
|
8220
8135
|
}
|
|
8136
|
+
if (existingManifest !== null) createBackupBeforeUpdate(process.cwd());
|
|
8221
8137
|
saveLocalPatches(targetDir);
|
|
8222
8138
|
cleanupOrphanedFiles(targetDir);
|
|
8223
8139
|
let spinner = ora({
|
|
@@ -8313,6 +8229,27 @@ async function install(isGlobal) {
|
|
|
8313
8229
|
failures.push("skills");
|
|
8314
8230
|
}
|
|
8315
8231
|
}
|
|
8232
|
+
const rulesSrc = node_path.join(src, "rules");
|
|
8233
|
+
if (node_fs.existsSync(rulesSrc)) {
|
|
8234
|
+
spinner = ora({
|
|
8235
|
+
text: "Installing rules...",
|
|
8236
|
+
color: "cyan"
|
|
8237
|
+
}).start();
|
|
8238
|
+
const rulesDest = node_path.join(targetDir, "rules");
|
|
8239
|
+
node_fs.mkdirSync(rulesDest, { recursive: true });
|
|
8240
|
+
const ruleEntries = node_fs.readdirSync(rulesSrc, { withFileTypes: true });
|
|
8241
|
+
for (const entry of ruleEntries) if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
8242
|
+
let content = node_fs.readFileSync(node_path.join(rulesSrc, entry.name), "utf8");
|
|
8243
|
+
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
8244
|
+
node_fs.writeFileSync(node_path.join(rulesDest, entry.name), content);
|
|
8245
|
+
}
|
|
8246
|
+
const installedRuleFiles = node_fs.readdirSync(rulesDest).filter((f) => f.endsWith(".md")).length;
|
|
8247
|
+
if (installedRuleFiles > 0) spinner.succeed(chalk.green("✓") + ` Installed ${installedRuleFiles} rules to rules/`);
|
|
8248
|
+
else {
|
|
8249
|
+
spinner.fail("Failed to install rules");
|
|
8250
|
+
failures.push("rules");
|
|
8251
|
+
}
|
|
8252
|
+
}
|
|
8316
8253
|
const changelogSrc = node_path.join(src, "..", "CHANGELOG.md");
|
|
8317
8254
|
const changelogDest = node_path.join(targetDir, "maxsim", "CHANGELOG.md");
|
|
8318
8255
|
if (node_fs.existsSync(changelogSrc)) {
|
|
@@ -8356,7 +8293,7 @@ async function install(isGlobal) {
|
|
|
8356
8293
|
node_fs.copyFileSync(toolSrc, toolDest);
|
|
8357
8294
|
console.log(` ${chalk.green("✓")} Installed maxsim-tools.cjs`);
|
|
8358
8295
|
} else {
|
|
8359
|
-
console.warn(` ${chalk.yellow("!")} cli.cjs not found at ${toolSrc}
|
|
8296
|
+
console.warn(` ${chalk.yellow("!")} cli.cjs not found at ${toolSrc} -- maxsim-tools.cjs not installed`);
|
|
8360
8297
|
failures.push("maxsim-tools.cjs");
|
|
8361
8298
|
}
|
|
8362
8299
|
const mcpSrc = node_path.resolve(__dirname, "mcp-server.cjs");
|
|
@@ -8365,9 +8302,9 @@ async function install(isGlobal) {
|
|
|
8365
8302
|
node_fs.mkdirSync(binDir, { recursive: true });
|
|
8366
8303
|
node_fs.copyFileSync(mcpSrc, mcpDest);
|
|
8367
8304
|
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 =
|
|
8305
|
+
} else console.warn(` ${chalk.yellow("!")} mcp-server.cjs not found -- MCP server not installed`);
|
|
8306
|
+
installHookFiles(targetDir, false, failures);
|
|
8307
|
+
const mcpJsonPath = node_path.join(process.cwd(), ".mcp.json");
|
|
8371
8308
|
let mcpConfig = {};
|
|
8372
8309
|
let skipMcpConfig = false;
|
|
8373
8310
|
if (node_fs.existsSync(mcpJsonPath)) {
|
|
@@ -8378,7 +8315,7 @@ async function install(isGlobal) {
|
|
|
8378
8315
|
console.warn(` ${chalk.yellow("!")} .mcp.json is corrupted (invalid JSON). Backup saved to .mcp.json.bak`);
|
|
8379
8316
|
let startFresh = true;
|
|
8380
8317
|
try {
|
|
8381
|
-
startFresh = await dist_default
|
|
8318
|
+
startFresh = await dist_default({
|
|
8382
8319
|
message: ".mcp.json is corrupted. Start with a fresh config? (No = abort MCP setup)",
|
|
8383
8320
|
default: true
|
|
8384
8321
|
});
|
|
@@ -8407,7 +8344,7 @@ async function install(isGlobal) {
|
|
|
8407
8344
|
writeManifest(targetDir);
|
|
8408
8345
|
console.log(` ${chalk.green("✓")} Wrote file manifest (${MANIFEST_NAME})`);
|
|
8409
8346
|
reportLocalPatches(targetDir);
|
|
8410
|
-
const { settingsPath, settings, statuslineCommand } = configureSettingsHooks(targetDir,
|
|
8347
|
+
const { settingsPath, settings, statuslineCommand } = configureSettingsHooks(targetDir, false);
|
|
8411
8348
|
return {
|
|
8412
8349
|
settingsPath,
|
|
8413
8350
|
settings,
|
|
@@ -8415,26 +8352,6 @@ async function install(isGlobal) {
|
|
|
8415
8352
|
};
|
|
8416
8353
|
}
|
|
8417
8354
|
/**
|
|
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
8355
|
* Prompt whether to enable Agent Teams (experimental feature)
|
|
8439
8356
|
*/
|
|
8440
8357
|
async function promptAgentTeams() {
|
|
@@ -8443,26 +8360,38 @@ async function promptAgentTeams() {
|
|
|
8443
8360
|
console.log(chalk.dim(" Coordinate multiple Claude Code instances working in parallel."));
|
|
8444
8361
|
console.log(chalk.dim(" Enables CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS in settings.json."));
|
|
8445
8362
|
console.log();
|
|
8446
|
-
return dist_default
|
|
8363
|
+
return dist_default({
|
|
8447
8364
|
message: "Enable Agent Teams?",
|
|
8448
8365
|
default: false
|
|
8449
8366
|
});
|
|
8450
8367
|
}
|
|
8451
8368
|
/**
|
|
8452
|
-
* Install MAXSIM for Claude Code
|
|
8369
|
+
* Install MAXSIM for Claude Code (always local)
|
|
8453
8370
|
*/
|
|
8454
|
-
async function installForClaude(
|
|
8455
|
-
const result = await install(
|
|
8371
|
+
async function installForClaude(isInteractive) {
|
|
8372
|
+
const result = await install();
|
|
8456
8373
|
let shouldInstallStatusline = false;
|
|
8457
8374
|
if (result.settings) shouldInstallStatusline = await handleStatusline(result.settings, isInteractive, forceStatusline);
|
|
8375
|
+
const agentTeamsAlreadyEnabled = process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1";
|
|
8458
8376
|
let enableAgentTeams = false;
|
|
8459
|
-
if (
|
|
8460
|
-
if (enableAgentTeams
|
|
8377
|
+
if (agentTeamsAlreadyEnabled) console.log(` ${chalk.green("✓")} Agent Teams: enabled`);
|
|
8378
|
+
else if (isInteractive) enableAgentTeams = await promptAgentTeams();
|
|
8379
|
+
else {
|
|
8380
|
+
console.log();
|
|
8381
|
+
console.log(chalk.cyan(" Agent Teams") + chalk.dim(" (Recommended for Parallel Execution)"));
|
|
8382
|
+
console.log(chalk.dim(" MAXSIM's parallel execution uses Agent Teams for coordinating multiple agents."));
|
|
8383
|
+
console.log(chalk.dim(" To enable, add to your environment:"));
|
|
8384
|
+
console.log();
|
|
8385
|
+
console.log(chalk.yellow(" export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1"));
|
|
8386
|
+
console.log();
|
|
8387
|
+
console.log(chalk.dim(" Or add to your shell profile (~/.bashrc, ~/.zshrc, etc.)"));
|
|
8388
|
+
}
|
|
8389
|
+
if ((enableAgentTeams || agentTeamsAlreadyEnabled) && result.settings) {
|
|
8461
8390
|
const env = result.settings.env ?? {};
|
|
8462
8391
|
env["CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS"] = "1";
|
|
8463
8392
|
result.settings.env = env;
|
|
8464
8393
|
}
|
|
8465
|
-
finishInstall(result.settingsPath, result.settings, result.statuslineCommand, shouldInstallStatusline,
|
|
8394
|
+
finishInstall(result.settingsPath, result.settings, result.statuslineCommand, shouldInstallStatusline, false);
|
|
8466
8395
|
}
|
|
8467
8396
|
const subcommand = argv._[0];
|
|
8468
8397
|
(async () => {
|
|
@@ -8487,23 +8416,13 @@ const subcommand = argv._[0];
|
|
|
8487
8416
|
}
|
|
8488
8417
|
return;
|
|
8489
8418
|
}
|
|
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"));
|
|
8419
|
+
if (hasUninstall) {
|
|
8420
|
+
if (!hasLocal) {
|
|
8421
|
+
console.error(chalk.yellow("--uninstall requires --local"));
|
|
8499
8422
|
process.exit(1);
|
|
8500
8423
|
}
|
|
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);
|
|
8424
|
+
uninstall(false, explicitConfigDir);
|
|
8425
|
+
} else await installForClaude(process.stdin.isTTY === true);
|
|
8507
8426
|
})().catch((err) => {
|
|
8508
8427
|
if (err instanceof Error && err.message.includes("User force closed")) {
|
|
8509
8428
|
console.log("\n" + chalk.yellow("Installation cancelled") + "\n");
|