pi-rust-skills 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +32 -0
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/SECURITY.md +18 -0
- package/examples/prompts.md +75 -0
- package/extensions/rust-skills.ts +182 -0
- package/package.json +70 -0
- package/references/RUST_AGENT_GUIDE.md +72 -0
- package/references/RUST_COMMANDS.md +69 -0
- package/scripts/list-skills.mjs +47 -0
- package/scripts/validate-skills.mjs +97 -0
- package/skills/rust-async-tokio/SKILL.md +92 -0
- package/skills/rust-build-cross/SKILL.md +54 -0
- package/skills/rust-cli/SKILL.md +113 -0
- package/skills/rust-code-review/SKILL.md +106 -0
- package/skills/rust-crate-publishing/SKILL.md +101 -0
- package/skills/rust-database/SKILL.md +57 -0
- package/skills/rust-debugging/SKILL.md +100 -0
- package/skills/rust-embedded-no-std/SKILL.md +55 -0
- package/skills/rust-ffi/SKILL.md +103 -0
- package/skills/rust-performance/SKILL.md +101 -0
- package/skills/rust-proc-macro/SKILL.md +55 -0
- package/skills/rust-project-bootstrap/SKILL.md +130 -0
- package/skills/rust-refactor-migration/SKILL.md +94 -0
- package/skills/rust-security-audit/SKILL.md +111 -0
- package/skills/rust-testing/SKILL.md +105 -0
- package/skills/rust-toolchain-ci/SKILL.md +102 -0
- package/skills/rust-wasm/SKILL.md +103 -0
- package/skills/rust-web-api/SKILL.md +48 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Rust Command Reference
|
|
2
|
+
|
|
3
|
+
## Toolchain
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
rustc --version
|
|
7
|
+
cargo --version
|
|
8
|
+
rustup show active-toolchain
|
|
9
|
+
rustup component add rustfmt clippy
|
|
10
|
+
rustup target list --installed
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Inspect project
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cargo metadata --no-deps --format-version 1
|
|
17
|
+
cargo tree
|
|
18
|
+
cargo tree -e features
|
|
19
|
+
cargo tree -d
|
|
20
|
+
cargo locate-project
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Build and test
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cargo check
|
|
27
|
+
cargo check --all-targets --all-features
|
|
28
|
+
cargo build
|
|
29
|
+
cargo build --release
|
|
30
|
+
cargo test
|
|
31
|
+
cargo test --all-features
|
|
32
|
+
cargo test test_name -- --nocapture
|
|
33
|
+
cargo test --doc
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Formatting and linting
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cargo fmt
|
|
40
|
+
cargo fmt --check
|
|
41
|
+
cargo clippy --all-targets --all-features -- -D warnings
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Documentation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
cargo doc --no-deps --open
|
|
48
|
+
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Publishing
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
cargo package --list
|
|
55
|
+
cargo package
|
|
56
|
+
cargo publish --dry-run
|
|
57
|
+
cargo publish
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Optional tools
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
cargo install cargo-audit cargo-deny cargo-nextest cargo-bloat cargo-expand
|
|
64
|
+
cargo audit
|
|
65
|
+
cargo deny check
|
|
66
|
+
cargo nextest run
|
|
67
|
+
cargo bloat --release --crates
|
|
68
|
+
cargo expand
|
|
69
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
const root = path.resolve(new URL("..", import.meta.url).pathname);
|
|
6
|
+
const skillsRoot = path.join(root, "skills");
|
|
7
|
+
|
|
8
|
+
async function walk(dir) {
|
|
9
|
+
const entries = await readdir(dir);
|
|
10
|
+
const skillDirs = [];
|
|
11
|
+
for (const entry of entries) {
|
|
12
|
+
const full = path.join(dir, entry);
|
|
13
|
+
const info = await stat(full);
|
|
14
|
+
if (!info.isDirectory()) continue;
|
|
15
|
+
try {
|
|
16
|
+
await stat(path.join(full, "SKILL.md"));
|
|
17
|
+
skillDirs.push(full);
|
|
18
|
+
} catch {
|
|
19
|
+
skillDirs.push(...(await walk(full)));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return skillDirs;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function frontmatter(content) {
|
|
26
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n/);
|
|
27
|
+
const fields = {};
|
|
28
|
+
if (!match) return fields;
|
|
29
|
+
for (const line of match[1].split("\n")) {
|
|
30
|
+
const idx = line.indexOf(":");
|
|
31
|
+
if (idx === -1) continue;
|
|
32
|
+
fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim().replace(/^['"]|['"]$/g, "");
|
|
33
|
+
}
|
|
34
|
+
return fields;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const rows = [];
|
|
38
|
+
for (const dir of await walk(skillsRoot)) {
|
|
39
|
+
const content = await readFile(path.join(dir, "SKILL.md"), "utf8");
|
|
40
|
+
const fm = frontmatter(content);
|
|
41
|
+
rows.push({ name: fm.name, description: fm.description });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const row of rows.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
45
|
+
console.log(`/skill:${row.name}`);
|
|
46
|
+
console.log(` ${row.description}`);
|
|
47
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
|
|
6
|
+
const root = path.resolve(new URL("..", import.meta.url).pathname);
|
|
7
|
+
const skillsRoot = path.join(root, "skills");
|
|
8
|
+
const namePattern = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
9
|
+
const errors = [];
|
|
10
|
+
const warnings = [];
|
|
11
|
+
|
|
12
|
+
async function walk(dir) {
|
|
13
|
+
const entries = await readdir(dir);
|
|
14
|
+
const skillDirs = [];
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
const full = path.join(dir, entry);
|
|
17
|
+
const info = await stat(full);
|
|
18
|
+
if (info.isDirectory()) {
|
|
19
|
+
try {
|
|
20
|
+
await stat(path.join(full, "SKILL.md"));
|
|
21
|
+
skillDirs.push(full);
|
|
22
|
+
} catch {
|
|
23
|
+
const nested = await walk(full);
|
|
24
|
+
skillDirs.push(...nested);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return skillDirs;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function parseFrontmatter(content, file) {
|
|
32
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n/);
|
|
33
|
+
if (!match) {
|
|
34
|
+
errors.push(`${file}: missing YAML frontmatter`);
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const fields = {};
|
|
39
|
+
for (const line of match[1].split("\n")) {
|
|
40
|
+
const idx = line.indexOf(":");
|
|
41
|
+
if (idx === -1) continue;
|
|
42
|
+
const key = line.slice(0, idx).trim();
|
|
43
|
+
let value = line.slice(idx + 1).trim();
|
|
44
|
+
value = value.replace(/^['"]|['"]$/g, "");
|
|
45
|
+
fields[key] = value;
|
|
46
|
+
}
|
|
47
|
+
return fields;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const skillDirs = await walk(skillsRoot);
|
|
51
|
+
const names = new Map();
|
|
52
|
+
|
|
53
|
+
for (const dir of skillDirs) {
|
|
54
|
+
const file = path.join(dir, "SKILL.md");
|
|
55
|
+
const rel = path.relative(root, file);
|
|
56
|
+
const content = await readFile(file, "utf8");
|
|
57
|
+
const fm = parseFrontmatter(content, rel);
|
|
58
|
+
|
|
59
|
+
if (!fm.name) errors.push(`${rel}: frontmatter requires name`);
|
|
60
|
+
if (!fm.description) errors.push(`${rel}: frontmatter requires description`);
|
|
61
|
+
|
|
62
|
+
if (fm.name && !namePattern.test(fm.name)) {
|
|
63
|
+
errors.push(`${rel}: invalid skill name '${fm.name}'`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (fm.name && fm.name.length > 64) {
|
|
67
|
+
errors.push(`${rel}: skill name exceeds 64 characters`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (fm.description && fm.description.length > 1024) {
|
|
71
|
+
errors.push(`${rel}: description exceeds 1024 characters`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (fm.name && names.has(fm.name)) {
|
|
75
|
+
errors.push(`${rel}: duplicate skill name '${fm.name}' also found in ${names.get(fm.name)}`);
|
|
76
|
+
}
|
|
77
|
+
if (fm.name) names.set(fm.name, rel);
|
|
78
|
+
|
|
79
|
+
if (!content.includes("## Workflow")) {
|
|
80
|
+
warnings.push(`${rel}: consider adding a '## Workflow' section`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (skillDirs.length === 0) errors.push("no skills found");
|
|
85
|
+
|
|
86
|
+
if (warnings.length > 0) {
|
|
87
|
+
console.warn("Warnings:");
|
|
88
|
+
for (const warning of warnings) console.warn(`- ${warning}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (errors.length > 0) {
|
|
92
|
+
console.error("Errors:");
|
|
93
|
+
for (const error of errors) console.error(`- ${error}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log(`Validated ${skillDirs.length} skills successfully.`);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-async-tokio
|
|
3
|
+
description: Builds and reviews Rust async code using Tokio, async traits, streams, channels, cancellation, task supervision, graceful shutdown, backpressure, and nonblocking I/O. Use for Rust networking, services, and async runtime work.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Tokio-based Rust projects or projects considering async Rust.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Rust Async Tokio
|
|
9
|
+
|
|
10
|
+
Use this skill when implementing or reviewing async Rust, especially Tokio services, clients, workers, daemons, queues, and network applications.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Inspect `Cargo.toml`, workspace shape, feature flags, target crates, and `rust_project_context` output when available.
|
|
15
|
+
2. Confirm whether async is actually needed. Do not add Tokio for simple CPU-bound or synchronous CLI work.
|
|
16
|
+
3. Identify runtime boundaries: binary entry point, library API, spawned tasks, blocking sections, and shutdown path.
|
|
17
|
+
4. Ensure every task has ownership, cancellation, supervision, and error reporting strategy.
|
|
18
|
+
5. Check that `.await` points do not hold mutex guards, borrowed temporaries, or other resources longer than intended.
|
|
19
|
+
6. Add integration tests for cancellation, timeout, graceful shutdown, and error paths.
|
|
20
|
+
|
|
21
|
+
## Tokio rules
|
|
22
|
+
|
|
23
|
+
- Use `tokio::spawn` for independent `Send + 'static` work.
|
|
24
|
+
- Use `tokio::task::spawn_blocking` for CPU-heavy or blocking filesystem/process work.
|
|
25
|
+
- Use `tokio::select!` for shutdown and cancellation.
|
|
26
|
+
- Prefer `JoinSet` for supervising groups of tasks.
|
|
27
|
+
- Prefer bounded channels for producer/consumer systems.
|
|
28
|
+
- Avoid `std::sync::Mutex` in async code when lock contention crosses `.await`; use `tokio::sync::Mutex` carefully or restructure ownership.
|
|
29
|
+
|
|
30
|
+
## Observability
|
|
31
|
+
|
|
32
|
+
- Use `tracing` spans around request, worker, queue, and task boundaries.
|
|
33
|
+
- Report task failures explicitly; do not detach tasks that can fail silently.
|
|
34
|
+
- Track queue depth, timeouts, retries, and shutdown duration when operating a service.
|
|
35
|
+
- Include enough context in errors to identify the runtime boundary that failed.
|
|
36
|
+
|
|
37
|
+
## Graceful shutdown pattern
|
|
38
|
+
|
|
39
|
+
```rust
|
|
40
|
+
let token = CancellationToken::new();
|
|
41
|
+
let worker_token = token.clone();
|
|
42
|
+
|
|
43
|
+
let worker = tokio::spawn(async move {
|
|
44
|
+
loop {
|
|
45
|
+
tokio::select! {
|
|
46
|
+
_ = worker_token.cancelled() => break,
|
|
47
|
+
result = do_one_unit_of_work() => {
|
|
48
|
+
result?;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
Ok::<_, anyhow::Error>(())
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
tokio::signal::ctrl_c().await?;
|
|
56
|
+
token.cancel();
|
|
57
|
+
worker.await??;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Use `tokio-util` only if the project already accepts that dependency or cancellation tokens are worth it.
|
|
61
|
+
|
|
62
|
+
## Async traits
|
|
63
|
+
|
|
64
|
+
- Native `async fn` in traits is fine when object safety is not required.
|
|
65
|
+
- Use boxed futures or `async-trait` only when dynamic dispatch is required and the tradeoff is acceptable.
|
|
66
|
+
- Document `Send` requirements when futures cross thread boundaries.
|
|
67
|
+
|
|
68
|
+
## Testing
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
cargo test --workspace --all-features
|
|
72
|
+
cargo test -p crate_name async_test_name -- --nocapture
|
|
73
|
+
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Use timeouts in tests to avoid hangs:
|
|
77
|
+
|
|
78
|
+
```rust
|
|
79
|
+
tokio::time::timeout(Duration::from_secs(1), operation()).await??;
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use `tokio::time::pause` and `advance` for timer-heavy code. Prefer channels, cancellation tokens, and controlled clocks over sleeps.
|
|
83
|
+
|
|
84
|
+
## Output expectations
|
|
85
|
+
|
|
86
|
+
Explain task ownership, cancellation behavior, backpressure, and validation commands. Flag any blocking or lock-across-await risks explicitly.
|
|
87
|
+
|
|
88
|
+
## Avoid
|
|
89
|
+
|
|
90
|
+
- Do not spawn untracked background tasks.
|
|
91
|
+
- Do not run blocking I/O or CPU-heavy work on executor worker threads.
|
|
92
|
+
- Do not use unbounded channels or unlimited task spawning when producers can outrun consumers.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-build-cross
|
|
3
|
+
description: Configures and reviews Rust build scripts, native dependencies, cc/pkg-config/cmake integration, target triples, linker settings, cross-compilation, platform-specific cfgs, and release packaging. Use for Rust builds that depend on native tooling or multiple platforms.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Rust stable. Cross builds may require target toolchains, linkers, native SDKs, pkg-config, cc, cmake, bindgen, or cross.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Rust Build Cross
|
|
9
|
+
|
|
10
|
+
Use this skill when Rust builds involve `build.rs`, native libraries, generated bindings, cross-compilation, custom linkers, or platform packaging.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Inspect `Cargo.toml`, workspace shape, feature flags, target crates, `.cargo/config.toml`, build scripts, and `rust_project_context` output when available.
|
|
15
|
+
2. Identify target triples, host tools, native dependencies, generated files, and linker requirements.
|
|
16
|
+
3. Make build scripts deterministic and explicit about rerun conditions.
|
|
17
|
+
4. Validate native and cross targets separately.
|
|
18
|
+
5. Document setup requirements for contributors and CI.
|
|
19
|
+
|
|
20
|
+
## Build script rules
|
|
21
|
+
|
|
22
|
+
- Emit `cargo:rerun-if-changed` and `cargo:rerun-if-env-changed` precisely.
|
|
23
|
+
- Prefer `pkg-config`, `cc`, `cmake`, or `bindgen` according to the dependency's build model.
|
|
24
|
+
- Keep generated files in `OUT_DIR` unless the project intentionally checks them in.
|
|
25
|
+
- Avoid network access and non-deterministic downloads in `build.rs`.
|
|
26
|
+
- Preserve useful error messages for missing SDKs, linkers, headers, or libraries.
|
|
27
|
+
|
|
28
|
+
## Cross-compilation
|
|
29
|
+
|
|
30
|
+
- Confirm host triple, target triple, linker, C compiler, and required system libraries.
|
|
31
|
+
- Use target-specific dependencies and `cfg` gates for platform code.
|
|
32
|
+
- Add `.cargo/config.toml` only when the project needs stable target configuration.
|
|
33
|
+
- Validate at least one native build before diagnosing cross-only failures.
|
|
34
|
+
|
|
35
|
+
## Commands
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cargo check --workspace --all-targets --all-features
|
|
39
|
+
cargo build --target target-triple
|
|
40
|
+
cargo test --workspace --all-features
|
|
41
|
+
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Use `cross build`, `zig cc`, or platform SDK commands only when the project already uses them or the target requires them.
|
|
45
|
+
|
|
46
|
+
## Avoid
|
|
47
|
+
|
|
48
|
+
- Do not hide native dependency failures by disabling features silently.
|
|
49
|
+
- Do not write generated files into source directories unless release policy requires it.
|
|
50
|
+
- Do not assume Linux linker settings work on macOS or Windows.
|
|
51
|
+
|
|
52
|
+
## Output expectations
|
|
53
|
+
|
|
54
|
+
Report host and target assumptions, native dependency requirements, build script changes, validation commands, and packaging implications.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-cli
|
|
3
|
+
description: Builds Rust command-line applications with clap, config files, environment variables, structured errors, logging, shell completions, tests, packaging, and cross-platform behavior. Use when creating or improving Rust CLI tools.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Rust stable toolchain. clap, tracing, serde, and assert_cmd are optional project dependencies.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Rust CLI
|
|
9
|
+
|
|
10
|
+
Use this skill for Rust command-line tools, developer utilities, admin tools, and terminal workflows.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Inspect `Cargo.toml`, workspace shape, feature flags, target crates, and `rust_project_context` output when available.
|
|
15
|
+
2. Define the CLI contract first: commands, flags, input/output, exit codes, and config precedence.
|
|
16
|
+
3. Keep `main.rs` thin. Put real logic in library modules that tests can call directly.
|
|
17
|
+
4. Use structured errors internally and user-friendly messages at the CLI boundary.
|
|
18
|
+
5. Add integration tests that execute the binary for critical commands.
|
|
19
|
+
6. Validate behavior on paths with spaces and platform-specific path separators.
|
|
20
|
+
|
|
21
|
+
## Recommended layout
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
src/
|
|
25
|
+
├── main.rs
|
|
26
|
+
├── cli.rs
|
|
27
|
+
├── config.rs
|
|
28
|
+
├── error.rs
|
|
29
|
+
└── commands/
|
|
30
|
+
├── mod.rs
|
|
31
|
+
└── scan.rs
|
|
32
|
+
tests/
|
|
33
|
+
└── cli.rs
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## clap pattern
|
|
37
|
+
|
|
38
|
+
```rust
|
|
39
|
+
use clap::{Parser, Subcommand};
|
|
40
|
+
|
|
41
|
+
#[derive(Debug, Parser)]
|
|
42
|
+
#[command(name = "tool-name", version, about)]
|
|
43
|
+
pub struct Cli {
|
|
44
|
+
#[arg(short, long, global = true)]
|
|
45
|
+
pub verbose: bool,
|
|
46
|
+
|
|
47
|
+
#[command(subcommand)]
|
|
48
|
+
pub command: Command,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#[derive(Debug, Subcommand)]
|
|
52
|
+
pub enum Command {
|
|
53
|
+
Scan { path: std::path::PathBuf },
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Error handling
|
|
58
|
+
|
|
59
|
+
- `main` should convert errors into stable exit codes and messages.
|
|
60
|
+
- Use `eprintln!` only at the boundary.
|
|
61
|
+
- Use `tracing` or `log` for diagnostics, not normal output.
|
|
62
|
+
- Keep stdout machine-readable when the command is designed for scripting.
|
|
63
|
+
|
|
64
|
+
## CLI contract
|
|
65
|
+
|
|
66
|
+
- Document config precedence, usually flags, environment, config file, then defaults.
|
|
67
|
+
- Reserve stdout for primary output and stderr for diagnostics, progress, and errors.
|
|
68
|
+
- Define stable exit codes for success, usage/config errors, input errors, and internal failures.
|
|
69
|
+
- Respect TTY behavior: color, progress bars, prompts, and paging should be disabled or configurable in non-interactive mode.
|
|
70
|
+
- Generate shell completions and manpages when the tool is meant for broad distribution.
|
|
71
|
+
|
|
72
|
+
## Testing commands
|
|
73
|
+
|
|
74
|
+
Useful dev dependencies:
|
|
75
|
+
|
|
76
|
+
```toml
|
|
77
|
+
[dev-dependencies]
|
|
78
|
+
assert_cmd = "2"
|
|
79
|
+
predicates = "3"
|
|
80
|
+
tempfile = "3"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Example:
|
|
84
|
+
|
|
85
|
+
```rust
|
|
86
|
+
#[test]
|
|
87
|
+
fn prints_help() {
|
|
88
|
+
let mut cmd = assert_cmd::Command::cargo_bin("tool-name").unwrap();
|
|
89
|
+
cmd.arg("--help").assert().success();
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Add golden output tests for stable help, JSON, or text output. Keep golden files small and review intentional changes.
|
|
94
|
+
|
|
95
|
+
## Validation
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
cargo fmt
|
|
99
|
+
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
100
|
+
cargo test --workspace --all-features
|
|
101
|
+
cargo test -p crate_name --test cli
|
|
102
|
+
cargo run -- --help
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Output expectations
|
|
106
|
+
|
|
107
|
+
Document the CLI contract, files changed, example invocations, and any future packaging steps such as shell completions, manpages, Homebrew, Scoop, or cargo-binstall.
|
|
108
|
+
|
|
109
|
+
## Avoid
|
|
110
|
+
|
|
111
|
+
- Do not mix diagnostics into machine-readable stdout.
|
|
112
|
+
- Do not make config precedence implicit.
|
|
113
|
+
- Do not add hidden panics for invalid user input.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-code-review
|
|
3
|
+
description: Reviews Rust code for correctness, ownership and lifetime issues, error handling, API design, unsafe usage, concurrency risks, performance traps, cargo features, tests, and idiomatic style. Use when asked to audit or improve Rust code.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Works best in a Cargo project with rustfmt, clippy, and tests available.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Rust Code Review
|
|
9
|
+
|
|
10
|
+
Use this skill for Rust pull request review, local code audit, bug-risk review, and idiomatic refactoring suggestions.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Gather context. Read `Cargo.toml`, workspace shape, feature flags, target crates, changed files, public APIs, tests, and any failure logs. Use `rust_project_context` when available.
|
|
15
|
+
2. Run or request validation commands where practical:
|
|
16
|
+
```bash
|
|
17
|
+
cargo fmt --check
|
|
18
|
+
cargo check --workspace --all-targets --all-features
|
|
19
|
+
cargo clippy --all-targets --all-features -- -D warnings
|
|
20
|
+
cargo test --all-features
|
|
21
|
+
```
|
|
22
|
+
3. Review in this priority order:
|
|
23
|
+
- Soundness and safety.
|
|
24
|
+
- Correctness and edge cases.
|
|
25
|
+
- Error handling and observability.
|
|
26
|
+
- API design and maintainability.
|
|
27
|
+
- Performance and allocation behavior.
|
|
28
|
+
- Tests and documentation.
|
|
29
|
+
4. Prefer actionable patches over broad commentary.
|
|
30
|
+
5. Do not suggest adding dependencies unless they simplify real complexity or reduce risk.
|
|
31
|
+
|
|
32
|
+
## Severity guide
|
|
33
|
+
|
|
34
|
+
- High: soundness, security, data loss, panics on normal input, or broken public contracts.
|
|
35
|
+
- Medium: incorrect edge cases, cancellation/resource leaks, portability bugs, or missing tests for risky behavior.
|
|
36
|
+
- Low: maintainability, clarity, docs, or style issues that do not change behavior.
|
|
37
|
+
|
|
38
|
+
## Rust-specific checklist
|
|
39
|
+
|
|
40
|
+
### Ownership and lifetimes
|
|
41
|
+
|
|
42
|
+
- Avoid unnecessary cloning. Prefer borrowing when lifetimes stay simple.
|
|
43
|
+
- Do not overuse explicit lifetimes; let elision work unless public API clarity improves.
|
|
44
|
+
- Watch for returning references tied to temporary values.
|
|
45
|
+
- Prefer owned return types when borrowing would make the API brittle.
|
|
46
|
+
|
|
47
|
+
### Errors
|
|
48
|
+
|
|
49
|
+
- Library code should usually return typed errors or `thiserror`-style enums.
|
|
50
|
+
- Application boundaries can use `anyhow`-style context.
|
|
51
|
+
- Preserve source errors and add context at I/O, network, parsing, and external process boundaries.
|
|
52
|
+
- Avoid `unwrap`, `expect`, and `panic` outside tests, examples, initialization invariants, or clearly documented impossible states.
|
|
53
|
+
|
|
54
|
+
### Unsafe code
|
|
55
|
+
|
|
56
|
+
- Flag every `unsafe` block for justification.
|
|
57
|
+
- Require a nearby safety comment explaining invariants.
|
|
58
|
+
- Check aliasing, initialization, lifetime extension, FFI contracts, and thread-safety assumptions.
|
|
59
|
+
- Prefer safe abstractions around unsafe internals.
|
|
60
|
+
|
|
61
|
+
### Async and concurrency
|
|
62
|
+
|
|
63
|
+
- Avoid holding locks across `.await`.
|
|
64
|
+
- Check that blocking work is not run on async executor workers.
|
|
65
|
+
- Prefer bounded channels when backpressure matters.
|
|
66
|
+
- Confirm cancellation behavior and task shutdown.
|
|
67
|
+
|
|
68
|
+
### API design
|
|
69
|
+
|
|
70
|
+
- Public APIs should use clear types, minimal generics, and docs with examples.
|
|
71
|
+
- Prefer `AsRef<Path>` for path-like inputs and `impl Into<String>` sparingly.
|
|
72
|
+
- Avoid exposing concrete dependency types unless they are part of the intended contract.
|
|
73
|
+
- Check MSRV, edition, feature flags, and semver compatibility before recommending public API changes.
|
|
74
|
+
- Treat public type names, trait bounds, error variants, feature defaults, and re-exports as compatibility surface.
|
|
75
|
+
|
|
76
|
+
### Feature and workspace coverage
|
|
77
|
+
|
|
78
|
+
- Review feature-gated code with `--all-features` and the default feature set when both matter.
|
|
79
|
+
- For workspaces, identify the affected package and run `cargo check -p crate_name --all-targets --all-features` when the full suite is too broad.
|
|
80
|
+
- Check generated code, proc macro expansion, and build scripts when the diff touches them.
|
|
81
|
+
|
|
82
|
+
## Review output format
|
|
83
|
+
|
|
84
|
+
Lead with findings. Use this structure:
|
|
85
|
+
|
|
86
|
+
```markdown
|
|
87
|
+
## Summary
|
|
88
|
+
|
|
89
|
+
## High-risk findings
|
|
90
|
+
|
|
91
|
+
## Correctness issues
|
|
92
|
+
|
|
93
|
+
## Maintainability improvements
|
|
94
|
+
|
|
95
|
+
## Suggested patch
|
|
96
|
+
|
|
97
|
+
## Validation
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
For each finding include: file, line or symbol, problem, why it matters, and a concrete fix.
|
|
101
|
+
|
|
102
|
+
## Avoid
|
|
103
|
+
|
|
104
|
+
- Do not bury high-risk findings below summaries.
|
|
105
|
+
- Do not recommend broad rewrites when a local fix resolves the issue.
|
|
106
|
+
- Do not weaken lints or tests without a clear compatibility reason.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-crate-publishing
|
|
3
|
+
description: Prepares Rust crates for publication to crates.io, including Cargo.toml metadata, README, license, docs, examples, semver, feature flags, cargo package checks, release tags, and post-publish validation. Use before publishing Rust crates.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Rust stable with cargo. crates.io publishing requires a configured registry token.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Rust Crate Publishing
|
|
9
|
+
|
|
10
|
+
Use this skill when preparing a Rust crate or workspace member for crates.io or an internal Cargo registry.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Inspect `Cargo.toml`, workspace shape, feature flags, target crates, and `rust_project_context` output when available.
|
|
15
|
+
2. Inspect README, license, public API, examples, tests, and release history.
|
|
16
|
+
3. Confirm crate name availability outside the code task; do not assume an unpublished name is available.
|
|
17
|
+
4. Ensure metadata is complete:
|
|
18
|
+
- `description`
|
|
19
|
+
- `license` or `license-file`
|
|
20
|
+
- `repository`
|
|
21
|
+
- `homepage` if useful
|
|
22
|
+
- `documentation` if custom
|
|
23
|
+
- `readme`
|
|
24
|
+
- `keywords` and `categories`
|
|
25
|
+
- `rust-version`
|
|
26
|
+
5. Confirm public API docs build without warnings.
|
|
27
|
+
6. Run package dry-run before publishing.
|
|
28
|
+
|
|
29
|
+
## Commands
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cargo fmt --check
|
|
33
|
+
cargo clippy --all-targets --all-features -- -D warnings
|
|
34
|
+
cargo test --all-features
|
|
35
|
+
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
|
|
36
|
+
cargo semver-checks
|
|
37
|
+
cargo package --allow-dirty --list
|
|
38
|
+
cargo package
|
|
39
|
+
cargo publish --dry-run
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Use `--allow-dirty` only for inspection. Do not publish dirty working trees.
|
|
43
|
+
Use `cargo semver-checks` when installed or when a public crate is being released from an existing version.
|
|
44
|
+
|
|
45
|
+
## Cargo.toml metadata template
|
|
46
|
+
|
|
47
|
+
```toml
|
|
48
|
+
[package]
|
|
49
|
+
name = "crate-name"
|
|
50
|
+
version = "0.1.0"
|
|
51
|
+
edition = "2024"
|
|
52
|
+
rust-version = "1.85"
|
|
53
|
+
description = "One-sentence description under 200 characters."
|
|
54
|
+
license = "MIT OR Apache-2.0"
|
|
55
|
+
repository = "https://github.com/user/repo"
|
|
56
|
+
readme = "README.md"
|
|
57
|
+
keywords = ["rust", "cli"]
|
|
58
|
+
categories = ["command-line-utilities"]
|
|
59
|
+
exclude = [".github/", "target/"]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Semver rules
|
|
63
|
+
|
|
64
|
+
- `0.x` can still break users; document breaking changes.
|
|
65
|
+
- Public type names, trait bounds, features, and error variants are API.
|
|
66
|
+
- Removing a feature flag or changing default features can be breaking.
|
|
67
|
+
- Prefer additive changes for patch/minor releases.
|
|
68
|
+
- Check MSRV changes, default feature changes, and re-export changes as compatibility events.
|
|
69
|
+
|
|
70
|
+
## Workspace publishing
|
|
71
|
+
|
|
72
|
+
- Publish dependency crates before crates that depend on them.
|
|
73
|
+
- Confirm every workspace member has correct `version`, `license`, `repository`, and `readme` metadata.
|
|
74
|
+
- Use `cargo publish -p crate_name --dry-run` for each publishable member.
|
|
75
|
+
- Do not publish private helper crates accidentally; set `publish = false` where needed.
|
|
76
|
+
|
|
77
|
+
## Release safety
|
|
78
|
+
|
|
79
|
+
- Verify crates.io owners and registry token setup outside the repository.
|
|
80
|
+
- Never print or store registry tokens in logs, docs, or scripts.
|
|
81
|
+
- Create a release tag only after the publish command succeeds.
|
|
82
|
+
- After publishing, install or depend on the published version in a clean temporary project for a smoke check.
|
|
83
|
+
|
|
84
|
+
## README checklist
|
|
85
|
+
|
|
86
|
+
- What the crate does.
|
|
87
|
+
- Install command.
|
|
88
|
+
- Minimal example.
|
|
89
|
+
- Feature flags.
|
|
90
|
+
- MSRV if set.
|
|
91
|
+
- License.
|
|
92
|
+
|
|
93
|
+
## Output expectations
|
|
94
|
+
|
|
95
|
+
Report readiness, missing metadata, dry-run results, and exact publish command. Never claim a publish succeeded unless the publish command was actually run and returned success.
|
|
96
|
+
|
|
97
|
+
## Avoid
|
|
98
|
+
|
|
99
|
+
- Do not publish from a dirty working tree.
|
|
100
|
+
- Do not assume workspace version bumps are harmless.
|
|
101
|
+
- Do not remove old feature flags or defaults without documenting the breaking change.
|