Skip to content

Commit 8a0e173

Browse files
UnbreakableMJAntigravity (Gemini 3.5 Flash)
andcommitted
Add spacecraft-nu-guidelines skill
- Create spacecraft-nu-guidelines/SKILL.md with detailed Nushell script guidelines. - Create spacecraft-nu-guidelines/references/idioms.md with Bash-to-Nushell equivalents. - Create spacecraft-nu-guidelines/references/modules.md with module, overlay, and main command guidelines. - Update README.md alphabetical skill catalog table. - Build spacecraft-nu-guidelines.zip and spacecraft-nu-guidelines.skill bundles. Co-Authored-By: Antigravity (Gemini 3.5 Flash) <noreply@google.com>
1 parent 57a5772 commit 8a0e173

6 files changed

Lines changed: 475 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ the rules re-attached to every prompt.
5555
| [`spacecraft-missing-pkg`](spacecraft-missing-pkg/) | Handles missing-package situations in the Spacecraft Software workflow. |
5656
| [`spacecraft-nickel-guidelines`](spacecraft-nickel-guidelines/) | Expert guidelines for writing high-quality, correct, maintainable, and type-safe Nickel configuration code — contracts, merging, priorities, and import options. |
5757
| [`spacecraft-nim-guidelines`](spacecraft-nim-guidelines/) | Type-safe highly-concurrent Nim guidance (targeting Nim 2.0+) — ARC/ORC deterministic memory management, move semantics (`sink`/`lent`), structured parallelism via `Malebolgia`, asynchronous networking with `Chronos`, safe FFI custom destructors (`=destroy`), and warnings-as-errors compiler configuration. |
58+
| [`spacecraft-nu-guidelines`](spacecraft-nu-guidelines/) | Expert guidelines for writing high-performance, clean, and type-safe Nushell (Nu) script code — structured data pipelines, variables and mutability, custom commands, environment management, and error handling. |
5859
| [`spacecraft-ocamel-guidelines`](spacecraft-ocamel-guidelines/) | Type-safe highly-concurrent OCaml guidance — direct-style I/O fibers via `Eio` and Domainslib task parallelism pools, Saturn lock-free structures, Software Transactional Memory with Kcas, C FFI memory safety (`CAMLparam`/`CAMLlocal`/`CAMLreturn`), and warning-as-errors compilation flags. |
5960
| [`spacecraft-python-guidelines`](spacecraft-python-guidelines/) | Type-safe highly-concurrent Python guidance (targeting Python 3.12+) — strict static typing (`mypy`), boundary validation (`Pydantic v2`), non-blocking asynchronous event loops (`asyncio`), multiprocess CPU scaling (`ProcessPoolExecutor`), memory-optimized slots classes, and Ruff linting rules. |
6061
| [`spacecraft-rust-guidelines`](spacecraft-rust-guidelines/) | High-performance concurrent Rust guidance — concurrency model selection, lock-free synchronisation, memory layout, tooling gates, and unsafe hygiene — plus a distilled idiom layer (`references/idioms.md`, adapted from Apollo's Rust Best Practices, MIT) covering borrowing, clippy discipline, testing, dispatch, and type-state. |

spacecraft-nu-guidelines.skill

7.89 KB
Binary file not shown.

spacecraft-nu-guidelines.zip

8.09 KB
Binary file not shown.

spacecraft-nu-guidelines/SKILL.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
---
2+
name: spacecraft-nu-guidelines
3+
description: Expert guidelines for writing high-performance, clean, and type-safe Nushell (Nu) script code. Triggers on any request involving Nushell scripts, command definitions, custom pipelines, closures, modules, environment variables, or config.nu configurations. By Spacecraft Software.
4+
---
5+
6+
# Spacecraft Nushell Guidelines
7+
8+
**You are an expert Nushell (Nu) systems and language engineer at Spacecraft Software.** Always follow these rules when writing, reviewing, or refactoring Nushell script files (`.nu`) or terminal pipelines. Never deviate. These guidelines ensure type safety, correct environment scoping, efficient pipeline execution, and clean, readable scripting.
9+
10+
---
11+
12+
## Core Philosophy
13+
14+
- **Pipelines of Structured Data**: Nushell communicates via typed structures (tables, records, lists, paths) rather than untyped raw byte/text streams. Avoid string-parsing hacks.
15+
- **Fail Early with Parsed Checking**: Nushell parses and checks the entire script (including types, command names, and imports) before executing a single line. Ensure type annotations are precise.
16+
- **Value-Centric Execution**: Every command and block returns a value. There are no "statements" that produce nothing; even commands that exit normally return `null` (`nothing`).
17+
- **Implicit Returns**: The last evaluated expression in a function, block, or pipeline is automatically returned. Avoid verbose `return` keywords.
18+
19+
---
20+
21+
## Mandatory Syntax & Layout Conventions
22+
23+
### 1. Spacing & Operators
24+
- **Mandatory Single Space**: Put exactly one space before and after the pipe operator `|`, variable assignment `=`, arithmetic/comparison operators, and between arguments/options.
25+
- **Correct**: `let result = 4 + 2; ls | where size > 1mb`
26+
- **Incorrect**: `let result=4+2`, `ls|where size>1mb`, `ls | where size > 1mb` (consecutive spaces are forbidden unless inside a string).
27+
- **Operators vs. Redirection**: In Nushell, `>` is strictly the greater-than operator, not file redirection. Use pipes and the `save` command or native redirection operators (`o>`, `e>`, `o+e>`).
28+
- **Correct**: `"Hello" | save output.txt` or `"Hello" o> output.txt`
29+
- **Incorrect**: `echo "Hello" > output.txt`
30+
31+
### 2. Lists & Records
32+
- **Omit Commas**: Do not use commas to separate items in lists or fields in records. Commas are optional and discouraged in Spacecraft Software style.
33+
- **Correct**: `let list = [1 2 3]`, `let record = {name: "Alice" role: "admin"}`
34+
- **Incorrect**: `let list = [1, 2, 3]`, `let record = {name: "Alice", role: "admin"}`
35+
- **Spacing inside delimiters**:
36+
- Lists: Put no spaces right after the opening `[` or before the closing `]`.
37+
- **Correct**: `[1 2 3]`
38+
- Records & Blocks: Put exactly one space after `{` and before `}`.
39+
- **Correct**: `{ name: "Alice" }`
40+
- **Incorrect**: `{name: "Alice"}`
41+
42+
### 3. Blocks & Closures
43+
- **Parameter formatting**: Put one space after separating commas and one space after the closing parameter pipe `|`.
44+
- **Correct**: `{ |x, y| $x + $y }`
45+
- **Incorrect**: `{|x,y|$x + $y}`, `{ |x,y| $x + $y }`
46+
- **Line length**:
47+
- Keep interactive one-liners under 80 characters.
48+
- For scripts, wrap pipelines, lists, or records exceeding 80 characters onto multiple lines:
49+
```nu
50+
# Multi-line pipeline
51+
ls
52+
| where size > 50mb
53+
| sort-by modified
54+
| first 5
55+
```
56+
57+
---
58+
59+
## Variables & Mutability
60+
61+
Choose the variable declaration keyword based on timing and mutability:
62+
63+
| Keyword | Timing | Reassignable | Use Cases |
64+
| :--- | :--- | :--- | :--- |
65+
| **`let`** | Runtime | No (Immutable) | Normal variables, pipeline intermediates, temporary values. |
66+
| **`mut`** | Runtime | Yes (Mutable) | Loop accumulators, complex state tracking, iterative building. |
67+
| **`const`** | Parse-time | No (Constant) | Module import paths, static configuration, compile-time metadata. |
68+
69+
### Variable Mutation Rules
70+
- **Sigil Requirement**: Use the `$` prefix whenever referencing, reassigning, or mutating a variable.
71+
- **Correct**: `mut x = 1; $x = 2; $x += 1`
72+
- **Incorrect**: `mut x = 1; x = 2; x += 1`
73+
- **Closure Restrictions**: Closures (`{ |x| ... }`) cannot capture mutable variables (`mut`). If a closure needs to update a value, use `reduce` or pass values explicitly instead of mutating outer variables.
74+
- **Correct**:
75+
```nu
76+
# Functional reduction
77+
let total = ([1 2 3] | reduce --fold 0 { |item, acc| $acc + $item })
78+
```
79+
- **Incorrect**:
80+
```nu
81+
mut total = 0
82+
[1 2 3] | each { |item| $total += $item } # Fails: Closure cannot capture mutable variable
83+
```
84+
85+
---
86+
87+
## Custom Commands (`def`)
88+
89+
Custom commands are typed, self-documenting functions.
90+
91+
### 1. Naming & Documentation
92+
- **Kebab-Case**: Command names must be lower-case kebab-case (e.g., `get-latest-logs`).
93+
- **Help Text**: Always provide description comments immediately above the command definition. These are parsed to populate the `help` system.
94+
95+
### 2. Signatures & Types
96+
- **Explicit Annotations**: Annotate all parameters and return types.
97+
```nu
98+
# Calculates the square of an integer
99+
def square [
100+
num: int # The number to square
101+
] {
102+
$num * $num
103+
}
104+
```
105+
- **Supported Types**: `int`, `string`, `bool`, `float`, `path`, `glob`, `record`, `table`, `list`, `closure`, `nothing`, `any`.
106+
- **Input/Output Signatures**: Specify stream types using `->` when writing custom pipe filters:
107+
```nu
108+
# Filters a list of strings
109+
def filter-strings []: list<string> -> list<string> {
110+
where ($it | str length) > 5
111+
}
112+
```
113+
114+
### 3. Parameters, Flags, & Defaults
115+
- **Optional parameters**: Append `?` to the parameter name (e.g., `path?: path`).
116+
- **Default values**: Provide defaults using `=` (e.g., `port: int = 8080`).
117+
- **Flags (switches)**: Prefix flags with `--`. Add a single-character short-form using a pipe `|` if useful.
118+
- Optional flag: `--verbose` (resolves to boolean `true`/`false`).
119+
- Typed flag: `--timeout: duration` (expects value when flag is used).
120+
```nu
121+
# Starts a spacecraft telemetry connection
122+
def connect [
123+
address: string
124+
--timeout: duration = 30s # Timeout limit
125+
--secure (-s) # Enable TLS
126+
] { ... }
127+
```
128+
- **Wrappers**: Use `def --wrapped` to wrap external commands, capturing excess arguments in a `...rest` parameter.
129+
```nu
130+
# Wrapped git execution
131+
def --wrapped git-run [...rest: string] {
132+
^git ...$rest
133+
}
134+
```
135+
136+
---
137+
138+
## Environment Management
139+
140+
Environment variables in Nushell are lexically scoped.
141+
142+
### 1. Modifying `$env`
143+
- **Direct Assignment**: Use `$env.VAR_NAME = value`. Do **not** use the deprecated `let-env` command.
144+
- **Extending PATH**: Always use `prepend` or `append` to modify path lists.
145+
- **Correct**: `$env.PATH = ($env.PATH | prepend "/opt/bin")`
146+
- **Temporary Scope**: Use `with-env` to restrict environment variables to a single block.
147+
```nu
148+
with-env { DATABASE_URL: "sqlite://space.db" } {
149+
^space-migrations run
150+
}
151+
```
152+
153+
### 2. Module Environment Exports
154+
- **export-env**: Use `export-env` blocks inside modules to expose environment modifications to importing shells.
155+
```nu
156+
# env-manager.nu
157+
export-env {
158+
$env.MISSION_STATUS = "active"
159+
}
160+
```
161+
162+
---
163+
164+
## Pipelines & Redirection
165+
166+
### 1. External Commands (`^`)
167+
- **Prefix Guard**: Always prefix external commands with `^` if a Nushell built-in exists with the same name, or to explicitly indicate an external binary.
168+
- **Correct**: `^ls -la` (system ls) vs `ls` (Nushell table generator).
169+
170+
### 2. Redirection Operators
171+
Use explicit operators instead of POSIX numbers (`2>&1`). Redirections work primarily with external commands:
172+
- `o>` (or `out>`): Redirect standard output to file.
173+
- `e>` (or `err>`): Redirect standard error to file.
174+
- `o+e>` (or `out+err>`): Redirect both stdout and stderr to the same file.
175+
- `e>|`: Pipe standard error into the next command in the pipeline.
176+
- `o+e>|`: Pipe both stdout and stderr into the next command.
177+
178+
### 3. Capturing Outputs (`complete`)
179+
- **Capture Record**: Use the `complete` command to collect stdout, stderr, and the numeric exit code of an external command.
180+
```nu
181+
let run = (do { ^cargo build } | complete)
182+
if $run.exit_code != 0 {
183+
error make {msg: $"Build failed with error: ($run.stderr)"}
184+
}
185+
```
186+
187+
---
188+
189+
## Control Flow & Error Handling
190+
191+
### 1. Expressions vs. Statements
192+
- **If Expressions**: In Nushell, `if` is an expression. Both `if` and `else` branches must return compatible types.
193+
- **Correct**: `let mode = (if $debug { "verbose" } else { "quiet" })`
194+
- **Match Patterns**: Use `match` for complex branching and record deconstruction:
195+
```nu
196+
match $status {
197+
{ state: "nominal", count: $c } => $"Status OK with ($c) telemetry entries"
198+
{ state: "warning" } => "Caution: check sensors"
199+
_ => "Critical failure"
200+
}
201+
```
202+
203+
### 2. Error Trapping (`try/catch`)
204+
- **Explicit catch**: Always use `try { ... } catch { |err| ... }` when invoking external calls or dangerous code that could crash.
205+
```nu
206+
try {
207+
http get "https://invalid-telemetry.space/api"
208+
} catch { |err|
209+
print $"Failed to fetch data: ($err.msg)"
210+
}
211+
```
212+
213+
---
214+
215+
## Anti-Patterns to Avoid
216+
217+
-**Using `echo` to log/print**: `echo` returns a value, which can corrupt the output of commands or subexpressions. Use `print` to log info to the terminal instead.
218+
-**POSIX redirection syntax**: Writing `cmd > out.txt 2>&1`. Use `cmd o+e> out.txt`.
219+
-**POSIX substitution syntax**: Writing `$(cmd)`. Use bare parentheses `(cmd)`.
220+
-**Bash chain execution**: Using `cmd1 && cmd2`. In Nushell, write `cmd1; if ($env.LAST_EXIT_CODE == 0) { cmd2 }` or use separate lines.
221+
-**No spaces around operators**: Writing `$a+$b` or `$x=$y`. Always put spaces: `$a + $b` and `$x = $y`.
222+
-**Parsing table output with grep/awk**: Piping `ls` output to external grep. Instead, use native filters: `ls | where name =~ "test"`.
223+
224+
---
225+
226+
## Pre-Commit / Code Audit Checklist
227+
228+
- [ ] All pipes (`|`), equals (`=`), and math/comparison operators have exactly one space on both sides.
229+
- [ ] No commas are used in lists `[1 2 3]` or records `{a: 1 b: 2}`.
230+
- [ ] Block and closure curly braces have a single space inside: `{ foo }` and `{ |x| foo }`.
231+
- [ ] No deprecated `let-env` is used; all environment variables are set with `$env.VAR = value`.
232+
- [ ] External command calls that override/shadow built-ins (or might be ambiguous) are prefixed with `^`.
233+
- [ ] `echo` is not used for terminal log printing; `print` is used instead.
234+
- [ ] Type annotations are added to all custom command parameters and custom commands that filter streams.
235+
- [ ] Closures are checked to ensure they do not capture mutable `mut` variables.
236+
- [ ] Checked for POSIX commands/substitutions like `$(...)` or `&&` and converted to Nushell equivalents.
237+
238+
When the user asks to write, edit, or audit Nushell code, apply these guidelines immediately. Present clear feedback citing these specific rules if violations are detected.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Nushell Idiomatic Patterns & Translation Reference
2+
3+
This document provides quick reference tables and side-by-side examples to translate common Bash patterns into idiomatic Nushell code.
4+
5+
---
6+
7+
## 1. Quick Translation Targets
8+
9+
| Bash Pattern | Nushell Equivalent | Notes |
10+
| :--- | :--- | :--- |
11+
| `val="hello"` | `let val = "hello"` | Variables are immutable by default. |
12+
| `val="new"` (reassign) | `mut val = "init"; $val = "new"` | Reassignment requires the `mut` keyword. |
13+
| `export VAR="value"` | `$env.VAR = "value"` | Env variables are stored in the `$env` record. |
14+
| `$(command)` | `(command)` | Standard parentheses denote command substitution. |
15+
| `cmd1 && cmd2` | `cmd1; if ($env.LAST_EXIT_CODE == 0) { cmd2 }` | Nushell has no `&&` short-circuiting for external commands. |
16+
| `cmd > out.txt 2>&1` | `cmd out+err> out.txt` | Stream redirection operator. |
17+
| `if [ -f path ]; then ...` | `if ("path" \| path exists) { ... }` | Use path inspection pipelines. |
18+
| `for f in *.rs; do ...` | `ls *.rs \| each { \|f\| ... }` | Prefer pipelines with closures over loops. |
19+
| `function name { ... }` | `def name [] { ... }` | Custom command definition. |
20+
21+
---
22+
23+
## 2. Common Scripting Scenarios
24+
25+
### Checking File Existence and Attributes
26+
In Bash, you use various `-f`, `-d`, `-e` flags with the `test` command. In Nushell, use the `path` family of commands.
27+
28+
#### Bash:
29+
```bash
30+
if [ -f "telemetry.log" ]; then
31+
echo "Found file"
32+
fi
33+
```
34+
35+
#### Nushell:
36+
```nu
37+
if ("telemetry.log" | path exists) and ("telemetry.log" | path type) == "file" {
38+
print "Found file"
39+
}
40+
```
41+
42+
---
43+
44+
### Executing Loops and Pipeline Maps
45+
Nushell processes lists and tables using pipelines. Avoid standard `for` loops in favor of `each` and `filter` closures.
46+
47+
#### Bash:
48+
```bash
49+
for file in *.json; do
50+
if grep -q "active" "$file"; then
51+
echo "Active: $file"
52+
fi
53+
done
54+
```
55+
56+
#### Nushell:
57+
```nu
58+
ls *.json
59+
| filter { |file| (open $file.name | get status?) == "active" }
60+
| each { |file| print $"Active: ($file.name)" }
61+
```
62+
63+
---
64+
65+
### Temporary Environment Scopes
66+
Run a command with temporary environment variables.
67+
68+
#### Bash:
69+
```bash
70+
PORT=9000 DEBUG=true node server.js
71+
```
72+
73+
#### Nushell:
74+
```nu
75+
with-env { PORT: 9000 DEBUG: "true" } {
76+
^node server.js
77+
}
78+
```
79+
80+
---
81+
82+
### Finding and Invoking Actions Recursively
83+
Nushell's globbing is built into `ls` and `glob`.
84+
85+
#### Bash:
86+
```bash
87+
find . -name "*.log" -exec rm {} \;
88+
```
89+
90+
#### Nushell:
91+
```nu
92+
ls **/*.log | each { |file| rm $file.name }
93+
```
94+
95+
---
96+
97+
## 3. Working with Nushell Tables
98+
99+
Nushell commands return structured tables. Here are the most common operations for table manipulation:
100+
101+
### Filtering Columns (`select` & `reject`)
102+
- Use `select` to keep specific columns.
103+
- Use `reject` to discard specific columns.
104+
105+
```nu
106+
# Keep only name and size
107+
ls | select name size
108+
109+
# Discard the type column
110+
ls | reject type
111+
```
112+
113+
### Filtering Rows (`where`)
114+
- Use boolean conditions to filter records.
115+
116+
```nu
117+
# Find large files modified recently
118+
ls | where size > 10mb and modified > ((date now) - 1hr)
119+
```
120+
121+
### Accessing Inner Values (`get`)
122+
- Extract a column as a list, or query a nested record path.
123+
124+
```nu
125+
# Get names as a list of strings
126+
let names = (ls | get name)
127+
128+
# Nested record extraction
129+
let port = ({ server: { config: { port: 8080 } } } | get server.config.port)
130+
```

0 commit comments

Comments
 (0)