@xyrlan/mnemo 0.14.0 → 0.15.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/lib/bootstrap.js CHANGED
@@ -5,7 +5,7 @@ const { probeOnPath } = require("./detect");
5
5
  const { resolveMnemoBinary } = require("./runMnemo");
6
6
 
7
7
 
8
- const PIN_SPEC = "mnemo-claude>=0.14,<0.15";
8
+ const PIN_SPEC = "mnemo-claude>=0.15,<0.16";
9
9
 
10
10
 
11
11
  function buildInstallCmd(installer, spec = PIN_SPEC) {
@@ -38,8 +38,14 @@ function isAlreadyInstalled(resolverFn = resolveMnemoBinary) {
38
38
  }
39
39
 
40
40
 
41
- function runShell(cmd, { quiet = false } = {}) {
42
- const result = spawnSync("sh", ["-c", cmd], { stdio: quiet ? "ignore" : "inherit" });
41
+ function runShell(cmd, { quiet = false, platform = process.platform } = {}) {
42
+ const isWin = platform === "win32";
43
+ const shellCmd = isWin ? "cmd.exe" : "sh";
44
+ const shellArgs = isWin ? ["/d", "/s", "/c", cmd] : ["-c", cmd];
45
+ const result = spawnSync(shellCmd, shellArgs, {
46
+ stdio: quiet ? "ignore" : "inherit",
47
+ windowsHide: true,
48
+ });
43
49
  return result.status === null ? 1 : result.status;
44
50
  }
45
51
 
@@ -52,11 +58,40 @@ function verifyOnPath() {
52
58
  }
53
59
 
54
60
 
55
- function pathFixHint(installer) {
61
+ function _userBaseFromPython(execFn) {
62
+ // `python3 -m site --user-base` is authoritative across platforms:
63
+ // Linux → ~/.local
64
+ // macOS → ~/Library/Python/<X.Y> (NOT ~/.local — common gotcha)
65
+ // Win → %APPDATA%\Python
66
+ // Returns the bin/Scripts dir, or null on failure (caller falls back to
67
+ // platform heuristics).
68
+ try {
69
+ const out = execFn("python3 -m site --user-base").trim();
70
+ if (!out) return null;
71
+ return out;
72
+ } catch (_e) {
73
+ return null;
74
+ }
75
+ }
76
+
77
+
78
+ function pathFixHint(installer, {
79
+ platform = process.platform,
80
+ execFn = (cmd) => execSync(cmd, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }),
81
+ } = {}) {
56
82
  if (installer === "pipx") return "Run `pipx ensurepath` and reopen your shell.";
57
83
  if (installer === "uv") return "Run `uv tool update-shell` and reopen your shell.";
58
84
  if (installer === "pip-user") {
59
- if (process.platform === "win32") return "Add %APPDATA%\\Python\\Scripts to PATH.";
85
+ if (platform === "win32") {
86
+ const base = _userBaseFromPython(execFn);
87
+ if (base) return `Add ${base}\\Scripts to PATH.`;
88
+ return "Add %APPDATA%\\Python\\Scripts to PATH.";
89
+ }
90
+ const base = _userBaseFromPython(execFn);
91
+ if (base) return `Add ${base}/bin to PATH (e.g. via your shell profile).`;
92
+ if (platform === "darwin") {
93
+ return "Add ~/Library/Python/<X.Y>/bin to PATH (run `python3 -m site --user-base` to find the right X.Y).";
94
+ }
60
95
  return "Add ~/.local/bin to PATH (e.g. via your shell profile).";
61
96
  }
62
97
  return "Re-open your shell to refresh PATH.";
package/lib/runInstall.js CHANGED
@@ -15,7 +15,7 @@ const { buildInitArgs, runMnemo } = require("./runMnemo");
15
15
  const m = require("./messages");
16
16
 
17
17
 
18
- function parseFlags(argv) {
18
+ function parseFlags(argv, { warn = (msg) => process.stderr.write(`warning: ${msg}\n`) } = {}) {
19
19
  const flags = { scope: null, vaultRoot: null, upgrade: false, yes: false, quiet: false };
20
20
  for (let i = 0; i < argv.length; i++) {
21
21
  const a = argv[i];
@@ -24,7 +24,18 @@ function parseFlags(argv) {
24
24
  else if (a === "--upgrade") flags.upgrade = true;
25
25
  else if (a === "--yes" || a === "-y") flags.yes = true;
26
26
  else if (a === "--quiet") flags.quiet = true;
27
- else if (a === "--vault-root") { flags.vaultRoot = argv[++i]; }
27
+ else if (a === "--vault-root") {
28
+ const next = argv[i + 1];
29
+ if (!next || next.startsWith("--")) {
30
+ warn(`--vault-root requires a path argument; ignoring.`);
31
+ } else {
32
+ flags.vaultRoot = next;
33
+ i++;
34
+ }
35
+ }
36
+ else if (a && a.startsWith("-")) {
37
+ warn(`unknown flag: ${a}`);
38
+ }
28
39
  }
29
40
  return flags;
30
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyrlan/mnemo",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "One-command installer for mnemo (the Obsidian that populates itself).",
5
5
  "bin": {
6
6
  "mnemo": "bin/mnemo.js"
@@ -18,7 +18,7 @@
18
18
  "access": "public"
19
19
  },
20
20
  "scripts": {
21
- "test": "node --test test/"
21
+ "test": "node --test test/*.test.js"
22
22
  },
23
23
  "files": [
24
24
  "bin/",