@zerwiz/ymir 0.1.31 → 0.1.32

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/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 2026-09-18 — the one-liner writes the PATH first (it never reached .bashrc)
2
+
3
+ - **The bug, exactly:** install.sh passed `"${@:-}"` to npm, which with no arguments is an
4
+ EMPTY argument — npm errored, and the script exited **before** the PATH block. So the
5
+ command was never added to .bashrc, on any machine without it already.
6
+ - **The order is now right:** the PATH is written into the shell files FIRST, then the
7
+ package is installed with a proper argument array — so a failed install still leaves
8
+ the command reachable, and a second run picks up where the first left off.
9
+
1
10
  > **Frozen 2026-09-18.** This file is the historical record and is no longer
2
11
  > written to (Rule 06: a record is never rewritten). New work is recorded as fix
3
12
  > notes — one file per fix, per component — under `docs/fixes/`, written with
package/install.sh ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env bash
2
+ # install.sh — the one-liner. Ymir into the operator's OWN prefix, with PATH set,
3
+ # so `ymir` works in the shell they are standing in and every shell after it.
4
+ #
5
+ # curl -fsSL https://raw.githubusercontent.com/zerwiz/ymir/main/install.sh | bash
6
+ #
7
+ # Why this exists, and why `npm install -g @zerwiz/ymir` alone is not enough: npm
8
+ # puts a global command in its global prefix's bin directory, and on an ordinary
9
+ # machine that directory is not on PATH. The command is installed and the shell
10
+ # cannot see it — the most common "it does not work" in the whole Node ecosystem.
11
+ # This script removes that class of failure:
12
+ #
13
+ # · a prefix the user owns (no sudo, no EACCES on /usr/lib/node_modules)
14
+ # · the export written into the shell's rc, so it survives the session
15
+ # · and then it proves the door: `ymir --version`
16
+ #
17
+ # Env: YMIR_NPM_PREFIX (default ~/.npm-global), YMIR_PKG (default @zerwiz/ymir).
18
+ set -eu
19
+
20
+ PREFIX="${YMIR_NPM_PREFIX:-$HOME/.npm-global}"
21
+ PKG="${YMIR_PKG:-@zerwiz/ymir}"
22
+
23
+ say() { printf '%s\n' "$*" >&2; }
24
+
25
+ command -v npm >/dev/null 2>&1 || {
26
+ say "error: npm is not installed, and this script does not install Node."
27
+ say "help: install Node 20+ (https://nodejs.org), then run this again."
28
+ exit 1
29
+ }
30
+
31
+ # 1. a prefix the user owns — every later install is painless
32
+ mkdir -p "$PREFIX/bin"
33
+ npm config set prefix "$PREFIX" >/dev/null 2>&1 || true
34
+ export PATH="$PREFIX/bin:$PATH"
35
+
36
+ # 2. the PATH FIRST — so a failed install still leaves the command reachable, and
37
+ # the user can simply run it again. (It used to be written after the install,
38
+ # and `"${@:-}"` handed npm an EMPTY argument, so the install failed and the
39
+ # script exited before any shell file was touched: "it never writes to .bashrc".)
40
+ rc_written=""
41
+ for rc in "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.zshrc" "$HOME/.profile"; do
42
+ [ -e "$rc" ] || continue
43
+ if ! grep -q "$PREFIX/bin" "$rc" 2>/dev/null; then
44
+ printf '\n# Ymir — the npm global bin, so `ymir` is found\ncase ":$PATH:" in *":%s/bin:"*) ;; *) export PATH="%s/bin:$PATH" ;; esac\n' "$PREFIX" "$PREFIX" >>"$rc"
45
+ rc_written="$rc_written ${rc##*/}"
46
+ fi
47
+ done
48
+ export PATH="$PREFIX/bin:$PATH"
49
+
50
+ # 3. the package
51
+ say "installing $PKG into $PREFIX …"
52
+ # `@latest` AND --prefer-online: a stale cached `latest` is how an install
53
+ # succeeds while changing nothing, and the user is left on an old build.
54
+ install_args=(-g "$PKG@latest" --prefer-online)
55
+ [ "$#" -gt 0 ] && install_args+=("$@")
56
+ if ! npm install "${install_args[@]}"; then
57
+ say "error: the install failed — see npm's output above."
58
+ say "note: your PATH is already set, so a second run picks up where this left off."
59
+ exit 1
60
+ fi
61
+
62
+
63
+ # 4. the FIRST SETUP — the whole platform, not just a command
64
+ # pi.dev and opencode finish here by running their own onboarding; an installer
65
+ # that stops at a binary leaves the user with a tool that does nothing yet, and
66
+ # with eight things still to go wrong. YMIR_SKIP_SETUP=1 installs the command only.
67
+ if [ "${YMIR_SKIP_SETUP:-0}" != 1 ]; then
68
+ say ""
69
+ say "the first setup — the plan, then the work. This takes a few minutes."
70
+ if ! ymir install --yes; then
71
+ say "warn: the setup did not finish cleanly — nothing is lost; run \`ymir\` again to continue."
72
+ fi
73
+ fi
74
+
75
+ # 5. prove the doors rather than promise them
76
+ if command -v ymir >/dev/null 2>&1; then
77
+ say ""
78
+ say "ymir $(ymir --version 2>/dev/null || printf '?') — installed."
79
+ say "what stands:"
80
+ ymir validate --quiet 2>/dev/null | grep -E "^ \"" | head -12 | sed 's/^/ /' >&2 || true
81
+ say "next: ymir raise # lift the hall (SPA :3888, the board :8437, the windows)"
82
+ say " ymir --help # every door"
83
+ else
84
+ say "error: the package is installed but \`ymir\` is still not on PATH."
85
+ say "help: export PATH=\"$PREFIX/bin:\$PATH\" (then open a new shell)"
86
+ exit 1
87
+ fi
88
+ [ -n "$rc_written" ] && say "PATH written into:$rc_written — open a new shell for other terminals."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerwiz/ymir",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "description": "Ymir — the single-tenant agent operating system. One command: curl -fsSL https://raw.githubusercontent.com/zerwiz/ymir/main/install.sh | bash · or: npx @zerwiz/ymir · or: npm i -g @zerwiz/ymir (if `ymir` is not found, the README has the three-line PATH cure)",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/zerwiz/ymir",
@@ -51,7 +51,8 @@
51
51
  ".cursor/",
52
52
  "assets/",
53
53
  "data/",
54
- "deploy/"
54
+ "deploy/",
55
+ "install.sh"
55
56
  ],
56
57
  "engines": {
57
58
  "node": ">=20"