Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions doc/changelog/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ not deferred to release. `release-tag.sh` promotes `[Unreleased]` →

### Added

- **Six monitoring modules for the small-tools modularization program: `btop`,
`bmon`, `iftop`, `iotop`, `nmon`, `powertop`** (`module/<name>.module.sh` +
`test/unit/module/<name>_spec.bats` each). All are apt-archetype `optional`
modules tagged `monitoring`, each installing its like-named apt package
(`btop`, `bmon`, `iftop`, `iotop`, `nmon`, `powertop`) via
`module_use_apt_archetype`, with module-defined `detect()`/`is_recommended()`
and a real `doctor()` that verifies the tool actually runs: `btop --version`
for btop, `bmon -V` for bmon, and `command -v <tool>` for iftop / iotop /
nmon / powertop (which ship no clean version flag). Each declares an en +
zh-TW `DESCRIPTION`, `SUPPORTED_UBUNTU=("22.04" "24.04" "26.04")`, and a
`TEST_VERIFY_CMD` matching its doctor probe. Both standalone- and
engine-invocable; all satisfy the 10-function module contract (ADR-0002,
enforced by `test/unit/module/contract_conformance_spec.bats`).
`doc/module/INDEX.md` regenerated (54 modules).
- **Six apt-archetype CLI/utility modules for the small-tools modularization
program: `tig`, `git-lfs`, `tree`, `ncdu`, `net-tools`, `sshfs`**
(`module/<name>.module.sh` + `test/unit/module/<name>_spec.bats` each). All
Expand Down
8 changes: 7 additions & 1 deletion doc/module/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Module Index

54 modules. Columns come from each module's metadata block
60 modules. Columns come from each module's metadata block
(`NAME` / `CATEGORY` / `TAGS` / `DESCRIPTION[en]`, doc/module-spec.md §3).
Per-module pages will land in a later milestone; until then each name links
to the module source.
Expand All @@ -12,6 +12,8 @@ to the module source.
|---|---|---|---|
| [anydesk](../../module/anydesk.module.sh) | optional | remote | AnyDesk — remote desktop client (upstream apt repository) |
| [batcat](../../module/batcat.module.sh) | optional | cli-essentials | bat — cat clone with syntax highlighting (Ubuntu binary: batcat) |
| [bmon](../../module/bmon.module.sh) | optional | monitoring | bmon — bandwidth monitor (real-time per-interface traffic, apt bmon package) |
| [btop](../../module/btop.module.sh) | optional | monitoring | btop — modern resource monitor (CPU / memory / disk / net, apt btop package) |
| [build-essential](../../module/build-essential.module.sh) | base | build | build-essential — C/C++ compiler toolchain metapackage (gcc, g++, make) |
| [claude-code-config](../../module/claude-code-config.module.sh) | optional | agent config dotfile | Personal Claude Code settings (~/.claude: settings.json + statusline) |
| [claude-code](../../module/claude-code.module.sh) | optional | agent | Anthropic Claude Code CLI agent (official native installer, self-updating) |
Expand All @@ -33,6 +35,8 @@ to the module source.
| [glow](../../module/glow.module.sh) | optional | cli-essentials | glow — render markdown on the CLI (yazi markdown-preview dependency) |
| [gum](../../module/gum.module.sh) | optional | cli-essentials tui | gum — a tool for glamorous shell scripts (preferred modern TUI backend) |
| [htop](../../module/htop.module.sh) | base | monitor | htop — interactive process viewer (apt htop package) |
| [iftop](../../module/iftop.module.sh) | optional | monitoring | iftop — display network bandwidth usage by host (apt iftop package) |
| [iotop](../../module/iotop.module.sh) | optional | monitoring | iotop — per-process disk I/O monitor (apt iotop package) |
| [jetson-stats](../../module/jetson-stats.module.sh) | optional | hardware | jetson-stats — jtop monitor TUI for NVIDIA Jetson (iGPU, nvpmodel, clocks, fan) |
| [jq](../../module/jq.module.sh) | base | cli core | jq — command-line JSON processor (apt jq package) |
| [kvm](../../module/kvm.module.sh) | optional | virtualization vm | KVM / libvirt / QEMU virtualization stack + virt-manager |
Expand All @@ -44,9 +48,11 @@ to the module source.
| [ncdu](../../module/ncdu.module.sh) | optional | monitor disk tui | ncdu — ncurses disk usage analyzer (TUI) |
| [neovim](../../module/neovim.module.sh) | recommended | editor cli | Neovim editor + nvimdots personal config |
| [net-tools](../../module/net-tools.module.sh) | optional | network cli | net-tools — legacy net utilities (ifconfig/netstat/route/arp) |
| [nmon](../../module/nmon.module.sh) | optional | monitoring | nmon — system performance monitor (CPU / memory / disk / net, apt nmon package) |
| [notion](../../module/notion.module.sh) | optional | notes | Notion desktop app (unofficial notion-electron .deb client) |
| [nvidia-driver](../../module/nvidia-driver.module.sh) | optional | gpu nvidia hardware | NVIDIA proprietary driver (auto-detected recommended version via ubuntu-drivers) |
| [pipx](../../module/pipx.module.sh) | base | python cli | pipx — install and run Python CLI apps in isolated virtualenvs (apt-managed) |
| [powertop](../../module/powertop.module.sh) | optional | monitoring | powertop — power consumption diagnostics and monitor (apt powertop package) |
| [python3](../../module/python3.module.sh) | base | python runtime | python3 — Python 3 runtime + packaging toolchain (pip, dev headers, setuptools) |
| [qmk-firmware](../../module/qmk-firmware.module.sh) | optional | hardware | QMK firmware dev environment — qmk CLI (pipx) + toolchain + qmk_firmware checkout |
| [ripgrep](../../module/ripgrep.module.sh) | optional | cli-essentials | ripgrep (rg) — fast, recursive grep alternative (apt ripgrep package) |
Expand Down
96 changes: 96 additions & 0 deletions module/bmon.module.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env bash
# module/bmon.module.sh — bmon — bandwidth monitor (apt bmon package) [archetype: apt]
#
# Part of the small-tools modularization program: each monitoring tool is an
# independently installable / removable module. Ubuntu ships the `bmon`
# package; the binary is `bmon`.
#
# Standalone usage:
# bash module/bmon.module.sh install [--dry-run]
# bash module/bmon.module.sh upgrade / remove / purge / verify / doctor
# bash module/bmon.module.sh detect / is-installed / is-recommended / is-outdated
# bash module/bmon.module.sh info / status (read-only metadata views)
#
# Engine usage (resolves DEPENDS_ON, batches with state.json):
# setup_ubuntu install bmon

# ── Dual-mode header ────────────────────────────────────────────────────────
MODULE_STANDALONE="true"
[[ "${BASH_SOURCE[0]:-}" != "${0:-}" ]] && MODULE_STANDALONE="false"
if [[ "${MODULE_STANDALONE}" == "true" ]]; then
# shellcheck source=../lib/module_bootstrap.sh
source "${LIB_DIR:-$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../lib" && pwd -P)}/module_bootstrap.sh"
module_bootstrap
fi
# Static-analysis hint (never executed: the guard is always false; wrapped in
# kcov-exclude so the dead line is not counted against coverage). module_bootstrap
# sources the lib helpers at runtime, but shellcheck cannot trace that 2-level
# dynamic source — this guarded line lets `shellcheck -x` follow module_helper.sh
# so it sees the metadata + archetype vars below are used externally (avoids SC2034).
# kcov-exclude-start
# shellcheck source=../lib/module_helper.sh
[[ -n "${__module_lint_hint:-}" ]] && source "${LIB_DIR}/module_helper.sh"
# kcov-exclude-end

# ── Metadata (doc/module-spec.md §3) ────────────────────────────────────────
NAME="bmon"
VERSION_PROVIDED="apt-managed"
CATEGORY="optional"
TAGS=("monitoring")
HOMEPAGE="https://github.com/tgraf/bmon"
declare -gA DESCRIPTION=(
[en]="bmon — bandwidth monitor (real-time per-interface traffic, apt bmon package)"
[zh-TW]="bmon — 頻寬監視工具(即時各介面網路流量,apt bmon 套件)"
)
declare -gA POST_INSTALL_MESSAGE=()
declare -gA WARN_MESSAGE=()
SUPPORTED_UBUNTU=("22.04" "24.04" "26.04")
SUPPORTED_PLATFORMS=("desktop" "server" "wsl" "container" "vm")
DEPENDS_ON=()
CONFLICTS_WITH=()
SUPPORTS_USER_HOME=false
RISK_LEVEL="low"
REBOOT_REQUIRED=false
INSTALL_TARGET_DEFAULT="sudo"
TEST_VERIFY_CMD="command -v bmon && bmon -V"

# Engine-consumed metadata: the registry/runner read these post-source, and
# the i18n arrays are dereferenced indirectly via module_i18n_get. Reference
# them once so the linter sees an in-file use (SC2034) without a disable.
: "${DESCRIPTION[*]:-}" "${POST_INSTALL_MESSAGE[*]:-}" "${WARN_MESSAGE[*]:-}" \
"${SUPPORTS_USER_HOME}" "${INSTALL_TARGET_DEFAULT}"

# ── Archetype A — apt ───────────────────────────────────────────────────────
APT_PKGS=("bmon")
APT_PPA=""
CONFIG_PATHS=()
module_use_apt_archetype

# ── Required hooks (detect + is_recommended stay module-specific) ────────────
detect() {
command -v apt-get >/dev/null 2>&1
}

is_recommended() {
! is_installed
}

# doctor: real runtime health — the tool must be installed AND actually run
# (`bmon -V` prints the version and exits). Warns (read-only) on Sidecar
# drift (ADR-0001).
doctor() {
module_dryrun_guard doctor "is_installed + bmon -V + Sidecar consistency" \
&& return 0
is_installed || { log_warn "[${NAME}] doctor: bmon is not installed"; return 1; }
bmon -V >/dev/null 2>&1 \
|| { log_warn "[${NAME}] doctor: bmon is present but not runnable"; return 1; }
if ! module_sidecar_get_version "${NAME}" >/dev/null 2>&1; then
log_warn "[${NAME}] doctor: Sidecar missing (ADR-0001 drift; re-run install/upgrade to heal)"
fi
return 0
}

# ── Standalone footer ───────────────────────────────────────────────────────
if [[ "${MODULE_STANDALONE:-false}" == "true" ]]; then
module_standalone_main "$@"
fi
95 changes: 95 additions & 0 deletions module/btop.module.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env bash
# module/btop.module.sh — btop — modern resource monitor (apt btop package) [archetype: apt]
#
# Part of the small-tools modularization program: each monitoring tool is an
# independently installable / removable module. Ubuntu ships the `btop`
# package; the binary is `btop`.
#
# Standalone usage:
# bash module/btop.module.sh install [--dry-run]
# bash module/btop.module.sh upgrade / remove / purge / verify / doctor
# bash module/btop.module.sh detect / is-installed / is-recommended / is-outdated
# bash module/btop.module.sh info / status (read-only metadata views)
#
# Engine usage (resolves DEPENDS_ON, batches with state.json):
# setup_ubuntu install btop

# ── Dual-mode header ────────────────────────────────────────────────────────
MODULE_STANDALONE="true"
[[ "${BASH_SOURCE[0]:-}" != "${0:-}" ]] && MODULE_STANDALONE="false"
if [[ "${MODULE_STANDALONE}" == "true" ]]; then
# shellcheck source=../lib/module_bootstrap.sh
source "${LIB_DIR:-$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../lib" && pwd -P)}/module_bootstrap.sh"
module_bootstrap
fi
# Static-analysis hint (never executed: the guard is always false; wrapped in
# kcov-exclude so the dead line is not counted against coverage). module_bootstrap
# sources the lib helpers at runtime, but shellcheck cannot trace that 2-level
# dynamic source — this guarded line lets `shellcheck -x` follow module_helper.sh
# so it sees the metadata + archetype vars below are used externally (avoids SC2034).
# kcov-exclude-start
# shellcheck source=../lib/module_helper.sh
[[ -n "${__module_lint_hint:-}" ]] && source "${LIB_DIR}/module_helper.sh"
# kcov-exclude-end

# ── Metadata (doc/module-spec.md §3) ────────────────────────────────────────
NAME="btop"
VERSION_PROVIDED="apt-managed"
CATEGORY="optional"
TAGS=("monitoring")
HOMEPAGE="https://github.com/aristocratos/btop"
declare -gA DESCRIPTION=(
[en]="btop — modern resource monitor (CPU / memory / disk / net, apt btop package)"
[zh-TW]="btop — 現代化資源監視工具(CPU / 記憶體 / 磁碟 / 網路,apt btop 套件)"
)
declare -gA POST_INSTALL_MESSAGE=()
declare -gA WARN_MESSAGE=()
SUPPORTED_UBUNTU=("22.04" "24.04" "26.04")
SUPPORTED_PLATFORMS=("desktop" "server" "wsl" "container" "vm")
DEPENDS_ON=()
CONFLICTS_WITH=()
SUPPORTS_USER_HOME=false
RISK_LEVEL="low"
REBOOT_REQUIRED=false
INSTALL_TARGET_DEFAULT="sudo"
TEST_VERIFY_CMD="command -v btop && btop --version | head -n1"

# Engine-consumed metadata: the registry/runner read these post-source, and
# the i18n arrays are dereferenced indirectly via module_i18n_get. Reference
# them once so the linter sees an in-file use (SC2034) without a disable.
: "${DESCRIPTION[*]:-}" "${POST_INSTALL_MESSAGE[*]:-}" "${WARN_MESSAGE[*]:-}" \
"${SUPPORTS_USER_HOME}" "${INSTALL_TARGET_DEFAULT}"

# ── Archetype A — apt ───────────────────────────────────────────────────────
APT_PKGS=("btop")
APT_PPA=""
CONFIG_PATHS=("${HOME}/.config/btop")
module_use_apt_archetype

# ── Required hooks (detect + is_recommended stay module-specific) ────────────
detect() {
command -v apt-get >/dev/null 2>&1
}

is_recommended() {
! is_installed
}

# doctor: real runtime health — the tool must be installed AND actually run
# (`btop --version`). Warns (read-only) on Sidecar drift (ADR-0001).
doctor() {
module_dryrun_guard doctor "is_installed + btop --version + Sidecar consistency" \
&& return 0
is_installed || { log_warn "[${NAME}] doctor: btop is not installed"; return 1; }
btop --version >/dev/null 2>&1 \
|| { log_warn "[${NAME}] doctor: btop is present but not runnable"; return 1; }
if ! module_sidecar_get_version "${NAME}" >/dev/null 2>&1; then
log_warn "[${NAME}] doctor: Sidecar missing (ADR-0001 drift; re-run install/upgrade to heal)"
fi
return 0
}

# ── Standalone footer ───────────────────────────────────────────────────────
if [[ "${MODULE_STANDALONE:-false}" == "true" ]]; then
module_standalone_main "$@"
fi
97 changes: 97 additions & 0 deletions module/iftop.module.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env bash
# module/iftop.module.sh — iftop — network bandwidth by host (apt iftop package) [archetype: apt]
#
# Part of the small-tools modularization program: each monitoring tool is an
# independently installable / removable module. Ubuntu ships the `iftop`
# package; the binary is `iftop`. iftop has no clean --version flag, so the
# doctor probe verifies the binary is present and resolvable on PATH.
#
# Standalone usage:
# bash module/iftop.module.sh install [--dry-run]
# bash module/iftop.module.sh upgrade / remove / purge / verify / doctor
# bash module/iftop.module.sh detect / is-installed / is-recommended / is-outdated
# bash module/iftop.module.sh info / status (read-only metadata views)
#
# Engine usage (resolves DEPENDS_ON, batches with state.json):
# setup_ubuntu install iftop

# ── Dual-mode header ────────────────────────────────────────────────────────
MODULE_STANDALONE="true"
[[ "${BASH_SOURCE[0]:-}" != "${0:-}" ]] && MODULE_STANDALONE="false"
if [[ "${MODULE_STANDALONE}" == "true" ]]; then
# shellcheck source=../lib/module_bootstrap.sh
source "${LIB_DIR:-$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../lib" && pwd -P)}/module_bootstrap.sh"
module_bootstrap
fi
# Static-analysis hint (never executed: the guard is always false; wrapped in
# kcov-exclude so the dead line is not counted against coverage). module_bootstrap
# sources the lib helpers at runtime, but shellcheck cannot trace that 2-level
# dynamic source — this guarded line lets `shellcheck -x` follow module_helper.sh
# so it sees the metadata + archetype vars below are used externally (avoids SC2034).
# kcov-exclude-start
# shellcheck source=../lib/module_helper.sh
[[ -n "${__module_lint_hint:-}" ]] && source "${LIB_DIR}/module_helper.sh"
# kcov-exclude-end

# ── Metadata (doc/module-spec.md §3) ────────────────────────────────────────
NAME="iftop"
VERSION_PROVIDED="apt-managed"
CATEGORY="optional"
TAGS=("monitoring")
HOMEPAGE="https://pdw.ex-parrot.com/iftop/"
declare -gA DESCRIPTION=(
[en]="iftop — display network bandwidth usage by host (apt iftop package)"
[zh-TW]="iftop — 依主機顯示網路頻寬用量(apt iftop 套件)"
)
declare -gA POST_INSTALL_MESSAGE=()
declare -gA WARN_MESSAGE=()
SUPPORTED_UBUNTU=("22.04" "24.04" "26.04")
SUPPORTED_PLATFORMS=("desktop" "server" "wsl" "container" "vm")
DEPENDS_ON=()
CONFLICTS_WITH=()
SUPPORTS_USER_HOME=false
RISK_LEVEL="low"
REBOOT_REQUIRED=false
INSTALL_TARGET_DEFAULT="sudo"
TEST_VERIFY_CMD="command -v iftop"

# Engine-consumed metadata: the registry/runner read these post-source, and
# the i18n arrays are dereferenced indirectly via module_i18n_get. Reference
# them once so the linter sees an in-file use (SC2034) without a disable.
: "${DESCRIPTION[*]:-}" "${POST_INSTALL_MESSAGE[*]:-}" "${WARN_MESSAGE[*]:-}" \
"${SUPPORTS_USER_HOME}" "${INSTALL_TARGET_DEFAULT}"

# ── Archetype A — apt ───────────────────────────────────────────────────────
APT_PKGS=("iftop")
APT_PPA=""
CONFIG_PATHS=()
module_use_apt_archetype

# ── Required hooks (detect + is_recommended stay module-specific) ────────────
detect() {
command -v apt-get >/dev/null 2>&1
}

is_recommended() {
! is_installed
}

# doctor: real runtime health — the tool must be installed AND resolvable on
# PATH (iftop has no clean --version flag). Warns (read-only) on Sidecar
# drift (ADR-0001).
doctor() {
module_dryrun_guard doctor "is_installed + command -v iftop + Sidecar consistency" \
&& return 0
is_installed || { log_warn "[${NAME}] doctor: iftop is not installed"; return 1; }
command -v iftop >/dev/null 2>&1 \
|| { log_warn "[${NAME}] doctor: iftop binary not found on PATH"; return 1; }
if ! module_sidecar_get_version "${NAME}" >/dev/null 2>&1; then
log_warn "[${NAME}] doctor: Sidecar missing (ADR-0001 drift; re-run install/upgrade to heal)"
fi
return 0
}

# ── Standalone footer ───────────────────────────────────────────────────────
if [[ "${MODULE_STANDALONE:-false}" == "true" ]]; then
module_standalone_main "$@"
fi
Loading
Loading