fix: infinite loop in pos completion walk-up caused CPU hang on TAB

_pos_complete_tool walks up the key looking for a tool that declares
POS_FLAGS/POS_SUBCMDS; "${k%-*}" on a dash-free key returns it
unchanged, so once the walk hit a bare category (e.g. 'system' from
system-nfs-server) the while loop spun at 100% CPU. Any TAB at an
argument position of a tool without flags/subcmds froze the shell.
Stop the walk-up when no dash remains.

Also refresh AGENTS.md quick facts and regenerate doc file table
(completions/pos.bash 278->279 lines).
This commit is contained in:
Your Name
2026-08-09 09:24:50 +00:00
parent fe7708f142
commit 95917607cf
3 changed files with 10 additions and 4 deletions
+8 -3
View File
@@ -10,10 +10,15 @@ CRITICAL: real guidance lives in DOC/. When you encounter a reference below, use
- @DOC/DEV.md — conventions, verification, and the "Adding a new Feature/App/Tool" checklists. Read before creating or changing code/docs.
- @DOC/POS.md — `pos` CLI reference (dispatcher + every command). Read when working on `bin/pos*` scripts or their docs.
- @DOC/README.md — index of all docs. Read to find the right doc.
- @DOC/HOWTO.md — hands-on per-category guides (network, docker, media, system, ssh, usb, communication, entertainment) with flags, recipes, and troubleshooting. Read when a task is about *using* `pos` day-to-day rather than extending it.
- @DOC/HOWTO.md — hands-on per-category guides (network, docker, media, system, ssh, usb, communication, entertainment). Read when a task is about *using* `pos` day-to-day rather than extending it.
## Quick facts
- Each tool is `bin/pos-<category>-<command>`; `bin/pos` dispatches via smart arg matching; bash completion derives from filenames.
- Verify edits with `make check` (runs `bash -n` + the generated-doc sync gate). Generated sections (dispatch table, file table, line counts, completion flags, this doc's Document Map) are code-derived — after changing `bin/pos-*`, `lib/*`, or `completions/`, run `make gen` and commit the refreshed output.
- **Tool model:** `bin/pos-<category>-<command>` (one category-less exception: `pos-config`). `bin/pos` dispatches by longest-prefix arg matching. New tools are auto-discovered but must be executable (`100755`) and carry a `# POS: <cat> <cmd> — <desc>` header right after the shebang; `# POS_FLAGS:` / `# POS_SUBCMDS:` / `# POS_CONFIG:` headers feed tab-completion and the `pos config` scope registry. A missing `# POS:` header hard-fails `make gen`.
- **Generated code:** blocks between `GEN:START`/`GEN:END` markers in `DOC/AGENT_Context_Project.md` (tree, dispatch, selfcontained, filetable, docmap) and `completions/pos.bash` (flags, subcmds, config scopes) are `make gen` output — never hand-edit them. After touching `bin/pos-*`, run `make gen` then `make check` (bash -n + exec-bit check + doc-sync gate + dispatch smoke; definition of done). Hand-maintained, not gen-checked: `DOC/POS.md`, the line-count rows above the filetable marker (e.g. `lib/common.sh`), `bin/pos` usage() EXAMPLES, root README.
- **Stdin gotcha:** any tool that reads stdin must be added to `INTERACTIVE_CMDS` in `bin/pos` — otherwise the logging `tee` pipe hangs on (or swallows) the prompt.
- **Deps:** apt packages → `PACKAGES` array in `preinstall.sh`; non-apt/manual installers (e.g. `usbsrv`) → `command -v <bin> || err "…"` guard inside the tool, never in PACKAGES.
- **Secrets:** never commit keys/tokens. `config/authorized_keys` and `config/rclone.conf` are gitignored; runtime tool config is `~/.config/linux_post_install/<tool>.env` (chmod 600, env-var precedence). Mask tokens in `config` output.
- **entertainment plugins:** standalone scripts in `entertainment/` that must NOT source `lib/common.sh` — stdout is the message that gets sent to Telegram (helper chatter would leak into it). Markers: `# POS_PLUGIN: <name>` + `# POS_KEYS:` declarations.
- **Conventions:** `set -euo pipefail`, `-h|--help` via case, idempotent writes, use `run`/`spawn` helpers (respect `$DRY_RUN`), `make hook` installs the opt-in pre-commit gate.
- Maintain `AGENT_TODO.md` (Now / Next / Later / Done): when you finish a task, move it to **Done** (dated) in the same commit.