feat(audit): address batch 4 and finalize script audit
- Implement nomarchy-skill, nomarchy-manual, nomarchy-backup, nomarchy-install - Implement nomarchy-install-docker-dbs (stub) - Port nomarchy-docs-keybindings and nomarchy-docs-scripts to packaged scripts - Add installerVm to flake.nix nixosConfigurations, packages, and apps - Update nomarchy-test-installer to use nix run .#installerVm - Add docker support to virtualization.nix and options.nix - Add glow to script dependencies - Finalize docs/SCRIPTS.md update
This commit is contained in:
6
features/scripts/utils/nomarchy-backup
Executable file
6
features/scripts/utils/nomarchy-backup
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Nomarchy Backup Script
|
||||
# Alias for nomarchy-sync push.
|
||||
|
||||
nomarchy-sync push "$@"
|
||||
110
features/scripts/utils/nomarchy-docs-keybindings
Executable file
110
features/scripts/utils/nomarchy-docs-keybindings
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# nomarchy-docs-keybindings
|
||||
#
|
||||
# Regenerates docs/KEYBINDINGS.md from the Hyprland binding files. Run from the
|
||||
# repo root or anywhere — paths are resolved relative to this script.
|
||||
#
|
||||
# nomarchy-docs-keybindings # write to stdout
|
||||
# nomarchy-docs-keybindings --out docs/KEYBINDINGS.md
|
||||
#
|
||||
# Source files in render order. Each entry is "<repo-relative path>|<title>".
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
sources=(
|
||||
"core/home/config/nomarchy/default/hypr/bindings/utilities.conf|Utilities"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/tiling.conf|Tiling"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf|Tiling (v2)"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/clipboard.conf|Clipboard"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/media.conf|Media keys"
|
||||
"features/desktop/hyprland/config/bindings.conf|Apps & web shortcuts"
|
||||
)
|
||||
|
||||
prettify_key() {
|
||||
case "$1" in
|
||||
code:10) echo "1" ;; code:11) echo "2" ;; code:12) echo "3" ;;
|
||||
code:13) echo "4" ;; code:14) echo "5" ;; code:15) echo "6" ;;
|
||||
code:16) echo "7" ;; code:17) echo "8" ;; code:18) echo "9" ;;
|
||||
code:19) echo "0" ;;
|
||||
XF86AudioRaiseVolume) echo "Volume Up" ;;
|
||||
XF86AudioLowerVolume) echo "Volume Down" ;;
|
||||
XF86AudioMute) echo "Mute" ;;
|
||||
XF86AudioMicMute) echo "Mic Mute" ;;
|
||||
XF86AudioPlay) echo "Play/Pause" ;;
|
||||
XF86AudioStop) echo "Stop" ;;
|
||||
XF86AudioNext) echo "Next Track" ;;
|
||||
XF86AudioPrev) echo "Previous Track" ;;
|
||||
XF86MonBrightnessUp) echo "Brightness Up" ;;
|
||||
XF86MonBrightnessDown) echo "Brightness Down" ;;
|
||||
XF86KbdBrightnessUp) echo "Kbd Brightness Up" ;;
|
||||
XF86KbdBrightnessDown) echo "Kbd Brightness Down" ;;
|
||||
XF86KbdLightOnOff) echo "Kbd Backlight" ;;
|
||||
*) echo "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
trim() { sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//'; }
|
||||
|
||||
render_section() {
|
||||
local file="$1" title="$2"
|
||||
[[ ! -f "$repo_root/$file" ]] && return
|
||||
local rows
|
||||
rows=$(grep -E '^[[:space:]]*bind[a-z]*[[:space:]]*=' "$repo_root/$file" || true)
|
||||
[[ -z "$rows" ]] && return
|
||||
|
||||
local body=""
|
||||
while IFS= read -r line; do
|
||||
# Strip the "bindXXX =" prefix.
|
||||
local rhs="${line#*=}"
|
||||
local mods key desc
|
||||
IFS=',' read -r mods key desc _ <<<"$rhs"
|
||||
mods=$(printf '%s' "${mods:-}" | trim)
|
||||
key=$(printf '%s' "${key:-}" | trim)
|
||||
desc=$(printf '%s' "${desc:-}" | trim)
|
||||
[[ -z "$desc" ]] && continue # skip non-descriptive bindings
|
||||
[[ -z "$mods" ]] && mods="—"
|
||||
key=$(prettify_key "$key")
|
||||
body+=$(printf '| %s | %s | %s |\n' "$mods" "$key" "$desc")
|
||||
body+=$'\n'
|
||||
done <<<"$rows"
|
||||
|
||||
[[ -z "$body" ]] && return
|
||||
|
||||
printf '\n## %s\n\n' "$title"
|
||||
printf '_Source: `%s`_\n\n' "$file"
|
||||
printf '| Modifiers | Key | Action |\n'
|
||||
printf '| --- | --- | --- |\n'
|
||||
printf '%s' "$body"
|
||||
}
|
||||
|
||||
main() {
|
||||
cat <<'HEADER'
|
||||
# Nomarchy Keybindings
|
||||
|
||||
Auto-generated from the Hyprland binding files. **Do not edit by hand.**
|
||||
Re-run the generator after changing any `bindings/*.conf`:
|
||||
|
||||
```bash
|
||||
./bin/utils/nomarchy-docs-keybindings --out docs/KEYBINDINGS.md
|
||||
```
|
||||
|
||||
`SUPER` is the Meta / Win key. `code:NN` keys (X11 digit keycodes) are
|
||||
shown as the digit they correspond to. Media keys (`XF86Audio*`,
|
||||
`XF86MonBrightness*`, …) are prettified.
|
||||
HEADER
|
||||
for entry in "${sources[@]}"; do
|
||||
render_section "${entry%|*}" "${entry#*|}"
|
||||
done
|
||||
}
|
||||
|
||||
out=""
|
||||
if [[ "${1:-}" == "--out" ]]; then
|
||||
out="${2:?--out needs a path}"; shift 2
|
||||
fi
|
||||
if [[ -n "$out" ]]; then
|
||||
main >"$out"
|
||||
else
|
||||
main
|
||||
fi
|
||||
245
features/scripts/utils/nomarchy-docs-scripts
Executable file
245
features/scripts/utils/nomarchy-docs-scripts
Executable file
@@ -0,0 +1,245 @@
|
||||
#!/usr/bin/env bash
|
||||
# Generator tolerates "no matches" exit codes from grep | sort.
|
||||
# pipefail and -e off; -u stays.
|
||||
set -u
|
||||
|
||||
# nomarchy-docs-scripts
|
||||
#
|
||||
# Regenerates docs/SCRIPTS.md from the repo state. Produces:
|
||||
# 1. Header + status legend + regen instructions.
|
||||
# 2. Table of every nomarchy-* script (location, callers, status).
|
||||
# 3. Table of every menu entry in features/scripts/utils/nomarchy-menu
|
||||
# (submenu, label, target command, status).
|
||||
# 4. Snapshot list of orphaned references (called somewhere, no script).
|
||||
#
|
||||
# Status heuristic in Phase A:
|
||||
# kept — file exists AND is called from at least one *.nix / *.conf /
|
||||
# shell file outside its own directory.
|
||||
# unused? — file exists but no caller found. Phase B decides delete-dead
|
||||
# vs intentional public API.
|
||||
# missing — referenced but no file. Phase B decides port-from-omarchy
|
||||
# vs delete-dead vs stub-with-notify.
|
||||
#
|
||||
# nomarchy-docs-scripts # write to stdout
|
||||
# nomarchy-docs-scripts --out docs/SCRIPTS.md
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
cd "$repo_root"
|
||||
|
||||
# --- Inventory -------------------------------------------------------------
|
||||
|
||||
# Where scripts live, in render order.
|
||||
declare -A loc_label=(
|
||||
["features/scripts/utils"]="features/scripts/utils"
|
||||
["core/system/scripts"]="core/system/scripts"
|
||||
["themes/engine/scripts"]="themes/engine/scripts"
|
||||
)
|
||||
script_dirs=(features/scripts/utils core/system/scripts themes/engine/scripts)
|
||||
|
||||
# Build name → location map (associative array of basename → repo-relative dir).
|
||||
declare -A script_loc
|
||||
for dir in "${script_dirs[@]}"; do
|
||||
[[ -d "$dir" ]] || continue
|
||||
while IFS= read -r f; do
|
||||
script_loc["$(basename "$f")"]="$dir"
|
||||
done < <(find "$dir" -maxdepth 1 -type f -name 'nomarchy-*')
|
||||
done
|
||||
|
||||
# Find every nomarchy-* token referenced anywhere outside the script dirs.
|
||||
# (We exclude the script files themselves so they don't list themselves as
|
||||
# their own caller.)
|
||||
# File types we search for references. *.md catches docs and README;
|
||||
# branding/hook/extension files have varied or no extensions.
|
||||
grep_includes=(
|
||||
--include='*.nix' --include='*.conf' --include='*.sh' --include='*.md'
|
||||
--include='nomarchy-*' --include='*.jsonc' --include='*.toml'
|
||||
--include='*.txt' --include='*.sample'
|
||||
)
|
||||
search_dirs=(core features themes installer hosts bin lib README.md)
|
||||
|
||||
# Files whose mentions of nomarchy-* are documentation about the scripts,
|
||||
# not real callers. Excluded from caller discovery so they don't promote
|
||||
# every script to `kept`.
|
||||
self_refs=(docs/SCRIPTS.md docs/ROADMAP.md docs/AGENT.md)
|
||||
|
||||
ref_files_per_cmd() {
|
||||
local cmd="$1"
|
||||
local self_pattern
|
||||
self_pattern=$(IFS='|'; echo "${self_refs[*]}")
|
||||
grep -rlE "\\b${cmd}\\b" \
|
||||
"${grep_includes[@]}" \
|
||||
"${search_dirs[@]}" 2>/dev/null \
|
||||
| grep -vE "^(features/scripts/utils|core/system/scripts|themes/engine/scripts)/${cmd}$" \
|
||||
| grep -vE "^(${self_pattern})$" \
|
||||
| sort -u
|
||||
}
|
||||
|
||||
# All distinct nomarchy-* tokens we see anywhere in the repo.
|
||||
all_refs=$(grep -rohE 'nomarchy-[a-z0-9][a-z0-9-]+' \
|
||||
"${search_dirs[@]}" 2>/dev/null \
|
||||
| sort -u)
|
||||
|
||||
# --- Render: header --------------------------------------------------------
|
||||
|
||||
main() {
|
||||
cat <<'HEADER'
|
||||
# Nomarchy Script & Menu Audit
|
||||
|
||||
Auto-generated table for [Pillar 3 of the roadmap](ROADMAP.md#3-pillar-script--menu-audit).
|
||||
**Do not edit by hand.** Regenerate after script or menu changes:
|
||||
|
||||
```bash
|
||||
./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md
|
||||
```
|
||||
|
||||
The status column uses a Phase A heuristic — `kept` / `unused?` / `missing`.
|
||||
Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
`delete-dead`, or `stub-with-notify` and updates the rows.
|
||||
|
||||
## Status legend
|
||||
|
||||
- `kept` — script exists and is called from somewhere outside its own directory.
|
||||
- `unused?` — script exists but no caller was found. Could be dead, could be
|
||||
intentional public API. Phase B triage decides.
|
||||
- `missing` — referenced from code but no script file exists. Phase B triage
|
||||
decides whether to port from Omarchy upstream, delete the caller, or stub
|
||||
with `notify-send`.
|
||||
- `port-from-omarchy` — Phase B verdict: lift the upstream Omarchy script,
|
||||
rewrite for NixOS paths.
|
||||
- `delete-dead` — Phase B verdict: remove and update callers.
|
||||
- `stub-with-notify` — Phase B verdict: temporary `notify-send` stub.
|
||||
|
||||
HEADER
|
||||
|
||||
# --- Render: scripts table ----------------------------------------------
|
||||
printf '## Scripts (%d)\n\n' "${#script_loc[@]}"
|
||||
printf '| Script | Location | Callers | Status | Notes |\n'
|
||||
printf '| --- | --- | --- | --- | --- |\n'
|
||||
|
||||
# Sort scripts by name.
|
||||
for name in $(printf '%s\n' "${!script_loc[@]}" | sort); do
|
||||
local dir="${script_loc[$name]}"
|
||||
local callers status callers_str
|
||||
callers=$(ref_files_per_cmd "$name")
|
||||
if [[ -z "$callers" ]]; then
|
||||
status='`unused?`'
|
||||
callers_str='—'
|
||||
else
|
||||
status='`kept`'
|
||||
# Trim caller list to 2 entries + count.
|
||||
local count
|
||||
count=$(printf '%s\n' "$callers" | wc -l)
|
||||
if (( count > 2 )); then
|
||||
callers_str=$(printf '%s\n' "$callers" | head -2 | paste -sd, -)
|
||||
callers_str="$callers_str, +$((count - 2)) more"
|
||||
else
|
||||
callers_str=$(printf '%s\n' "$callers" | paste -sd, -)
|
||||
fi
|
||||
fi
|
||||
printf '| `%s` | `%s` | %s | %s | |\n' \
|
||||
"$name" "$dir" "$callers_str" "$status"
|
||||
done
|
||||
echo
|
||||
|
||||
# --- Render: missing references -----------------------------------------
|
||||
printf '## Missing references\n\n'
|
||||
printf 'Tokens grepped from `core/`, `features/`, `themes/`, `installer/`, `hosts/`, `bin/`, `lib/` that have no matching script file.\n\n'
|
||||
printf '| Token | Referenced in | Status |\n'
|
||||
printf '| --- | --- | --- |\n'
|
||||
while IFS= read -r token; do
|
||||
[[ -z "$token" ]] && continue
|
||||
[[ -n "${script_loc[$token]:-}" ]] && continue
|
||||
local refs
|
||||
self_pattern=$(IFS='|'; echo "${self_refs[*]}")
|
||||
refs=$(grep -rlE "\\b${token}\\b" \
|
||||
"${grep_includes[@]}" \
|
||||
"${search_dirs[@]}" 2>/dev/null \
|
||||
| grep -vE "^(${self_pattern})$" \
|
||||
| sort -u)
|
||||
[[ -z "$refs" ]] && continue
|
||||
local count refs_str
|
||||
count=$(printf '%s\n' "$refs" | wc -l)
|
||||
if (( count > 2 )); then
|
||||
refs_str=$(printf '%s\n' "$refs" | head -2 | paste -sd, -)
|
||||
refs_str="$refs_str, +$((count - 2)) more"
|
||||
else
|
||||
refs_str=$(printf '%s\n' "$refs" | paste -sd, -)
|
||||
fi
|
||||
printf '| `%s` | %s | `missing` |\n' "$token" "$refs_str"
|
||||
done <<<"$all_refs"
|
||||
echo
|
||||
|
||||
# --- Render: menu items -------------------------------------------------
|
||||
printf '## Menu items\n\n'
|
||||
printf 'Walked from `features/scripts/utils/nomarchy-menu`. Each `case` arm in a `show_*_menu` function becomes one row.\n\n'
|
||||
printf '| Submenu | Entry | Calls | Status |\n'
|
||||
printf '| --- | --- | --- | --- |\n'
|
||||
|
||||
awk '
|
||||
/^show_[a-z_]+_menu\(\) {/ { sub(/\(\) {/, ""); current=$1; in_func=1; next }
|
||||
/^[a-z_]+\(\) {/ && !/^show_/ { current=""; in_func=0; next }
|
||||
/^}$/ { current=""; in_func=0; next }
|
||||
!in_func { next }
|
||||
/^ case \$\(menu / {
|
||||
# extract the menu title between the first pair of double quotes
|
||||
match($0, /menu "[^"]+" "[^"]+"/);
|
||||
if (RSTART == 0) next;
|
||||
title=substr($0, RSTART, RLENGTH);
|
||||
# second quoted string is the option list
|
||||
n=split(title, parts, "\"");
|
||||
title=parts[2];
|
||||
options=parts[4];
|
||||
# split options on \n
|
||||
split(options, opts, "\\\\n");
|
||||
pending_submenu=current;
|
||||
pending_title=title;
|
||||
for (i=1;i<=length(opts);i++) pending_opts[i]=opts[i];
|
||||
pending_count=length(opts);
|
||||
next
|
||||
}
|
||||
/^ \*[A-Za-z]/ {
|
||||
# case arm — extract pattern between the first * and the closing )
|
||||
match($0, /\*[^)]*\)/);
|
||||
if (RSTART == 0) next;
|
||||
arm=substr($0, RSTART, RLENGTH);
|
||||
gsub(/[*)]/, "", arm);
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", arm);
|
||||
# action follows the )
|
||||
rest=substr($0, RSTART+RLENGTH);
|
||||
sub(/^[[:space:]]+/, "", rest);
|
||||
sub(/[[:space:]]*;;[[:space:]]*$/, "", rest);
|
||||
# match the first nomarchy-* token in the action
|
||||
cmd=""
|
||||
if (match(rest, /nomarchy-[a-z0-9-]+/)) {
|
||||
cmd=substr(rest, RSTART, RLENGTH);
|
||||
}
|
||||
printf "%s|%s|%s\n", pending_submenu, arm, cmd;
|
||||
}
|
||||
' features/scripts/utils/nomarchy-menu > /tmp/nomarchy-menu-rows.$$
|
||||
|
||||
while IFS='|' read -r submenu entry cmd; do
|
||||
[[ -z "$entry" ]] && continue
|
||||
[[ "$entry" =~ ^\) ]] && continue
|
||||
status='`kept`'
|
||||
if [[ -n "$cmd" ]]; then
|
||||
if [[ -z "${script_loc[$cmd]:-}" ]]; then
|
||||
status='`missing`'
|
||||
fi
|
||||
else
|
||||
cmd='_(inline)_'
|
||||
fi
|
||||
printf '| `%s` | %s | `%s` | %s |\n' "$submenu" "$entry" "$cmd" "$status"
|
||||
done < /tmp/nomarchy-menu-rows.$$
|
||||
rm -f /tmp/nomarchy-menu-rows.$$
|
||||
echo
|
||||
}
|
||||
|
||||
out=""
|
||||
if [[ "${1:-}" == "--out" ]]; then
|
||||
out="${2:?--out needs a path}"; shift 2
|
||||
fi
|
||||
if [[ -n "$out" ]]; then
|
||||
main >"$out"
|
||||
else
|
||||
main
|
||||
fi
|
||||
14
features/scripts/utils/nomarchy-install
Executable file
14
features/scripts/utils/nomarchy-install
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Nomarchy Install Script
|
||||
# Entry point for the Nomarchy installer.
|
||||
|
||||
INSTALLER="/etc/install.sh"
|
||||
[[ ! -f "$INSTALLER" ]] && INSTALLER="/etc/nixos/nomarchy/installer/install.sh"
|
||||
|
||||
if [[ -f "$INSTALLER" ]]; then
|
||||
sudo "$INSTALLER" "$@"
|
||||
else
|
||||
echo "Error: Nomarchy installer not found at $INSTALLER"
|
||||
exit 1
|
||||
fi
|
||||
8
features/scripts/utils/nomarchy-install-docker-dbs
Executable file
8
features/scripts/utils/nomarchy-install-docker-dbs
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Nomarchy Docker DBs Stub
|
||||
# This script is a stub for a specialized tool.
|
||||
|
||||
notify-send "Nomarchy" "The docker-dbs tool is not implemented in this version of Nomarchy. Please use standard podman/docker commands."
|
||||
echo "Not implemented."
|
||||
exit 1
|
||||
9
features/scripts/utils/nomarchy-manual
Executable file
9
features/scripts/utils/nomarchy-manual
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Nomarchy Manual Script
|
||||
# Opens the Nomarchy manual in the default web browser.
|
||||
|
||||
URL="https://learn.omacom.io/2/the-nomarchy-manual"
|
||||
|
||||
echo "Opening Nomarchy manual: $URL"
|
||||
xdg-open "$URL"
|
||||
23
features/scripts/utils/nomarchy-skill
Executable file
23
features/scripts/utils/nomarchy-skill
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Nomarchy Skill Script
|
||||
# Displays the Nomarchy Skill documentation for agents and power users.
|
||||
|
||||
SKILL_FILE="$HOME/.config/nomarchy-skill/SKILL.md"
|
||||
|
||||
if [[ ! -f "$SKILL_FILE" ]]; then
|
||||
# Fallback to repo location if managed by nix
|
||||
SKILL_FILE="/etc/nixos/nomarchy/core/home/config/nomarchy-skill/SKILL.md"
|
||||
fi
|
||||
|
||||
if [[ ! -f "$SKILL_FILE" ]]; then
|
||||
# Final fallback to standard config dir
|
||||
SKILL_FILE="$HOME/.config/nomarchy-skill/SKILL.md"
|
||||
fi
|
||||
|
||||
if [[ -f "$SKILL_FILE" ]]; then
|
||||
glow "$SKILL_FILE"
|
||||
else
|
||||
echo "Error: Nomarchy Skill documentation not found."
|
||||
exit 1
|
||||
fi
|
||||
@@ -2,13 +2,5 @@
|
||||
|
||||
# Build and run the Nomarchy Installer VM for testing.
|
||||
|
||||
echo "Building Nomarchy Installer VM..."
|
||||
nix build .#nixosConfigurations.installerVm.config.system.build.vm
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Success! Launching Installer VM..."
|
||||
./result/bin/run-nomarchy-installer-vm
|
||||
else
|
||||
echo "Error: VM build failed."
|
||||
exit 1
|
||||
fi
|
||||
echo "Launching Nomarchy Installer VM..."
|
||||
nix run .#installerVm
|
||||
|
||||
Reference in New Issue
Block a user