@zerwiz/ymir 0.1.8 → 0.1.9
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 +42 -0
- package/bin/app-lib.sh +58 -0
- package/bin/design-check.sh +12 -1
- package/bin/design-icon.sh +15 -0
- package/bin/desktop-place.sh +14 -1
- package/bin/eir-doctor.sh +12 -1
- package/bin/hall-snapshot.sh +12 -1
- package/bin/sessrumnir-ensure.sh +12 -1
- package/bin/sessrumnir-sync.sh +12 -1
- package/bin/sessrumnir.sh +12 -1
- package/bin/smidja-lib.sh +14 -13
- package/bin/ymir-install.sh +7 -3
- package/bin/ymir-invite.sh +14 -3
- package/bin/ymir-style.sh +13 -0
- package/package.json +1 -1
- package/scripts/electron.sh +15 -2
- package/scripts/start.sh +18 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,46 @@
|
|
|
1
1
|
|
|
2
|
+
## 2026-09-17 — 0.1.9: both shapes reach the registry
|
|
3
|
+
|
|
4
|
+
- **`ymir raise` works on a packaged install.** 0.1.8 shipped before the resolver,
|
|
5
|
+
so a user who installed from npm hit `cd …/apps/hlidskjalf: No such file or
|
|
6
|
+
directory` — every package had arrived, and eighteen scripts were looking in the
|
|
7
|
+
clone's `apps/`. `bin/app-lib.sh` resolves a surface in either shape now.
|
|
8
|
+
- **A clone and a package are one tree to the scripts.** Proven against both: the
|
|
9
|
+
five surfaces resolve from `/home/zerwiz/Ymir` and from an npm-installed
|
|
10
|
+
package, and `ymir raise` against a packaged tree fetches the app's
|
|
11
|
+
dependencies, raises the gate API, starts Nornir cron, and brings up Bifrost and
|
|
12
|
+
the well.
|
|
13
|
+
- **The patience words** — `style_patience` — open the installer's long chain and
|
|
14
|
+
the raise path's build, so a long hour says what it is doing.
|
|
15
|
+
|
|
16
|
+
## 2026-09-17 — both shapes: a clone and an npm install, and the patience words
|
|
17
|
+
|
|
18
|
+
- **`ymir raise` failed on a packaged install** — and the reason was ours, not
|
|
19
|
+
npm's. Every package had arrived; the scripts looked for the apps in the clone's
|
|
20
|
+
`apps/`, where a package keeps nothing. `scripts/start.sh` died on
|
|
21
|
+
`cd …/apps/hlidskjalf: No such file or directory`. **Eighteen files assumed the
|
|
22
|
+
clone's layout.**
|
|
23
|
+
- **One resolver, both shapes:** `bin/app-lib.sh` — `apps/<surface>` in a clone,
|
|
24
|
+
`node_modules/@zerwiz/<package>` in a package, with the surface→package map
|
|
25
|
+
(`smidja` → `@zerwiz/smidja-factory`). Wired into the raise path, the windows,
|
|
26
|
+
the invite door, the seat-hall, Eir, the icons, the placement, the hall snapshot
|
|
27
|
+
and the installer's own SPA and shell steps. `bin/smidja-lib.sh` delegates to it
|
|
28
|
+
now, so there is one truth about where things live.
|
|
29
|
+
- **Proven in both trees**: all five surfaces resolve from `/home/zerwiz/Ymir`
|
|
30
|
+
(a clone) and from an npm-installed package. And `ymir raise` run against the
|
|
31
|
+
packaged tree no longer dies — it fetches the app's dependencies, raises the
|
|
32
|
+
gate API, **starts Nornir cron**, and brings up Bifrost and the well.
|
|
33
|
+
- **A trap worth naming:** `printf -v <name>` writes to the *function's* scope, so
|
|
34
|
+
a helper whose scratch variable shares the caller's requested name swallows the
|
|
35
|
+
answer. Every scratch name in the resolvers is function-prefixed for that
|
|
36
|
+
reason.
|
|
37
|
+
- **The patience words.** A long install should say what it is doing and why it
|
|
38
|
+
takes a while. `style_patience` — the cloth's own line — now opens the
|
|
39
|
+
installer's long chain and the raise path's build:
|
|
40
|
+
*much moves · the halls are being set right · this hour is long, and nothing of
|
|
41
|
+
yours is lost in it — roots come home, shapes are re-cut, names are set true
|
|
42
|
+
again. Your patience is noted, and it is earned.*
|
|
43
|
+
|
|
2
44
|
## 2026-09-17 — 0.1.8: the day's work reaches npm
|
|
3
45
|
|
|
4
46
|
- **The doors.** `ymir` now carries the operator's verbs, each named for the
|
package/bin/app-lib.sh
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# app-lib.sh — where an app actually lives.
|
|
3
|
+
#
|
|
4
|
+
# Two installs, one name. In a clone the apps sit at `apps/<surface>` (the
|
|
5
|
+
# registry's `repo: apps/<path>` block clones them there). In a packaged install
|
|
6
|
+
# the tree has no `apps/` at all: each surface arrives as a dependency, at
|
|
7
|
+
# `node_modules/@zerwiz/<package>`.
|
|
8
|
+
#
|
|
9
|
+
# surface package
|
|
10
|
+
# ---------------- ---------------------
|
|
11
|
+
# hlidskjalf hlidskjalf
|
|
12
|
+
# hlidskjalf-mobile hlidskjalf-mobile
|
|
13
|
+
# odrerir odrerir
|
|
14
|
+
# sessrumnir sessrumnir
|
|
15
|
+
# smidja smidja-factory
|
|
16
|
+
#
|
|
17
|
+
# A surface's name is not always its package's name — and a path is not a name at
|
|
18
|
+
# all. Every script that needs an app resolves it HERE, so the two shapes can
|
|
19
|
+
# never disagree (Rule 07). Source-safe; functions only.
|
|
20
|
+
#
|
|
21
|
+
# app_dir <surface> <result-var> the app's directory (empty + exit 1 if absent)
|
|
22
|
+
# app_pkg <surface> the npm package name for that surface
|
|
23
|
+
set -u
|
|
24
|
+
|
|
25
|
+
app_pkg() { # <surface> → the package name npm serves
|
|
26
|
+
case "${1-}" in
|
|
27
|
+
smidja) printf '%s' 'smidja-factory' ;;
|
|
28
|
+
*) printf '%s' "${1-}" ;;
|
|
29
|
+
esac
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
app_dir() { # <surface> <result-var> — a clone's apps/<x>, else the package
|
|
33
|
+
# Scratch names are function-prefixed on purpose: `printf -v <name>` writes to THIS
|
|
34
|
+
# function's scope, so a scratch variable sharing the caller's requested name
|
|
35
|
+
# would swallow the answer (a caller asking for "c" or "root" would get nothing).
|
|
36
|
+
local _apd_surface="${1-}" _apd_rv="${2-}" _apd_root _apd_pkg _apd_c
|
|
37
|
+
[ -n "$_apd_surface" ] && [ -n "$_apd_rv" ] || return 2
|
|
38
|
+
_apd_root="${YMIR_ROOT_DIR:-}"
|
|
39
|
+
if [ -z "$_apd_root" ]; then _apd_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"; fi
|
|
40
|
+
_apd_pkg="$(app_pkg "$_apd_surface")"
|
|
41
|
+
for _apd_c in "$_apd_root/apps/$_apd_surface" "$_apd_root/node_modules/@zerwiz/$_apd_pkg"; do
|
|
42
|
+
[ -d "$_apd_c" ] && { printf -v "$_apd_rv" '%s' "$_apd_c"; return 0; }
|
|
43
|
+
done
|
|
44
|
+
printf -v "$_apd_rv" '%s' ""
|
|
45
|
+
return 1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Some callers need the directory a mint writes INTO (an app's public/, electron/,
|
|
49
|
+
# dist/…). A packaged app is read-only in spirit, so the clone's apps/ is preferred
|
|
50
|
+
# when it exists; otherwise the package is the only truth there is.
|
|
51
|
+
app_root() { # <result-var> — where apps live in THIS tree
|
|
52
|
+
local _apr_rv="${1-}" _apr_root
|
|
53
|
+
[ -n "$_apr_rv" ] || return 2
|
|
54
|
+
_apr_root="${YMIR_ROOT_DIR:-}"
|
|
55
|
+
if [ -z "$_apr_root" ]; then _apr_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"; fi
|
|
56
|
+
if [ -d "$_apr_root/apps" ]; then printf -v "$_apr_rv" '%s' "$_apr_root/apps"; return 0; fi
|
|
57
|
+
printf -v "$_apr_rv" '%s' "$_apr_root/node_modules/@zerwiz"
|
|
58
|
+
}
|
package/bin/design-check.sh
CHANGED
|
@@ -19,8 +19,19 @@ set -u
|
|
|
19
19
|
VERSION="1.0.0"
|
|
20
20
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
21
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
22
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
23
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
24
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
25
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
26
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
27
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
28
|
+
done
|
|
29
|
+
unset _ya _yac
|
|
30
|
+
fi
|
|
31
|
+
app_dir sessrumnir APP_SESSRUMNIR || APP_SESSRUMNIR=""
|
|
32
|
+
|
|
22
33
|
TOKENS="$ROOT/midgard/design-system/tokens.css"
|
|
23
|
-
SEEDS="$
|
|
34
|
+
SEEDS="$APP_SESSRUMNIR/src/renderer/src/themes/fensalir.json"
|
|
24
35
|
|
|
25
36
|
case "${1-}" in
|
|
26
37
|
-v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;;
|
package/bin/design-icon.sh
CHANGED
|
@@ -16,6 +16,21 @@ set -u
|
|
|
16
16
|
VERSION="1.0.0"
|
|
17
17
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
18
18
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
19
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
20
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
21
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
22
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
24
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
25
|
+
done
|
|
26
|
+
unset _ya _yac
|
|
27
|
+
fi
|
|
28
|
+
app_dir hlidskjalf APP_HLIDSKJALF || APP_HLIDSKJALF=""
|
|
29
|
+
app_dir hlidskjalf-mobile APP_HLIDSKJALF_MOBILE || APP_HLIDSKJALF_MOBILE=""
|
|
30
|
+
app_dir odrerir APP_ODRERIR || APP_ODRERIR=""
|
|
31
|
+
app_dir sessrumnir APP_SESSRUMNIR || APP_SESSRUMNIR=""
|
|
32
|
+
app_dir smidja-factory APP_SMIDJA_FACTORY || APP_SMIDJA_FACTORY=""
|
|
33
|
+
|
|
19
34
|
ICONS="$ROOT/midgard/design-system/icons"
|
|
20
35
|
STONE="#0e0c09"
|
|
21
36
|
|
package/bin/desktop-place.sh
CHANGED
|
@@ -29,6 +29,19 @@ fi
|
|
|
29
29
|
VERSION="1.0.0"
|
|
30
30
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
31
31
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
32
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
33
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
34
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
35
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
36
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
37
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
38
|
+
done
|
|
39
|
+
unset _ya _yac
|
|
40
|
+
fi
|
|
41
|
+
app_dir hlidskjalf APP_HLIDSKJALF || APP_HLIDSKJALF=""
|
|
42
|
+
app_dir sessrumnir APP_SESSRUMNIR || APP_SESSRUMNIR=""
|
|
43
|
+
app_dir odrerir APP_ODRERIR || APP_ODRERIR=""
|
|
44
|
+
|
|
32
45
|
HYPR_DIR="$HOME/.config/hypr"
|
|
33
46
|
RULE_FILE="$HYPR_DIR/ymir-desktops.lua"
|
|
34
47
|
# The three Ymir surfaces, in the order they should claim desktops.
|
|
@@ -46,7 +59,7 @@ CLASS_odrerir="ymir-odrerir"
|
|
|
46
59
|
# not a branch of this one.
|
|
47
60
|
install_entries() {
|
|
48
61
|
local dst="$HOME/.local/share/applications" n=0
|
|
49
|
-
local dirs=("$
|
|
62
|
+
local dirs=("$APP_HLIDSKJALF/electron" "$APP_SESSRUMNIR/resources" "$APP_ODRERIR/electron")
|
|
50
63
|
if [ "$(ymir_os)" != linux ] && [ "$(ymir_os)" != wsl ]; then
|
|
51
64
|
printf 'skip: desktop entries are Omarchy/Linux-shaped; this host is %s\n' "$(ymir_os)" >&2
|
|
52
65
|
return 0
|
package/bin/eir-doctor.sh
CHANGED
|
@@ -22,6 +22,17 @@ STATE="${BROKK_STATE_OVERRIDE:-$YMIR_HOME/state}"
|
|
|
22
22
|
# stdout stay the data (bin/ymir-style.sh).
|
|
23
23
|
if [ -z "${YMIR_STYLE_LOADED:-}" ]; then . "$SCRIPT_DIR/ymir-style.sh"; YMIR_STYLE_LOADED=1; fi
|
|
24
24
|
style_init
|
|
25
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
26
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
27
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
28
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
29
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
30
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
31
|
+
done
|
|
32
|
+
unset _ya _yac
|
|
33
|
+
fi
|
|
34
|
+
app_dir sessrumnir APP_SESSRUMNIR || APP_SESSRUMNIR=""
|
|
35
|
+
|
|
25
36
|
|
|
26
37
|
case "${1-}" in -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;; -h|--help|"") sed -n '2,15p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; esac
|
|
27
38
|
ACTION="${1:-check}"; shift || true
|
|
@@ -154,7 +165,7 @@ detail() { # <name> -> one short fact
|
|
|
154
165
|
herdr) "have herdr && herdr --version 2>/dev/null | head -1 || echo 'herdr absent'" ;;
|
|
155
166
|
a2abridge) "have a2abridge && a2abridge --version 2>/dev/null | head -1 || echo 'engine absent'" ;;
|
|
156
167
|
hermes) "have hermes && echo present || echo absent" ;;
|
|
157
|
-
sessrumnir)"[ -d $
|
|
168
|
+
sessrumnir)"[ -d $APP_SESSRUMNIR/out ] && echo built || echo 'not built'" ;;
|
|
158
169
|
well) "echo 'engram :4602'" ;;
|
|
159
170
|
mcp) "echo 'a2abridge + engram'" ;;
|
|
160
171
|
lock) "cat $STATE/.lock 2>/dev/null | tr -d '[:space:]' | sed 's/^/pid /' || echo none" ;;
|
package/bin/hall-snapshot.sh
CHANGED
|
@@ -16,6 +16,17 @@
|
|
|
16
16
|
# (the Live Hall's own deck; the merged public site takes it from its build).
|
|
17
17
|
set -u
|
|
18
18
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
19
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
20
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
21
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
22
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
24
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
25
|
+
done
|
|
26
|
+
unset _ya _yac
|
|
27
|
+
fi
|
|
28
|
+
app_dir odrerir APP_ODRERIR || APP_ODRERIR=""
|
|
29
|
+
|
|
19
30
|
ROOT="${BROKK_ROOT_OVERRIDE:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
20
31
|
|
|
21
32
|
# The operator's settings and secrets live in the home they chose, never in the
|
|
@@ -37,7 +48,7 @@ hoard_data_dir YMIR_DATA_DIR
|
|
|
37
48
|
# runtime state belong to the home the operator chose at installation, never in
|
|
38
49
|
# the tree — a packaged install replaces its tree on upgrade (Rule 04).
|
|
39
50
|
STATE="${BROKK_STATE_OVERRIDE:-$YMIR_STATE_DIR}"
|
|
40
|
-
OUT="${1:-$
|
|
51
|
+
OUT="${1:-$APP_ODRERIR/public/livehall.json}"
|
|
41
52
|
|
|
42
53
|
runes_file="${BROKK_RUNES_FILE:-${YMIR_HOME:-$HOME/Documents/Ymir}/hodd/memory/runes_audit.md}"
|
|
43
54
|
PROJECTS_FILE="${YMIR_HOME:-$HOME/Documents/Ymir}/hodd/identity/projects.yaml"
|
package/bin/sessrumnir-ensure.sh
CHANGED
|
@@ -20,7 +20,18 @@ set -u
|
|
|
20
20
|
VERSION="1.0.0"
|
|
21
21
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
22
22
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
23
|
-
|
|
23
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
24
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
25
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
26
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
27
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
28
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
29
|
+
done
|
|
30
|
+
unset _ya _yac
|
|
31
|
+
fi
|
|
32
|
+
app_dir sessrumnir APP_SESSRUMNIR || APP_SESSRUMNIR=""
|
|
33
|
+
|
|
34
|
+
APP="$APP_SESSRUMNIR"
|
|
24
35
|
|
|
25
36
|
case "${1-}" in -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;; -h|--help|"") sed -n '2,16p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; esac
|
|
26
37
|
CMD="${1-}"; shift || true
|
package/bin/sessrumnir-sync.sh
CHANGED
|
@@ -24,7 +24,18 @@
|
|
|
24
24
|
set -euo pipefail
|
|
25
25
|
|
|
26
26
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
27
|
-
|
|
27
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
28
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
29
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
30
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
31
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
32
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
33
|
+
done
|
|
34
|
+
unset _ya _yac
|
|
35
|
+
fi
|
|
36
|
+
app_dir sessrumnir APP_SESSRUMNIR || APP_SESSRUMNIR=""
|
|
37
|
+
|
|
38
|
+
APP="$APP_SESSRUMNIR"
|
|
28
39
|
FORK="$APP/fork"
|
|
29
40
|
UPSTREAM_REPO="${SESSRUMNIR_UPSTREAM:-https://github.com/zerwiz/pi-desktop.git}"
|
|
30
41
|
OWNED_JSON="$FORK/owned.json"
|
package/bin/sessrumnir.sh
CHANGED
|
@@ -14,6 +14,17 @@ set -u
|
|
|
14
14
|
VERSION="1.0.0"
|
|
15
15
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
16
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
17
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
18
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
19
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
20
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
22
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
23
|
+
done
|
|
24
|
+
unset _ya _yac
|
|
25
|
+
fi
|
|
26
|
+
app_dir sessrumnir APP_SESSRUMNIR || APP_SESSRUMNIR=""
|
|
27
|
+
|
|
17
28
|
|
|
18
29
|
# The roots that live OUTSIDE the code tree: this machine's records and the
|
|
19
30
|
# runtime state belong to the home the operator chose at installation, never in
|
|
@@ -27,7 +38,7 @@ if [ -z "${YMIR_HOARD_LIB_LOADED:-}" ]; then
|
|
|
27
38
|
fi
|
|
28
39
|
hoard_state_dir YMIR_STATE_DIR
|
|
29
40
|
hoard_data_dir YMIR_DATA_DIR
|
|
30
|
-
APP="$
|
|
41
|
+
APP="$APP_SESSRUMNIR"
|
|
31
42
|
PID_FILE="$YMIR_STATE_DIR/sessrumnir.pid"
|
|
32
43
|
LOG_FILE="$YMIR_STATE_DIR/sessrumnir.log"
|
|
33
44
|
|
package/bin/smidja-lib.sh
CHANGED
|
@@ -20,20 +20,21 @@ SMIDJA_SURFACE="smidja"
|
|
|
20
20
|
SMIDJA_PACKAGE="smidja-factory"
|
|
21
21
|
|
|
22
22
|
smidja_factory_dir() { # <result-var> — the smithy's directory, or empty
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
# The general resolver (bin/app-lib.sh) knows both shapes; the smithy is one
|
|
24
|
+
# surface among them. The old skill symlink is the last resort, and a dangling
|
|
25
|
+
# one is not a home — the visualizer must be readable there.
|
|
26
|
+
local _smd_rv=${1-} _smd_c
|
|
27
|
+
[ -n "$_smd_rv" ] || return 2
|
|
28
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
29
|
+
local _sl; _sl="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
30
|
+
[ -r "$_sl/app-lib.sh" ] && { . "$_sl/app-lib.sh"; YMIR_APP_LIB_LOADED=1; }
|
|
27
31
|
fi
|
|
28
|
-
|
|
29
|
-
"$
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
[ -d "$c/apps/visualizer" ] && { printf -v "$result_var" '%s' "$c"; return 0; }
|
|
35
|
-
done
|
|
36
|
-
printf -v "$result_var" '%s' ""
|
|
32
|
+
if app_dir smidja _smd_c 2>/dev/null && [ -d "$_smd_c/apps/visualizer" ]; then
|
|
33
|
+
printf -v "$_smd_rv" '%s' "$_smd_c"; return 0
|
|
34
|
+
fi
|
|
35
|
+
_smd_c="${YMIR_ROOT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/.agents/skills/$SMIDJA_PACKAGE"
|
|
36
|
+
[ -d "$_smd_c/apps/visualizer" ] && { printf -v "$_smd_rv" '%s' "$_smd_c"; return 0; }
|
|
37
|
+
printf -v "$_smd_rv" '%s' ""
|
|
37
38
|
return 1
|
|
38
39
|
}
|
|
39
40
|
|
package/bin/ymir-install.sh
CHANGED
|
@@ -53,6 +53,8 @@ hoard_local_env YMIR_ENV_FILE
|
|
|
53
53
|
# repo (Rule 04).
|
|
54
54
|
# shellcheck source=bin/hoard-lib.sh
|
|
55
55
|
. "$SCRIPT_DIR/hoard-lib.sh"
|
|
56
|
+
# shellcheck source=bin/app-lib.sh
|
|
57
|
+
. "$SCRIPT_DIR/app-lib.sh"
|
|
56
58
|
ymir_home_root YMIR_HOME
|
|
57
59
|
# Where the smithy's parts live: apps/smidja-factory in a clone, or the
|
|
58
60
|
# @zerwiz/smidja-factory package in an npm install (bin/smidja-lib.sh).
|
|
@@ -585,7 +587,8 @@ step_smidja() {
|
|
|
585
587
|
# Hlidskjalf installs with npm (its own lockfile), not bun, and its API serves the
|
|
586
588
|
# UI from ./dist. Without this step a fresh clone has no SPA and no build.
|
|
587
589
|
step_spa() {
|
|
588
|
-
local app="
|
|
590
|
+
local app; app_dir hlidskjalf app || app=""
|
|
591
|
+
local app_ok="$app"
|
|
589
592
|
[ -d "$app" ] || { add hlidskjalf SKIP "no apps/hlidskjalf"; return 0; }
|
|
590
593
|
if [ "$CHECK" = 0 ]; then
|
|
591
594
|
if ! have npm; then
|
|
@@ -708,8 +711,8 @@ step_desktop() {
|
|
|
708
711
|
fi
|
|
709
712
|
local shell partial=""
|
|
710
713
|
for shell in hlidskjalf odrerir sessrumnir; do
|
|
711
|
-
local dir
|
|
712
|
-
|
|
714
|
+
local dir d
|
|
715
|
+
app_dir "$shell" dir || continue
|
|
713
716
|
d="$(electron_runtime_state "$dir" 2>/dev/null || true)"
|
|
714
717
|
[ "$d" = partial ] && partial="$partial $shell"
|
|
715
718
|
done
|
|
@@ -819,6 +822,7 @@ step_panes() {
|
|
|
819
822
|
|
|
820
823
|
# Ask before touching the machine; --check only previews and never asks.
|
|
821
824
|
[ "$CHECK" = 0 ] && confirm_install
|
|
825
|
+
[ "$CHECK" = 0 ] && style_patience "the halls are being stood up for the first time"
|
|
822
826
|
|
|
823
827
|
step_panes; step_prereqs; step_home; step_tree; step_apps; step_engines; step_models; step_hermes; step_sessrumnir; step_backend; step_host; step_sandbox; step_memory; step_smidja; step_spa; step_omarchy; step_loaders; step_gates; step_marks
|
|
824
828
|
# Migrations MOVE private data — that is a write, and `--check` promises none.
|
package/bin/ymir-invite.sh
CHANGED
|
@@ -16,8 +16,19 @@
|
|
|
16
16
|
set -euo pipefail
|
|
17
17
|
|
|
18
18
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
20
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
21
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
22
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
24
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
25
|
+
done
|
|
26
|
+
unset _ya _yac
|
|
27
|
+
fi
|
|
28
|
+
app_dir hlidskjalf APP_HLIDSKJALF || APP_HLIDSKJALF=""
|
|
29
|
+
|
|
30
|
+
MODULE="$APP_HLIDSKJALF/server/accounts.ts"
|
|
31
|
+
STORE="$APP_HLIDSKJALF/server/accounts.ts" # absolute: one definition of an account, wherever this is run from
|
|
21
32
|
|
|
22
33
|
die() { printf 'ymir-invite: %s\n' "$1" >&2; exit 1; }
|
|
23
34
|
|
|
@@ -25,7 +36,7 @@ command -v bun >/dev/null 2>&1 || die "bun is required (bin/ymir-install.sh inst
|
|
|
25
36
|
|
|
26
37
|
# A tiny bun program per action — the module is the single source of truth.
|
|
27
38
|
accounts() {
|
|
28
|
-
( cd "$
|
|
39
|
+
( cd "$APP_HLIDSKJALF" && bun -e "$1" )
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
[ -f "$MODULE" ] || die "the account store module is missing: $MODULE"
|
package/bin/ymir-style.sh
CHANGED
|
@@ -95,6 +95,19 @@ style_line() { # <state> <name> <detail> — the one line per thing
|
|
|
95
95
|
|
|
96
96
|
style_heading() { printf '\n%s%s%s\n' "$C_BRONZE" "$1" "$C_OFF" >&2; }
|
|
97
97
|
|
|
98
|
+
# For a long hour: say what is happening and why it takes a while. A user who
|
|
99
|
+
# knows the halls are being set right waits; a user watching a silent cursor
|
|
100
|
+
# wonders whether it has broken.
|
|
101
|
+
style_patience() { # [what is being set right]
|
|
102
|
+
local what="${1:-the halls are being set right}"
|
|
103
|
+
printf '\n' >&2
|
|
104
|
+
style_line DO "much moves" "$what"
|
|
105
|
+
style_hint " this hour is long, and nothing of yours is lost in it —"
|
|
106
|
+
style_hint " roots come home, shapes are re-cut, names are set true again."
|
|
107
|
+
style_hint " Your patience is noted, and it is earned."
|
|
108
|
+
printf '\n' >&2
|
|
109
|
+
}
|
|
110
|
+
|
|
98
111
|
# The ending: what stands, then exactly what to type next. Every CLI deserves
|
|
99
112
|
# to leave the operator with the next step and nothing else to guess.
|
|
100
113
|
style_next() { # one command per line, as "verb — what it does"
|
package/package.json
CHANGED
package/scripts/electron.sh
CHANGED
|
@@ -26,6 +26,19 @@ fi
|
|
|
26
26
|
VERSION="1.1.0"
|
|
27
27
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
28
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
29
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
30
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
31
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
32
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
33
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
34
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
35
|
+
done
|
|
36
|
+
unset _ya _yac
|
|
37
|
+
fi
|
|
38
|
+
app_dir hlidskjalf APP_HLIDSKJALF || APP_HLIDSKJALF=""
|
|
39
|
+
app_dir odrerir APP_ODRERIR || APP_ODRERIR=""
|
|
40
|
+
app_dir sessrumnir APP_SESSRUMNIR || APP_SESSRUMNIR=""
|
|
41
|
+
|
|
29
42
|
|
|
30
43
|
# The roots that live OUTSIDE the code tree: this machine's records and the
|
|
31
44
|
# runtime state belong to the home the operator chose at installation, never in
|
|
@@ -39,8 +52,8 @@ if [ -z "${YMIR_HOARD_LIB_LOADED:-}" ]; then
|
|
|
39
52
|
fi
|
|
40
53
|
hoard_state_dir YMIR_STATE_DIR
|
|
41
54
|
hoard_data_dir YMIR_DATA_DIR
|
|
42
|
-
APP="$
|
|
43
|
-
Odrerir_app="$
|
|
55
|
+
APP="$APP_HLIDSKJALF"
|
|
56
|
+
Odrerir_app="$APP_ODRERIR"
|
|
44
57
|
NO_INSTALL=0
|
|
45
58
|
VIEW="${YMIR_DESKTOP_VIEW:-hlidskjalf}"
|
|
46
59
|
VIEWS=(hlidskjalf smidja odrerir)
|
package/scripts/start.sh
CHANGED
|
@@ -17,6 +17,21 @@ if [ -z "${YMIR_PLATFORM_LOADED:-}" ]; then
|
|
|
17
17
|
fi
|
|
18
18
|
|
|
19
19
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
20
|
+
# The cloth (bin/ymir-style.sh) — colour and words for the human watching.
|
|
21
|
+
if [ -z "${YMIR_STYLE_LOADED:-}" ] && [ -r "$ROOT/bin/ymir-style.sh" ]; then
|
|
22
|
+
. "$ROOT/bin/ymir-style.sh"; YMIR_STYLE_LOADED=1; style_init
|
|
23
|
+
fi
|
|
24
|
+
# Where an app lives: apps/<surface> in a clone, node_modules/@zerwiz/<pkg> in an
|
|
25
|
+
# npm install — both shapes, one resolver (bin/app-lib.sh).
|
|
26
|
+
if [ -z "${YMIR_APP_LIB_LOADED:-}" ]; then
|
|
27
|
+
_ya="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
+
for _yac in "$_ya/app-lib.sh" "$(dirname "$_ya")/bin/app-lib.sh"; do
|
|
29
|
+
[ -r "$_yac" ] && { . "$_yac"; YMIR_APP_LIB_LOADED=1; break; }
|
|
30
|
+
done
|
|
31
|
+
unset _ya _yac
|
|
32
|
+
fi
|
|
33
|
+
app_dir hlidskjalf APP_HLIDSKJALF || APP_HLIDSKJALF=""
|
|
34
|
+
|
|
20
35
|
# Where the smithy's parts live: apps/smidja-factory in a clone, or the
|
|
21
36
|
# @zerwiz/smidja-factory package in an npm install (bin/smidja-lib.sh).
|
|
22
37
|
if [ -z "${YMIR_SMIDJA_LIB_LOADED:-}" ]; then
|
|
@@ -48,7 +63,7 @@ hoard_data_dir YMIR_DATA_DIR
|
|
|
48
63
|
# The roots that live OUTSIDE the code tree: this machine's records and the
|
|
49
64
|
# runtime state belong to the home the operator chose at installation, never in
|
|
50
65
|
# the tree — a packaged install replaces its tree on upgrade (Rule 04).
|
|
51
|
-
APP="$
|
|
66
|
+
APP="$APP_HLIDSKJALF"
|
|
52
67
|
RUN="$ROOT/.run"
|
|
53
68
|
PID_FILE="$RUN/hlidskjalf.pid"
|
|
54
69
|
LOG="$RUN/hlidskjalf.log"
|
|
@@ -80,7 +95,8 @@ else
|
|
|
80
95
|
fi
|
|
81
96
|
|
|
82
97
|
if [[ ! -d "$APP/node_modules" ]]; then
|
|
83
|
-
|
|
98
|
+
style_patience "the seat's own dependencies are being fetched, then the hall is raised"
|
|
99
|
+
echo "Installing dependencies…"
|
|
84
100
|
(cd "$APP" && npm install --no-audit --no-fund)
|
|
85
101
|
fi
|
|
86
102
|
|