Skip to content

Commit 0c8a6ff

Browse files
UnbreakableMJclaude
andcommitted
skills: retarget spacecraft-cli-preference at the local host
Companion to 6a01665, which did the same for spacecraft-missing-pkg. The preference stack is unchanged — no tool is re-ranked. What changes is that a substitution is now conditional on the machine it lands on. Three gates, applied before anything is emitted: - Availability (§1.1). Substituting to a tool that isn't installed turns a working command into `command not found`. Probe once, then route: present -> substitute; preferred absent but legacy present -> legacy plus a `# preferred: <tool>` note; both absent -> ephemeral run via spacecraft-missing-pkg. On this host that last branch is real: the table maps dig -> dog and neither is installed. - Execution class (§1.2). The agent's shell has no TTY, yet ~20 entries are full-screen TUIs. Each now names its headless sibling (bottom -> procs, gitui -> git/jj, trip -> trip --mode report) or is marked hand-off. A separate class covers system-mutating tools, including two with destructive *defaults*: `kondo -a` deletes with no confirmation and `fclones remove` deletes files. sudo-rs is never run by the agent. - Target (§1.0). One table, three audiences: what the agent runs, what gets committed to a repo, and what the user is handed to run. A committed `eza` breaks the build for everyone without it. Also: - Install hints across all 110 reference mastheads rewritten to defer to spacecraft-missing-pkg while keeping package identity. They previously carried 92 x `cargo install`, 6 x `paru -S`, 3 x `pacman -S`, 3 x `npm install -g`, 2 x `pip install`, `nix-env` and `nix profile install` -- every one of them a prohibition in the sibling skill. - Shell-integration tools (zoxide, atuin, starship, broot, gitway) route to `programs.<tool>.enable`; hand-editing an rc file stays prohibited. - Package rows gated on host type: paru is Arch-only, and topgrade/omni/zap/am drift a declaratively managed host rather than serving it. - Consent banners added to kondo, fclones, gptman, disktui, topgrade, paru. - §1.3 separates the shell the agent invokes from the shell a script is authored for -- §1.5's Nushell/Ion cascade governs the latter only. New reference: local-execution.md. Version 1.1, description 985 chars (cap 1000). Bundles rebuilt at 114 files. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6a01665 commit 0c8a6ff

115 files changed

Lines changed: 488 additions & 138 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ the rules re-attached to every prompt.
3838
| [`spacecraft-carbon-guidelines`](spacecraft-carbon-guidelines/) | Type-safe highly-interoperable Carbon guidance — introducers (`let`/`var`), null safety (`Optional(T)`), bidirectional C++ interoperability (`import Cpp`), safety build profiles (debug/hardened), and C++ thread/atomic integrations. |
3939
| [`spacecraft-chez-guidelines`](spacecraft-chez-guidelines/) | Functional, safe, concurrent Chez Scheme guidance — R6RS libraries + Akku, pure-first design, `optimize-level` as the safety lever (level 3 = `unsafe`), hand-built mailboxes/channels over real threads (no Fibers), the FFI + AOT/whole-program compilation, and Guile-habit guardrails. |
4040
| [`spacecraft-clang-guidelines`](spacecraft-clang-guidelines/) | Memory-safe highly-hardened C guidance — NASA Power of 10 Rules (no runtime heap allocation, bounded loops, small functions, high assertion density), MISRA C safety subsets, CERT C secure coding rules, Clang `-fbounds-safety` compiler extensions, and C11 atomics. |
41-
| [`spacecraft-cli-preference`](spacecraft-cli-preference/) | Modern CLI substitutions: `eza` for `ls`, `rg` for `grep`, `gitway` for Git SSH, etc. |
41+
| [`spacecraft-cli-preference`](spacecraft-cli-preference/) | Modern CLI substitutions: `eza` for `ls`, `rg` for `grep`, `gitway` for Git SSH, etc. Conditional on the local host — substitute only when the tool is installed, fall back to the legacy tool with a note when it isn't, never launch a TUI in the agent's TTY-less shell, and get consent before anything that mutates or deletes. |
4242
| [`spacecraft-cli-standard`](spacecraft-cli-standard/) | Enforces the Spacecraft Software Dual-Mode Self-Documenting CLI Standard (v1.0.0) on every CLI. |
4343
| [`spacecraft-cli-shell`](spacecraft-cli-shell/) | Syntax-compliance guard for Nushell / Ion / POSIX / Bash commands. |
4444
| [`spacecraft-clojure-guidelines`](spacecraft-clojure-guidelines/) | Functional, safe-concurrent Clojure guidance — immutable-first design, reference-type decision tree (atoms / refs+STM / agents / core.async), transducers, lazy-seq discipline, ClojureScript and Babashka platform notes, and `standard-clj` formatting. |

spacecraft-cli-preference.skill

10.7 KB
Binary file not shown.

spacecraft-cli-preference.zip

10.7 KB
Binary file not shown.

spacecraft-cli-preference/SKILL.md

Lines changed: 156 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
---
22
name: spacecraft-cli-preference
33
description: >
4-
Enforces Spacecraft Software's CLI tool preferences. Whenever an agent is about to
5-
generate, run, or recommend a shell command — in any context, including
6-
bash snippets, scripts, CI, docs, or agentic tool use — the agent must first
7-
check the command-mapping table in this skill and substitute the preferred
8-
alternative for any legacy tool that has one. Examples: `eza` instead of
9-
`ls`, `bat` for `cat`, `rg` for `grep`, `fd` for `find`, `jaq` for `jq`,
10-
`xh` for `curl`, `dog` for `dig`, `procs` for `ps`, `bottom` for `top`.
11-
Trigger on any mention of shell commands, terminal use, scripting, file
12-
search, process inspection, network diagnostics, archive handling, text
13-
editing, git, package management, or system monitoring. When invoking a
14-
specific alternative, first consult the matching reference file in the
15-
references directory for correct flag syntax.
4+
Enforces Spacecraft Software's CLI tool preferences. Whenever an agent is
5+
about to generate, run, or recommend a shell command — bash snippets,
6+
scripts, CI, docs, or agentic tool use — check this skill's command-mapping
7+
table first and substitute the preferred alternative for any legacy tool
8+
that has one: `eza` for `ls`, `bat` for `cat`, `rg` for `grep`, `fd` for
9+
`find`, `jaq` for `jq`, `xh` for `curl`, `dog` for `dig`, `procs` for `ps`,
10+
`bottom` for `top`. Trigger on any mention of shell commands, scripting,
11+
file search, process inspection, network diagnostics, archive handling,
12+
text editing, git, package management, or system monitoring. Consult the
13+
matching reference file for flag syntax before invoking.
14+
Substitution is conditional on the local host: substitute only when the
15+
preferred tool is installed, fall back to the legacy tool with a note when
16+
it is not, never launch a TUI in the agent's TTY-less shell, and get
17+
consent before any command that mutates or deletes.
1618
license: GPL-3.0-or-later
1719
maintainer: Mohamed Hammad <Mohamed.Hammad@SpacecraftSoftware.org>
1820
website: https://Construct.SpacecraftSoftware.org/
1921
---
2022

2123
# Spacecraft Software CLI Preference — Modern Alternatives over Legacy Tools
2224

23-
**Version:** 1.0 | **Date:** 2026-05-18 | **Author:** Mohamed Hammad
25+
**Version:** 1.1 | **Date:** 2026-07-24 | **Author:** Mohamed Hammad
2426
**Maintainer:** Mohamed Hammad | **Contact:** [Mohamed.Hammad@SpacecraftSoftware.org](mailto:Mohamed.Hammad@SpacecraftSoftware.org)
2527
**Copyright:** (C) 2026 Mohamed Hammad & Spacecraft Software | **License:** GPL-3.0-or-later
2628
**Website:** [https://Construct.SpacecraftSoftware.org/](https://Construct.SpacecraftSoftware.org/)
@@ -45,12 +47,97 @@ a command appears.
4547
If §3 has no specific row for the legacy tool, apply the cascading fallback in
4648
§1.5 (`uutils` for GNU coreutils, Brush for Bash-only scripts).
4749

48-
### Shell-syntax awareness
50+
**This runs on the user's own machine.** The preference stack below is
51+
unchanged, but on a real host a substitution is only correct if the tool is
52+
actually installed, the agent's shell can actually execute it, and the command
53+
does not silently change or delete something. §1.1–§1.3 are those three gates;
54+
apply them before emitting anything.
4955

50-
Mohamed's primary shells are **Nushell** and **Ion**. Some command patterns
51-
(piping into `xargs`, command substitution `$(…)`, `&&`/`||` chaining) behave
52-
differently in those shells. When in doubt, prefer the portable POSIX form,
53-
but flag it if the user is clearly working inside a specific non-Bash shell.
56+
### §1.0 — Substitution depends on the target
57+
58+
The same mapping table serves three audiences that need different behaviour:
59+
60+
| Target | Rule |
61+
|---|---|
62+
| A command **the agent runs** in its own shell | Substitute only if the tool is present (§1.1), the command is headless-safe (§1.2), and it is non-destructive (§1.2). The agent's shell is a non-interactive Bash with no TTY — regardless of the user's interactive shell. |
63+
| A command **written into the user's repo** — script, CI job, `Justfile`, docs | Substitute only if the repo's own environment guarantees the tool: a devShell, a documented prerequisite, a CI image that ships it. Otherwise keep the portable form and add `# preferred: <tool>`. A committed `eza` breaks the build for every contributor without it. |
64+
| A command **suggested for the user to run** interactively | Full preference applies, TUIs included — this is where `gitui`, `yazi`, `bottom`, and `helix` belong. Hand it over with the `!` prefix rather than running it. |
65+
66+
### §1.1 — Check availability before substituting
67+
68+
A substitution to a tool that isn't installed is worse than no substitution:
69+
it turns a working command into `command not found`. Probe first, then route:
70+
71+
| Preferred | Legacy | Action |
72+
|---|---|---|
73+
| present || **Substitute.** The happy path. |
74+
| present | absent | **Substitute** — it is the only option (e.g. `jaq` where `jq` was never installed). |
75+
| absent | present | **Use the legacy tool** and append `# preferred: <tool> — see references/<tool>.md`. Do not fail, do not silently install. |
76+
| absent | absent | **Route to `spacecraft-missing-pkg`** for an ephemeral run (`nix run nixpkgs#<pkg> -- …`). Neither form exists, so provisioning is the only way through. |
77+
78+
```sh
79+
command -v eza >/dev/null 2>&1 && echo substitute || echo fall-back
80+
```
81+
82+
Probe once per session and reuse the answer — don't re-check before every
83+
command. `command -v` alone under-reports: Nushell `def`s, Bash functions, and
84+
non-default bin directories hide installed tools from it. Use
85+
`spacecraft-missing-pkg`'s Step 0 checklist rather than restating it here.
86+
87+
### §1.2 — Execution classes
88+
89+
Every tool in §3 falls into one of four classes. Detail, per-tool headless
90+
alternatives, and the destructive-flag catalogue are in
91+
**[references/local-execution.md](references/local-execution.md)**.
92+
93+
**Headless-safe — the agent may run these directly.**
94+
`eza`, `bat`, `fd`, `rg`, `sd`, `dust`, `procs`, `jaq`, `ouch`, `delta`,
95+
`just`, `tokei`, `uutils`, `xh`, `wget2`, `dog`, `monolith`, `lychee`,
96+
`macchina`, `oxipng`, `gifski`, `rav1e`, `viu`, `yt-dlp`, `jj`, `tokei`,
97+
`dua` (non-interactive form), `fclones group`.
98+
99+
**Needs a TTY — hand off, or use the headless sibling.** Never launch these in
100+
the agent's shell; they hang, garble the transcript, or exit with a terminal
101+
error. Prefer the alternative when the goal is information, hand off when the
102+
goal is interaction:
103+
104+
`bottom``procs` · `dua i``dua` · `gitui``git` / `jj` ·
105+
`yazi` / `broot` / `superfile``fd` / `eza` · `trip``trip --mode report` ·
106+
`gping``ping` · `atuin` TUI → `atuin search` · `zellij`, `kmon`, `impala`,
107+
`linutil`, editors (`hx`, `amp`, `rsvim`, `msedit`), chat TUIs (`iamb`,
108+
`rumatui`, `disrust`, `rivetui`), media TUIs (`ncspot`, `termusic`,
109+
`radio-browser`), `t-rec`, and the agent REPLs → hand off.
110+
111+
**System-mutating or destructive — get consent, or hand off.** State what will
112+
change and wait:
113+
114+
`topgrade`, `paru`, `omni`, `zap`, `am`, `rustup`, `cargo-update`, `gptman`,
115+
`disktui`, `nmstate`, `lanzaboote`, `greetd` / `lemurs` / `tuigreet`,
116+
`xremap`, `iwd`, `dotter`, `podman`. Two have destructive *defaults* worth
117+
naming: **`kondo -a` deletes build artifacts with no confirmation** and
118+
**`fclones remove` deletes files**. **`sudo-rs` is never run by the agent**
119+
same rule as `sudo`; hand it over.
120+
121+
**Shell-integration — declarative config, never a hand-edited rc.** `zoxide`,
122+
`atuin`, `starship`, `broot --install`, `gitway --install` all work by writing
123+
init lines into the user's shell config. Do not edit `.bashrc` / `config.nu` /
124+
`.profile`. On a managed host these are `programs.<tool>.enable` in Home
125+
Manager — propose that edit and let the user apply it
126+
(`spacecraft-missing-pkg` Band C).
127+
128+
### §1.3 — Shell syntax: whose shell?
129+
130+
Two separate questions, routinely conflated:
131+
132+
- **The shell the agent invokes.** Whatever the harness gives it — here a
133+
non-interactive Bash. Its commands must be valid *there*, no matter what the
134+
user's login shell is.
135+
- **The shell a script is authored for.** That follows the user's preference
136+
and Standard §7 (Nushell, Ion, Brush, and Bash are all first-class); a
137+
script committed to a repo stays POSIX unless the repo says otherwise.
138+
139+
`spacecraft-cli-shell` is the syntax authority for both — consult it rather
140+
than guessing at `^`-prefixes, `$(…)`, or `&&` behaviour per shell.
54141

55142
---
56143

@@ -61,14 +148,20 @@ tool that has no explicit row, or a context where a shell has to be chosen.
61148
In both cases apply the cascade below — **always go as far up the list as
62149
possible** before dropping to the next tier.
63150

64-
### Shells (when the AI picks or emits shell syntax)
151+
### Shells (when the AI **authors** a script or code example for the user)
152+
153+
This cascade governs what the agent *writes*, not what it *runs* — see §1.3.
154+
65155
1. **Nushell** 🦀 or **Ion** 🦀 — both are Mohamed's primaries, both are Rust.
66156
Default to one of these for any new script, one-liner, or code example.
67157
2. **Brush** 🦀 — only when Bash-compatibility is strictly required (e.g. a
68158
script must run under a `bash` interpreter and Nushell/Ion aren't options).
69159
3. **Plain Bash / POSIX `sh`** — last resort, only when the target environment
70160
hard-requires it (CI runner defaults, portability to unknown systems).
71161

162+
A script **committed to a repo** inverts this: portability wins, so POSIX `sh`
163+
is the default there unless the repo already standardises on another shell.
164+
72165
### GNU utilities (when substituting a legacy coreutils binary)
73166
1. **Specific Rust alternative from §3**`rg`, `fd`, `eza`, `bat`, `sd`,
74167
`procs`, `dust`, `jaq`, etc. Always check §3 first.
@@ -162,6 +255,17 @@ Read files with a plain file-view operation — each is short (typically 40–12
162255

163256
### Package & system management
164257

258+
> **Gate.** These rows say *which* manager is preferred, not that the agent may
259+
> run it. Provisioning policy belongs to **`spacecraft-missing-pkg`**: prefer
260+
> an ephemeral run, put persistent tools in the host's declarative config, and
261+
> get consent before any durable install. Never run a system-wide update
262+
> unprompted.
263+
>
264+
> **Host-appropriateness matters.** `paru` is Arch-only; `topgrade`, `omni`,
265+
> `zap`, and `am` fight a declaratively managed host (NixOS, Home Manager,
266+
> Guix) by installing outside its config. On such a host the answer is the
267+
> host's own manager, not a row from this table.
268+
165269
| Use case | Prefer | Ref file | Notes |
166270
|---------------------|-----------------------|-------------------------------|-------------------------------------------|
167271
| universal package mgr | `omni` 🦀 | `references/omni.md` | Cross-distro bridge |
@@ -302,13 +406,39 @@ procs rustc
302406
xh https://api.github.com/repos/UnbreakableMJ/Understand-Anything
303407
```
304408

409+
### When the gates change the answer
410+
411+
```bash
412+
# Preferred tool absent, legacy present → fall back and note it
413+
dig +short example.com A # preferred: dog — see references/dog.md
414+
415+
# Both absent → ephemeral run via spacecraft-missing-pkg, not a failing command
416+
nix run nixpkgs#dog -- example.com A
417+
418+
# TTY-class tool, agent needs the information → headless sibling
419+
procs rustc # not `btm`, which needs a terminal
420+
421+
# TTY-class tool, user wants the interaction → hand off
422+
! gitui
423+
424+
# Destructive default → propose, don't run
425+
# kondo -a would delete target/ and node_modules/ under ~/projects — confirm?
426+
```
427+
305428
---
306429

307430
## §5 — When NOT to Substitute
308431

432+
- **The preferred tool isn't installed** (§1.1). Fall back to the legacy tool
433+
with a note — never emit a command that will fail.
434+
- **The command would run in the agent's shell but needs a TTY** (§1.2). Use
435+
the headless sibling, or hand the TUI to the user.
436+
- **The command mutates or deletes** (§1.2) and consent hasn't been given.
309437
- **Explicit user request** for the legacy tool ("show me the raw `grep` command").
310438
- **Portable scripts** the user will run on systems without the Rust stack
311439
installed (document the alternative as a comment but keep the portable form).
440+
This includes anything **committed to a repo** whose environment doesn't
441+
guarantee the tool.
312442
- **Compatibility-critical pipelines** where a specific tool's exact output
313443
format is required by downstream tooling.
314444
- **The legacy tool is already the Spacecraft Software-sanctioned choice** for that slot
@@ -325,7 +455,7 @@ Each file in `references/` follows this structure:
325455
```markdown
326456
# <tool>
327457

328-
**Replaces:** <legacy tool(s)> | **Language:** 🦀/⚡/🐹/🐍/(λ)/⚠️ | **Install:** <package hint>
458+
**Replaces:** <legacy tool(s)> | **Language:** 🦀/⚡/🐹/🐍/(λ)/⚠️ | **Install:** via `spacecraft-missing-pkg` (<upstream package identity>)
329459

330460
## Purpose
331461
<One paragraph — what it does and when to reach for it.>
@@ -343,6 +473,12 @@ Each file in `references/` follows this structure:
343473
- <edge cases, non-POSIX behaviour, config requirements, etc.>
344474
```
345475

476+
The `**Install:**` field names *what* the tool is published as — a crate, an
477+
npm package, a distro package, an upstream release — and defers the *how* to
478+
`spacecraft-missing-pkg`. It never carries a runnable install command:
479+
`cargo install`, `paru -S`, `npm install -g`, `pip install`, `nix-env`, and
480+
`nix profile install` are prohibited there, as they are everywhere else.
481+
346482
---
347483

348484
## §7 — Attribution

spacecraft-cli-preference/references/adguardvpn-cli.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# AdGuard VPN CLI
22

3-
**Replaces:** manual VPN dial-up | **Language:** 🐹 Go | **Install:** AdGuard official installer
3+
**Replaces:** manual VPN dial-up | **Language:** 🐹 Go | **Install:** via `spacecraft-missing-pkg` (upstream installer (AdGuard official))
44

55
## Purpose
66
Command-line client for AdGuard VPN. Manage connection, protocols, DNS, split-tunnel.

spacecraft-cli-preference/references/aichat.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# aichat
22

3-
**Replaces:** multiple per-vendor LLM CLIs | **Language:** 🦀 Rust | **Install:** `cargo install aichat`
3+
**Replaces:** multiple per-vendor LLM CLIs | **Language:** 🦀 Rust | **Install:** via `spacecraft-missing-pkg` (upstream crate: `aichat`)
44

55
## Purpose
66
Universal LLM REPL + CLI. One tool for OpenAI, Claude, Gemini, local Ollama, llama.cpp, Azure, Bedrock, and more. Supports RAG, agents, function-calling.

spacecraft-cli-preference/references/am.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# am (AppMan)
22

3-
**Replaces:** manual AppImage management | **Language:** ⚠️ Bash | **Install:** upstream install script
3+
**Replaces:** manual AppImage management | **Language:** ⚠️ Bash | **Install:** via `spacecraft-missing-pkg` (upstream install script)
44

55
## Purpose
66
Bash-based AppImage manager. Lightweight, no daemon, extensive catalog. Secondary choice after `zap`.

spacecraft-cli-preference/references/amp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# amp
22

3-
**Replaces:** `vim` (minimal alternative) | **Language:** 🦀 Rust | **Install:** `cargo install amp`
3+
**Replaces:** `vim` (minimal alternative) | **Language:** 🦀 Rust | **Install:** via `spacecraft-missing-pkg` (upstream crate: `amp`)
44

55
## Purpose
66
Vi-inspired terminal editor. Smaller footprint than Helix, simpler than Vim, no plugin system.

spacecraft-cli-preference/references/atuin.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# atuin
22

3-
**Replaces:** native shell history, `fc`, reverse-i-search (Ctrl+R) | **Language:** 🦀 Rust | **Install:** `cargo install atuin`
3+
**Replaces:** native shell history, `fc`, reverse-i-search (Ctrl+R) | **Language:** 🦀 Rust | **Install:** via `spacecraft-missing-pkg` (upstream crate: `atuin`)
44

55
## Purpose
66
SQLite-backed shell history with fuzzy full-text search, per-directory/host/session context, optional end-to-end encrypted sync across machines.

spacecraft-cli-preference/references/bandwhich.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# bandwhich
22

3-
**Replaces:** `iftop`, `nethogs` | **Language:** 🦀 Rust | **Install:** `cargo install bandwhich`
3+
**Replaces:** `iftop`, `nethogs` | **Language:** 🦀 Rust | **Install:** via `spacecraft-missing-pkg` (upstream crate: `bandwhich`)
44

55
## Purpose
66
Per-process/per-connection bandwidth monitor. Shows which process is using how much in real time.

0 commit comments

Comments
 (0)