fix: cache pos config scopes for completion; stop per-TAB registry scan

pos config <TAB> re-scanned every tool's '# POS_CONFIG:' header per
keypress (dozens of subshells, greps, seds). On the loaded homelab box a
stuck completion wedged interactive shells at 69% CPU for ~an hour. make
gen now emits a static _pos_config_scopes array into completions/pos.bash
(no runtime scan; live-scan fallback if the cache is missing).
This commit is contained in:
Your Name
2026-08-09 04:31:07 -04:00
parent 494952369d
commit cb82acb155
4 changed files with 45 additions and 13 deletions
+3 -1
View File
@@ -16,7 +16,9 @@ summary (newest last).
## Done
- **2026-08-09** — `pos config <scope>` interactive config editor: reads the `# POS_CONFIG:` registry across tools into a single runtime config (`~/.config/linux_post_install/*.env`, one file per scope, chmod 600); secret masking with show/hide toggle, `digits:`/`num:`/`url:` validation, `-` to clear, blank keeps; `*plugins` marker expands plugin vars (entertainment) from `entertainment-lib.sh`; gen-docs now handles category-less tools (`pos-config`), fixed a `set -e`+`pipefail` bug that truncated the header registry.
- **2026-08-09** — `pos config <TAB>` scope completion is now cached at gen time (`_pos_config_scopes` array emitted by `make gen` from the `# POS_CONFIG:` registry) instead of scanning ~40 tools per TAB — a per-keypress subshell storm that wedged interactive shells for minutes on the loaded homelab box. Two stuck `-bash` sessions (69%/38% CPU) killed. `plugin_marker`/`plugin_keys` hardened with `|| true` so `config_keys` no longer aborts mid-scan under `set -euo pipefail` on mixed lib/plugin dirs (installed layout) — fixes missing plugin keys in `pos config entertainment`.
- **2026-08-09** — `pos config <scope>` interactive config editor: reads the `# POS_CONFIG:` registry across tools into a single runtime config (`~/.config/linux_post_install/*.env`, one file per scope, chmod 600); secret masking with show/hide toggle, `digits:`/`num:`/`url:` validation, `-` to clear, blank keeps; `*plugins` marker expands plugin vars (entertainment) from `entertainment-lib.sh`; `desc::example` value-format hints shown in the editor; gen-docs now handles category-less tools (`pos-config`), fixed a `set -e`+`pipefail` bug that truncated the header registry.
- **2026-08-09** — `pos-communication-telegram``pos-communication-telegram-sender`: one canonical `send` (dropped the legacy `--send` flag, which duplicated the `send` subcommand in completion). `pos communication telegram <TAB>` now completes to just `sender listener`. `lib/notify.sh` maps platform `telegram``telegram-sender` via `notify_sender_name()`; entertainment-send + health `--send` check updated. Removed phantom subcommands from howto/communication.md (webhook/logs/broadcast/file never existed).
+1 -1
View File
@@ -578,7 +578,7 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
| `bin/pos-system-nfs-client` | 138 | Mount NFS shares (ephemeral or persistent systemd mount units) |
| `bin/pos-system-nfs-server` | 134 | Manage the NFS kernel server (status, share/unshare exports, enable/disable) |
| `bin/pos-usb-server` | 218 | USB Redirector server control (--ls, --share; prompts when args omitted) |
| `completions/pos.bash` | 267 | Dynamic bash completion |
| `completions/pos.bash` | 279 | Dynamic bash completion |
<!-- GEN:END filetable -->
| `apps/install.sh` | 171 | App install/uninstall picker/orchestrator |
+23 -11
View File
@@ -17,6 +17,9 @@ _pos_subcmds[communication-telegram-sender]="send test config"
_pos_subcmds[docker-compose]="ls installed up down restart logs update config"
_pos_subcmds[docker-vbox]="create enter stop start rm ls"
# GEN:END possubcmds
# GEN:START posconfigscopes
declare -a _pos_config_scopes=(compose entertainment notify system telegram)
# GEN:END posconfigscopes
_pos() {
local cur prev words cword
@@ -158,18 +161,27 @@ _pos() {
COMPREPLY=($(compgen -W "${out[*]}" -- "$cur"))
}
# Dynamic scope completion for `pos config <TAB>` — greps the
# "# POS_CONFIG:" headers in the tools dir (the config registry).
# Config scope completion for `pos config <TAB>` — cached at gen time from
# the "# POS_CONFIG:" registry (scanning all tools per TAB is too heavy).
# Falls back to a live scan only if the cache is missing.
_pos_config_scopes() {
local scopes=() f line scope
for f in "$pos_dir"/pos-*; do
[ -x "$f" ] || continue
while IFS= read -r line; do
scope="$(sed 's/^# POS_CONFIG:[[:space:]]*//' <<<"$line" | cut -d'|' -f1 | tr -d ' ')"
[ -n "$scope" ] && scopes+=("$scope")
done < <(grep '^# POS_CONFIG:' "$f" 2>/dev/null)
done
COMPREPLY=($(compgen -W "$(printf '%s\n' "${scopes[@]}" | sort -u | tr '\n' ' ') --help" -- "$cur"))
local scopes=()
if declare -p _pos_config_scopes &>/dev/null; then
scopes=("${_pos_config_scopes[@]}")
else
local f line scope
for f in "$pos_dir"/pos-*; do
[ -x "$f" ] || continue
while IFS= read -r line; do
line="${line#*POS_CONFIG:}"
scope="${line%%|*}"
scope="${scope// }"
[ -n "$scope" ] && scopes+=("$scope")
done < <(grep '^# POS_CONFIG:' "$f" 2>/dev/null || true)
done
mapfile -t scopes < <(printf '%s\n' "${scopes[@]}" | sort -u)
fi
COMPREPLY=($(compgen -W "${scopes[*]} --help" -- "$cur"))
}
# ── Dispatch ───────────────────────────────────────────────
+18
View File
@@ -120,6 +120,23 @@ gen_possubcmds() {
done
}
# Config scopes: the "# POS_CONFIG:" registry (first field = scope), cached so
# `pos config <TAB>` doesn't re-scan every tool per completion.
gen_posconfigscopes() {
local f line scope scopes=()
for f in "$root"/bin/pos-*; do
[ -x "$f" ] || continue
while IFS= read -r line; do
line="${line#*POS_CONFIG:}"
scope="${line%%|*}"
scope="${scope// }"
[ -n "$scope" ] && scopes+=("$scope")
done < <(grep '^# POS_CONFIG:' "$f" 2>/dev/null || true)
done
mapfile -t scopes < <(printf '%s\n' "${scopes[@]}" | sort -u)
echo "declare -a _pos_config_scopes=(${scopes[*]:-})"
}
# Section index of AGENT_Context itself: maps each "## " heading to its
# line range. Excludes the "Document Map" heading (this block).
gen_docmap() {
@@ -189,6 +206,7 @@ regen_block "$ctx" dispatch
regen_block "$ctx" selfcontained
regen_block "$comp" posflags
regen_block "$comp" possubcmds
regen_block "$comp" posconfigscopes
regen_block "$ctx" filetable
# docmap is self-referential: its own block size shifts the section line