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.
@@ -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.