maxsimcli 5.0.0 → 5.0.2

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.
@@ -1,3 +1,34 @@
1
+ ## [5.0.1](https://github.com/maystudios/maxsimcli/compare/v5.0.0...v5.0.1) (2026-03-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **install:** update Discord community link ([3c548ab](https://github.com/maystudios/maxsimcli/commit/3c548ab608223780534ac8c5b1c79ad2bf66f338))
7
+
8
+ # [5.0.0](https://github.com/maystudios/maxsimcli/compare/v4.16.0...v5.0.0) (2026-03-12)
9
+
10
+
11
+ * feat!: replace MCP server with CLI github commands ([2fc6a0e](https://github.com/maystudios/maxsimcli/commit/2fc6a0eeafbd5e7f010406f8c097fa3aad654db3))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * **e2e:** remove stale MCP server tests and update install assertions ([32f6fe1](https://github.com/maystudios/maxsimcli/commit/32f6fe1226da022aef46b831dbeec39e052401a4))
17
+
18
+
19
+ ### Features
20
+
21
+ * add sound notification hooks for AskUserQuestion and Stop events ([6e96a6e](https://github.com/maystudios/maxsimcli/commit/6e96a6e7e5147eefae5a1e073927ce99ceedaf49))
22
+ * make GitHub Issues single source of truth for task/plan tracking ([8409c10](https://github.com/maystudios/maxsimcli/commit/8409c107305ff1183f2997d92a1515979ce2dc28))
23
+
24
+
25
+ ### BREAKING CHANGES
26
+
27
+ * MCP server removed. GitHub operations now use
28
+ `node maxsim-tools.cjs github <command>` instead of MCP tools.
29
+
30
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
31
+
1
32
  # [4.16.0](https://github.com/maystudios/maxsimcli/compare/v4.15.4...v4.16.0) (2026-03-12)
2
33
 
3
34
 
@@ -1,38 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
- //#region \0rolldown/runtime.js
4
- var __create = Object.create;
5
- var __defProp = Object.defineProperty;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __getOwnPropNames = Object.getOwnPropertyNames;
8
- var __getProtoOf = Object.getPrototypeOf;
9
- var __hasOwnProp = Object.prototype.hasOwnProperty;
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
13
- key = keys[i];
14
- if (!__hasOwnProp.call(to, key) && key !== except) {
15
- __defProp(to, key, {
16
- get: ((k) => from[k]).bind(null, key),
17
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
- });
19
- }
20
- }
21
- }
22
- return to;
23
- };
24
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
25
- value: mod,
26
- enumerable: true
27
- }) : target, mod));
28
-
29
- //#endregion
30
- let node_fs = require("node:fs");
31
- node_fs = __toESM(node_fs);
32
- let node_os = require("node:os");
33
- node_os = __toESM(node_os);
34
- let node_path = require("node:path");
35
- node_path = __toESM(node_path);
36
3
 
37
4
  //#region src/hooks/shared.ts
38
5
  /**
@@ -58,52 +25,12 @@ function readStdinJson(callback) {
58
25
  //#endregion
59
26
  //#region src/hooks/maxsim-sync-reminder.ts
60
27
  /**
61
- * Sync Reminder Hook — PostToolUse hook that detects .planning/ file writes
62
- * and gently reminds the user to sync changes to GitHub Issues.
63
- *
64
- * Debounces reminders: fires on the first .planning/ write per session,
65
- * then every DEBOUNCE_CALLS writes thereafter.
28
+ * Sync Reminder Hook — No longer needed.
29
+ * GitHub Issues is the sole source of truth for phase artifacts and todos.
30
+ * Local .planning/ writes no longer need sync reminders.
66
31
  */
67
- /** Number of .planning/ writes between repeated reminders. */
68
32
  const DEBOUNCE_CALLS = 10;
69
- const REMINDER_MESSAGE = ".planning/ files changed locally. Consider syncing to GitHub Issues when ready.";
70
- function processSyncReminder(data) {
71
- const sessionId = data.session_id;
72
- const filePath = data.tool_input?.file_path;
73
- if (!sessionId || !filePath) return null;
74
- const normalized = node_path.normalize(filePath);
75
- const planningSegment = `${node_path.sep}.planning${node_path.sep}`;
76
- const planningEnd = `${node_path.sep}.planning`;
77
- if (!normalized.includes(planningSegment) && !normalized.endsWith(planningEnd)) return null;
78
- const stateFile = node_path.join(node_os.tmpdir(), `maxsim-sync-${sessionId}.json`);
79
- let state;
80
- try {
81
- if (node_fs.existsSync(stateFile)) state = JSON.parse(node_fs.readFileSync(stateFile, "utf8"));
82
- else state = {
83
- callsSinceRemind: 0,
84
- reminded: false
85
- };
86
- } catch {
87
- state = {
88
- callsSinceRemind: 0,
89
- reminded: false
90
- };
91
- }
92
- state.callsSinceRemind++;
93
- if (!state.reminded || state.callsSinceRemind >= DEBOUNCE_CALLS) {
94
- state.callsSinceRemind = 0;
95
- state.reminded = true;
96
- try {
97
- node_fs.writeFileSync(stateFile, JSON.stringify(state));
98
- } catch {}
99
- return { hookSpecificOutput: {
100
- hookEventName: "PostToolUse",
101
- additionalContext: REMINDER_MESSAGE
102
- } };
103
- }
104
- try {
105
- node_fs.writeFileSync(stateFile, JSON.stringify(state));
106
- } catch {}
33
+ function processSyncReminder(_data) {
107
34
  return null;
108
35
  }
109
36
  if (require.main === module) readStdinJson((data) => {
@@ -1 +1 @@
1
- {"version":3,"file":"maxsim-sync-reminder.cjs","names":["path","os","fs"],"sources":["../../../src/hooks/shared.ts","../../../src/hooks/maxsim-sync-reminder.ts"],"sourcesContent":["/**\n * Shared utilities for MAXSIM hooks.\n */\n\n/**\n * Read all stdin as a string, then invoke callback with parsed JSON.\n * Used by statusline and sync-reminder hooks.\n */\nexport function readStdinJson<T>(callback: (data: T) => void): void {\n let input = '';\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', (chunk: string) => (input += chunk));\n process.stdin.on('end', () => {\n try {\n const data = JSON.parse(input) as T;\n callback(data);\n } catch {\n // Silent fail -- never block hook execution\n process.exit(0);\n }\n });\n}\n\n/** The '.claude' path segment -- template marker replaced during install. */\nexport const CLAUDE_DIR = '.claude';\n\n/**\n * Play a system sound for notifications. Fire-and-forget, never blocks.\n * Suppressed when MAXSIM_SOUND=0, CI=true, or SSH_CONNECTION is set.\n */\nexport function playSound(type: 'question' | 'stop'): void {\n try {\n if (\n process.env.MAXSIM_SOUND === '0' ||\n process.env.CI === 'true' ||\n process.env.SSH_CONNECTION\n ) {\n return;\n }\n\n const platform = process.platform;\n\n if (platform === 'win32') {\n const file =\n type === 'question'\n ? 'C:\\\\Windows\\\\Media\\\\notify.wav'\n : 'C:\\\\Windows\\\\Media\\\\chimes.wav';\n const { spawn } = require('node:child_process') as typeof import('node:child_process');\n const child = spawn(\n 'powershell',\n ['-NoProfile', '-Command', `(New-Object Media.SoundPlayer '${file}').PlaySync()`],\n { stdio: 'ignore', windowsHide: true, detached: true },\n );\n child.unref();\n } else if (platform === 'darwin') {\n const file =\n type === 'question'\n ? '/System/Library/Sounds/Ping.aiff'\n : '/System/Library/Sounds/Glass.aiff';\n const { spawn } = require('node:child_process') as typeof import('node:child_process');\n const child = spawn('afplay', [file], {\n stdio: 'ignore',\n detached: true,\n });\n child.unref();\n } else {\n // Linux / unknown — terminal bell fallback\n process.stderr.write('\\x07');\n }\n } catch {\n // Silent fail — never block hook execution\n }\n}\n","#!/usr/bin/env node\n/**\n * Sync Reminder Hook — PostToolUse hook that detects .planning/ file writes\n * and gently reminds the user to sync changes to GitHub Issues.\n *\n * Debounces reminders: fires on the first .planning/ write per session,\n * then every DEBOUNCE_CALLS writes thereafter.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { readStdinJson } from './shared';\n\nexport interface SyncReminderInput {\n session_id?: string;\n cwd?: string;\n tool_input?: { file_path?: string };\n}\n\nexport interface SyncReminderOutput {\n hookSpecificOutput: {\n hookEventName: string;\n additionalContext: string;\n };\n}\n\ninterface DebounceState {\n callsSinceRemind: number;\n reminded: boolean;\n}\n\n/** Number of .planning/ writes between repeated reminders. */\nexport const DEBOUNCE_CALLS = 10;\n\nconst REMINDER_MESSAGE =\n '.planning/ files changed locally. Consider syncing to GitHub Issues when ready.';\n\nexport function processSyncReminder(\n data: SyncReminderInput,\n): SyncReminderOutput | null {\n const sessionId = data.session_id;\n const filePath = data.tool_input?.file_path;\n\n if (!sessionId || !filePath) {\n return null;\n }\n\n // Normalize path for cross-platform (Windows backslash handling)\n const normalized = path.normalize(filePath);\n\n // Check if the file is inside a .planning/ directory\n const planningSegment = `${path.sep}.planning${path.sep}`;\n const planningEnd = `${path.sep}.planning`;\n if (\n !normalized.includes(planningSegment) &&\n !normalized.endsWith(planningEnd)\n ) {\n return null;\n }\n\n // Load debounce state from temp file\n const stateFile = path.join(\n os.tmpdir(),\n `maxsim-sync-${sessionId}.json`,\n );\n\n let state: DebounceState;\n try {\n if (fs.existsSync(stateFile)) {\n state = JSON.parse(fs.readFileSync(stateFile, 'utf8')) as DebounceState;\n } else {\n state = { callsSinceRemind: 0, reminded: false };\n }\n } catch {\n state = { callsSinceRemind: 0, reminded: false };\n }\n\n state.callsSinceRemind++;\n\n // Fire reminder on first write OR after debounce interval expires\n if (!state.reminded || state.callsSinceRemind >= DEBOUNCE_CALLS) {\n state.callsSinceRemind = 0;\n state.reminded = true;\n\n try {\n fs.writeFileSync(stateFile, JSON.stringify(state));\n } catch {\n // Silent fail -- never block hook execution\n }\n\n return {\n hookSpecificOutput: {\n hookEventName: 'PostToolUse',\n additionalContext: REMINDER_MESSAGE,\n },\n };\n }\n\n // Not time for a reminder yet\n try {\n fs.writeFileSync(stateFile, JSON.stringify(state));\n } catch {\n // Silent fail -- never block hook execution\n }\n\n return null;\n}\n\n// Standalone entry\nif (require.main === module) {\n readStdinJson<SyncReminderInput>((data) => {\n const result = processSyncReminder(data);\n if (result) {\n process.stdout.write(JSON.stringify(result));\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,SAAgB,cAAiB,UAAmC;CAClE,IAAI,QAAQ;AACZ,SAAQ,MAAM,YAAY,OAAO;AACjC,SAAQ,MAAM,GAAG,SAAS,UAAmB,SAAS,MAAO;AAC7D,SAAQ,MAAM,GAAG,aAAa;AAC5B,MAAI;AAEF,YADa,KAAK,MAAM,MAAM,CAChB;UACR;AAEN,WAAQ,KAAK,EAAE;;GAEjB;;;;;;;;;;;;;ACaJ,MAAa,iBAAiB;AAE9B,MAAM,mBACJ;AAEF,SAAgB,oBACd,MAC2B;CAC3B,MAAM,YAAY,KAAK;CACvB,MAAM,WAAW,KAAK,YAAY;AAElC,KAAI,CAAC,aAAa,CAAC,SACjB,QAAO;CAIT,MAAM,aAAaA,UAAK,UAAU,SAAS;CAG3C,MAAM,kBAAkB,GAAGA,UAAK,IAAI,WAAWA,UAAK;CACpD,MAAM,cAAc,GAAGA,UAAK,IAAI;AAChC,KACE,CAAC,WAAW,SAAS,gBAAgB,IACrC,CAAC,WAAW,SAAS,YAAY,CAEjC,QAAO;CAIT,MAAM,YAAYA,UAAK,KACrBC,QAAG,QAAQ,EACX,eAAe,UAAU,OAC1B;CAED,IAAI;AACJ,KAAI;AACF,MAAIC,QAAG,WAAW,UAAU,CAC1B,SAAQ,KAAK,MAAMA,QAAG,aAAa,WAAW,OAAO,CAAC;MAEtD,SAAQ;GAAE,kBAAkB;GAAG,UAAU;GAAO;SAE5C;AACN,UAAQ;GAAE,kBAAkB;GAAG,UAAU;GAAO;;AAGlD,OAAM;AAGN,KAAI,CAAC,MAAM,YAAY,MAAM,oBAAoB,gBAAgB;AAC/D,QAAM,mBAAmB;AACzB,QAAM,WAAW;AAEjB,MAAI;AACF,WAAG,cAAc,WAAW,KAAK,UAAU,MAAM,CAAC;UAC5C;AAIR,SAAO,EACL,oBAAoB;GAClB,eAAe;GACf,mBAAmB;GACpB,EACF;;AAIH,KAAI;AACF,UAAG,cAAc,WAAW,KAAK,UAAU,MAAM,CAAC;SAC5C;AAIR,QAAO;;AAIT,IAAI,QAAQ,SAAS,OACnB,gBAAkC,SAAS;CACzC,MAAM,SAAS,oBAAoB,KAAK;AACxC,KAAI,OACF,SAAQ,OAAO,MAAM,KAAK,UAAU,OAAO,CAAC;EAE9C"}
1
+ {"version":3,"file":"maxsim-sync-reminder.cjs","names":[],"sources":["../../../src/hooks/shared.ts","../../../src/hooks/maxsim-sync-reminder.ts"],"sourcesContent":["/**\n * Shared utilities for MAXSIM hooks.\n */\n\n/**\n * Read all stdin as a string, then invoke callback with parsed JSON.\n * Used by statusline and sync-reminder hooks.\n */\nexport function readStdinJson<T>(callback: (data: T) => void): void {\n let input = '';\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', (chunk: string) => (input += chunk));\n process.stdin.on('end', () => {\n try {\n const data = JSON.parse(input) as T;\n callback(data);\n } catch {\n // Silent fail -- never block hook execution\n process.exit(0);\n }\n });\n}\n\n/** The '.claude' path segment -- template marker replaced during install. */\nexport const CLAUDE_DIR = '.claude';\n\n/**\n * Play a system sound for notifications. Fire-and-forget, never blocks.\n * Suppressed when MAXSIM_SOUND=0, CI=true, or SSH_CONNECTION is set.\n */\nexport function playSound(type: 'question' | 'stop'): void {\n try {\n if (\n process.env.MAXSIM_SOUND === '0' ||\n process.env.CI === 'true' ||\n process.env.SSH_CONNECTION\n ) {\n return;\n }\n\n const platform = process.platform;\n\n if (platform === 'win32') {\n const file =\n type === 'question'\n ? 'C:\\\\Windows\\\\Media\\\\notify.wav'\n : 'C:\\\\Windows\\\\Media\\\\chimes.wav';\n const { spawn } = require('node:child_process') as typeof import('node:child_process');\n const child = spawn(\n 'powershell',\n ['-NoProfile', '-Command', `(New-Object Media.SoundPlayer '${file}').PlaySync()`],\n { stdio: 'ignore', windowsHide: true, detached: true },\n );\n child.unref();\n } else if (platform === 'darwin') {\n const file =\n type === 'question'\n ? '/System/Library/Sounds/Ping.aiff'\n : '/System/Library/Sounds/Glass.aiff';\n const { spawn } = require('node:child_process') as typeof import('node:child_process');\n const child = spawn('afplay', [file], {\n stdio: 'ignore',\n detached: true,\n });\n child.unref();\n } else {\n // Linux / unknown — terminal bell fallback\n process.stderr.write('\\x07');\n }\n } catch {\n // Silent fail — never block hook execution\n }\n}\n","#!/usr/bin/env node\n/**\n * Sync Reminder Hook — No longer needed.\n * GitHub Issues is the sole source of truth for phase artifacts and todos.\n * Local .planning/ writes no longer need sync reminders.\n */\n\nimport { readStdinJson } from './shared';\n\nexport interface SyncReminderInput {\n session_id?: string;\n cwd?: string;\n tool_input?: { file_path?: string };\n}\n\nexport interface SyncReminderOutput {\n hookSpecificOutput: {\n hookEventName: string;\n additionalContext: string;\n };\n}\n\nexport const DEBOUNCE_CALLS = 10;\n\nexport function processSyncReminder(\n _data: SyncReminderInput,\n): SyncReminderOutput | null {\n // No-op: GitHub Issues is SSOT for phase artifacts and todos.\n return null;\n}\n\n// Standalone entry\nif (require.main === module) {\n readStdinJson<SyncReminderInput>((data) => {\n const result = processSyncReminder(data);\n if (result) {\n process.stdout.write(JSON.stringify(result));\n }\n });\n}\n"],"mappings":";;;;;;;;;;;AAQA,SAAgB,cAAiB,UAAmC;CAClE,IAAI,QAAQ;AACZ,SAAQ,MAAM,YAAY,OAAO;AACjC,SAAQ,MAAM,GAAG,SAAS,UAAmB,SAAS,MAAO;AAC7D,SAAQ,MAAM,GAAG,aAAa;AAC5B,MAAI;AAEF,YADa,KAAK,MAAM,MAAM,CAChB;UACR;AAEN,WAAQ,KAAK,EAAE;;GAEjB;;;;;;;;;;ACEJ,MAAa,iBAAiB;AAE9B,SAAgB,oBACd,OAC2B;AAE3B,QAAO;;AAIT,IAAI,QAAQ,SAAS,OACnB,gBAAkC,SAAS;CACzC,MAAM,SAAS,oBAAoB,KAAK;AACxC,KAAI,OACF,SAAQ,OAAO,MAAM,KAAK,UAAU,OAAO,CAAC;EAE9C"}
@@ -73,13 +73,14 @@ Every agent return MUST include these sections (enforced by the handoff-contract
73
73
 
74
74
  ## Model Selection
75
75
 
76
- Config `model_profile` (quality/balanced/budget) provides baseline model per agent type. Orchestrator can override per-spawn for complex tasks.
77
-
78
- | Agent | quality | balanced | budget |
79
- |-------|---------|----------|--------|
80
- | executor | opus | sonnet | sonnet |
81
- | planner | opus | sonnet | haiku |
82
- | researcher | opus | sonnet | haiku |
83
- | verifier | sonnet | sonnet | haiku |
76
+ Config `model_profile` (quality/balanced/budget/tokenburner) provides baseline model per agent type. Orchestrator can override per-spawn for complex tasks.
77
+
78
+ | Agent | quality | balanced | budget | tokenburner |
79
+ |-------|---------|----------|--------|-------------|
80
+ | executor | opus | sonnet | sonnet | opus |
81
+ | planner | opus | opus | sonnet | opus |
82
+ | researcher | opus | sonnet | haiku | opus |
83
+ | verifier | sonnet | sonnet | haiku | opus |
84
+ | debugger | sonnet | sonnet | haiku | opus |
84
85
 
85
86
  Model is set via `model: inherit` in agent frontmatter (uses session model) or explicit override in orchestrator spawn.