maxsimcli 2.5.3 → 2.5.5

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,17 @@
1
+ ## [2.5.5](https://github.com/maystudios/maxsim/compare/v2.5.4...v2.5.5) (2026-02-25)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **dashboard:** resolve claude executable path on Windows ([18261ea](https://github.com/maystudios/maxsim/commit/18261eafb20dfab82bc4d864d35dcbb550320027))
7
+
8
+ ## [2.5.4](https://github.com/maystudios/maxsim/compare/v2.5.3...v2.5.4) (2026-02-25)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **dashboard:** cross-platform compatibility fixes ([9101d90](https://github.com/maystudios/maxsim/commit/9101d90de233ea563227d9477721ac1fb1f39115))
14
+
1
15
  ## [2.5.3](https://github.com/maystudios/maxsim/compare/v2.5.2...v2.5.3) (2026-02-25)
2
16
 
3
17
 
@@ -32444,7 +32444,7 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
32444
32444
  const tls = require("tls");
32445
32445
  const { randomBytes, createHash: createHash$1 } = require("crypto");
32446
32446
  const { Duplex: Duplex$2, Readable: Readable$1 } = require("stream");
32447
- const { URL: URL$1 } = require("url");
32447
+ const { URL } = require("url");
32448
32448
  const PerMessageDeflate = require_permessage_deflate();
32449
32449
  const Receiver = require_receiver();
32450
32450
  const Sender = require_sender();
@@ -32973,9 +32973,9 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
32973
32973
  websocket._closeTimeout = opts.closeTimeout;
32974
32974
  if (!protocolVersions.includes(opts.protocolVersion)) throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})`);
32975
32975
  let parsedUrl;
32976
- if (address instanceof URL$1) parsedUrl = address;
32976
+ if (address instanceof URL) parsedUrl = address;
32977
32977
  else try {
32978
- parsedUrl = new URL$1(address);
32978
+ parsedUrl = new URL(address);
32979
32979
  } catch (e) {
32980
32980
  throw new SyntaxError(`Invalid URL: ${address}`);
32981
32981
  }
@@ -33077,7 +33077,7 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
33077
33077
  req.abort();
33078
33078
  let addr;
33079
33079
  try {
33080
- addr = new URL$1(location, address);
33080
+ addr = new URL(location, address);
33081
33081
  } catch (e) {
33082
33082
  emitErrorAndClose(websocket, /* @__PURE__ */ new SyntaxError(`Invalid URL: ${location}`));
33083
33083
  return;
@@ -41434,14 +41434,10 @@ try {
41434
41434
  const DISCONNECT_TIMEOUT_MS = 6e4;
41435
41435
  const STATUS_INTERVAL_MS = 1e3;
41436
41436
  const ACTIVE_THRESHOLD_MS = 2e3;
41437
- const logDir$1 = node_path.join(node_path.dirname(new URL(require("url").pathToFileURL(__filename).href).pathname.replace(/^\/([A-Z]:)/i, "$1")), "..", "logs");
41438
41437
  function ptyLog(level, ...args) {
41439
- try {
41440
- node_fs.mkdirSync(logDir$1, { recursive: true });
41441
- const ts = (/* @__PURE__ */ new Date()).toISOString();
41442
- const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
41443
- node_fs.appendFileSync(node_path.join(logDir$1, `dashboard-${ts.slice(0, 10)}.log`), `[${ts}] [${level}] [pty-manager] ${msg}\n`);
41444
- } catch {}
41438
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
41439
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
41440
+ console.error(`[${ts}] [${level}] [pty-manager] ${msg}`);
41445
41441
  }
41446
41442
  var PtyManager = class PtyManager {
41447
41443
  static instance = null;
@@ -41466,7 +41462,7 @@ var PtyManager = class PtyManager {
41466
41462
  ptyLog("INFO", "Killing existing session before spawn");
41467
41463
  this.kill();
41468
41464
  }
41469
- const shell = process.platform === "win32" ? "claude.cmd" : "claude";
41465
+ const shell = this.resolveClaudePath();
41470
41466
  const args = [];
41471
41467
  if (opts.skipPermissions) args.push("--dangerously-skip-permissions");
41472
41468
  ptyLog("INFO", `Spawning: shell=${shell}, args=${JSON.stringify(args)}, cwd=${opts.cwd}, cols=${opts.cols ?? 120}, rows=${opts.rows ?? 30}`);
@@ -41572,6 +41568,26 @@ var PtyManager = class PtyManager {
41572
41568
  isAvailable() {
41573
41569
  return pty !== null;
41574
41570
  }
41571
+ resolveClaudePath() {
41572
+ if (process.platform !== "win32") return "claude";
41573
+ const { execSync } = require("child_process");
41574
+ for (const name of [
41575
+ "claude.exe",
41576
+ "claude.cmd",
41577
+ "claude"
41578
+ ]) try {
41579
+ const first = execSync(`where ${name}`, {
41580
+ encoding: "utf8",
41581
+ timeout: 5e3
41582
+ }).trim().split(/\r?\n/)[0];
41583
+ if (first) {
41584
+ ptyLog("INFO", `Resolved claude path: ${first}`);
41585
+ return first;
41586
+ }
41587
+ } catch {}
41588
+ ptyLog("WARN", "Could not resolve claude path, falling back to \"claude\"");
41589
+ return "claude";
41590
+ }
41575
41591
  broadcastToClients(message) {
41576
41592
  const data = JSON.stringify(message);
41577
41593
  for (const client of this.connectedClients) if (client.readyState === import_websocket.default.OPEN) client.send(data);
@@ -41596,8 +41612,7 @@ var PtyManager = class PtyManager {
41596
41612
 
41597
41613
  //#endregion
41598
41614
  //#region src/server.ts
41599
- const dashboardDir = node_path.dirname(new URL(require("url").pathToFileURL(__filename).href).pathname.replace(/^\/([A-Z]:)/i, "$1"));
41600
- const logDir = node_path.join(dashboardDir, "logs");
41615
+ const logDir = node_path.join(__dirname, "logs");
41601
41616
  node_fs.mkdirSync(logDir, { recursive: true });
41602
41617
  const logFile = node_path.join(logDir, `dashboard-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.log`);
41603
41618
  const logStream = node_fs.createWriteStream(logFile, { flags: "a" });
@@ -41707,7 +41722,7 @@ function setupWatcher(cwd, wss) {
41707
41722
  function parseRoadmap(cwd) {
41708
41723
  const roadmapPath = node_path.join(cwd, ".planning", "ROADMAP.md");
41709
41724
  if (!node_fs.existsSync(roadmapPath)) return null;
41710
- const content = node_fs.readFileSync(roadmapPath, "utf-8");
41725
+ const content = node_fs.readFileSync(roadmapPath, "utf-8").replace(/\r\n/g, "\n");
41711
41726
  const phasesDir = node_path.join(cwd, ".planning", "phases");
41712
41727
  const phasePattern = (0, import_dist.getPhasePattern)();
41713
41728
  const phases = [];
@@ -41789,7 +41804,7 @@ function parseRoadmap(cwd) {
41789
41804
  function parseState(cwd) {
41790
41805
  const statePath = node_path.join(cwd, ".planning", "STATE.md");
41791
41806
  if (!node_fs.existsSync(statePath)) return null;
41792
- const content = node_fs.readFileSync(statePath, "utf-8");
41807
+ const content = node_fs.readFileSync(statePath, "utf-8").replace(/\r\n/g, "\n");
41793
41808
  const position = (0, import_dist.stateExtractField)(content, "Current Position") || (0, import_dist.stateExtractField)(content, "Phase");
41794
41809
  const lastActivity = (0, import_dist.stateExtractField)(content, "Last activity") || (0, import_dist.stateExtractField)(content, "Last Activity");
41795
41810
  const currentPhase = (0, import_dist.stateExtractField)(content, "Current Phase") || (0, import_dist.stateExtractField)(content, "Phase");
@@ -41870,7 +41885,7 @@ function parsePhaseDetail(cwd, phaseId) {
41870
41885
  const plans = [];
41871
41886
  for (const planFileName of planFileNames) {
41872
41887
  const planPath = node_path.join(phaseDir, planFileName);
41873
- const content = node_fs.readFileSync(planPath, "utf-8");
41888
+ const content = node_fs.readFileSync(planPath, "utf-8").replace(/\r\n/g, "\n");
41874
41889
  const frontmatter = (0, import_dist.extractFrontmatter)(content);
41875
41890
  const tasks = [];
41876
41891
  const taskRegex = /<task\s+type="([^"]*)"[^>]*>\s*<name>([^<]+)<\/name>([\s\S]*?)<\/task>/g;
@@ -41976,7 +41991,7 @@ app.patch("/api/roadmap", (req, res) => {
41976
41991
  if (!node_fs.existsSync(roadmapPath)) return res.status(404).json({ error: "ROADMAP.md not found" });
41977
41992
  const { phaseNumber, checked } = req.body;
41978
41993
  if (!phaseNumber || checked === void 0) return res.status(400).json({ error: "phaseNumber and checked are required" });
41979
- let content = node_fs.readFileSync(roadmapPath, "utf-8");
41994
+ let content = node_fs.readFileSync(roadmapPath, "utf-8").replace(/\r\n/g, "\n");
41980
41995
  const escapedNum = phaseNumber.replace(".", "\\.");
41981
41996
  const pattern = new RegExp(`(-\\s*\\[)(x| )(\\]\\s*.*Phase\\s+${escapedNum})`, "i");
41982
41997
  if (!content.match(pattern)) return res.status(404).json({ error: `Phase ${phaseNumber} checkbox not found in ROADMAP.md` });
@@ -42000,7 +42015,7 @@ app.patch("/api/state", (req, res) => {
42000
42015
  if (!isWithinPlanning(projectCwd, ".planning/STATE.md")) return res.status(400).json({ error: "Invalid path" });
42001
42016
  const { field, value } = req.body;
42002
42017
  if (!field || value === void 0) return res.status(400).json({ error: "field and value are required" });
42003
- const updated = (0, import_dist.stateReplaceField)(node_fs.readFileSync(statePath, "utf-8"), field, value);
42018
+ const updated = (0, import_dist.stateReplaceField)(node_fs.readFileSync(statePath, "utf-8").replace(/\r\n/g, "\n"), field, value);
42004
42019
  if (!updated) return res.status(404).json({ error: `Field "${field}" not found in STATE.md` });
42005
42020
  suppressPath(statePath);
42006
42021
  node_fs.writeFileSync(statePath, updated, "utf-8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maxsimcli",
3
- "version": "2.5.3",
3
+ "version": "2.5.5",
4
4
  "private": false,
5
5
  "description": "A meta-prompting, context engineering and spec-driven development system for Claude Code, OpenCode, Gemini and Codex by MayStudios.",
6
6
  "bin": {