cue-ai 0.5.0 → 0.7.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/README.md +757 -110
- package/package.json +5 -5
- package/profiles/README.md +12 -12
- package/profiles/SCHEMA.md +31 -3
- package/profiles/_cache/README.md +1 -1
- package/profiles/_types.ts +26 -1
- package/profiles/backend/profile.yaml +1 -0
- package/profiles/career/profile.yaml +13 -0
- package/profiles/core/profile.yaml +76 -9
- package/profiles/creative-media/README.md +1 -1
- package/profiles/cybersecurity/profile.yaml +779 -756
- package/profiles/ecc/profile.yaml +39 -0
- package/profiles/event-design/profile.yaml +10 -0
- package/profiles/fleet-control/README.md +1 -1
- package/profiles/frontend/profile.yaml +14 -0
- package/profiles/full/README.md +1 -1
- package/profiles/go-api/profile.yaml +1 -0
- package/profiles/marketing/profile.yaml +12 -1
- package/profiles/predict-everything/profile.yaml +9 -0
- package/profiles/rust/profile.yaml +22 -3
- package/profiles/rust-cli/profile.yaml +14 -0
- package/profiles/rust-core/profile.yaml +35 -0
- package/profiles/rust-embedded/profile.yaml +11 -0
- package/profiles/rust-ffi/profile.yaml +13 -0
- package/profiles/rust-game/profile.yaml +11 -0
- package/profiles/rust-wasm/profile.yaml +11 -0
- package/profiles/rust-web/profile.yaml +17 -0
- package/profiles/schema.json +44 -4
- package/profiles/trendradar/profile.yaml +11 -0
- package/resources/mcps/README.md +39 -164
- package/resources/mcps/configs/claude.sanitized.json +55 -0
- package/resources/mcps/configs/claude_runtime.sanitized.json +47 -0
- package/resources/skills/README.md +70 -113
- package/resources/skills/skills/event-design/wedding-invitations/SKILL.md +43 -0
- package/resources/skills/skills/meta/acpx/SKILL.md +78 -0
- package/resources/skills/skills/meta/cue-usage/SKILL.md +24 -0
- package/resources/skills/skills/meta/profile-fit-monitor/SKILL.md +24 -0
- package/resources/skills/skills/predict-everything/mirofish/SKILL.md +75 -0
- package/resources/skills/skills/research/trendradar/SKILL.md +88 -0
- package/resources/skills/skills/rust/async-tokio/SKILL.md +27 -0
- package/resources/skills/skills/rust/axum-api/SKILL.md +38 -0
- package/resources/skills/skills/rust/bacon-watch/SKILL.md +24 -0
- package/resources/skills/skills/rust/bevy/SKILL.md +43 -0
- package/resources/skills/skills/rust/bindgen/SKILL.md +39 -0
- package/resources/skills/skills/rust/cargo-audit/SKILL.md +26 -0
- package/resources/skills/skills/rust/cargo-basics/SKILL.md +28 -0
- package/resources/skills/skills/rust/cargo-chef/SKILL.md +43 -0
- package/resources/skills/skills/rust/cargo-edit/SKILL.md +26 -0
- package/resources/skills/skills/rust/cargo-expand/SKILL.md +24 -0
- package/resources/skills/skills/rust/cargo-flamegraph/SKILL.md +26 -0
- package/resources/skills/skills/rust/cargo-fuzz/SKILL.md +34 -0
- package/resources/skills/skills/rust/cargo-hack/SKILL.md +26 -0
- package/resources/skills/skills/rust/cargo-msrv/SKILL.md +30 -0
- package/resources/skills/skills/rust/cargo-mutants/SKILL.md +26 -0
- package/resources/skills/skills/rust/cargo-nextest/SKILL.md +24 -0
- package/resources/skills/skills/rust/cargo-readme/SKILL.md +36 -0
- package/resources/skills/skills/rust/cbindgen/SKILL.md +41 -0
- package/resources/skills/skills/rust/chisel-tool/SKILL.md +32 -0
- package/resources/skills/skills/rust/clap-cli/SKILL.md +44 -0
- package/resources/skills/skills/rust/clippy-and-fmt/SKILL.md +25 -0
- package/resources/skills/skills/rust/cross-compile/SKILL.md +26 -0
- package/resources/skills/skills/rust/embedded/SKILL.md +33 -0
- package/resources/skills/skills/rust/error-handling/SKILL.md +32 -0
- package/resources/skills/skills/rust/just-runner/SKILL.md +26 -0
- package/resources/skills/skills/rust/mdbook/SKILL.md +25 -0
- package/resources/skills/skills/rust/napi-rs/SKILL.md +32 -0
- package/resources/skills/skills/rust/no-std/SKILL.md +42 -0
- package/resources/skills/skills/rust/property-testing/SKILL.md +35 -0
- package/resources/skills/skills/rust/pyo3/SKILL.md +40 -0
- package/resources/skills/skills/rust/ratatui-tui/SKILL.md +36 -0
- package/resources/skills/skills/rust/release-plz/SKILL.md +27 -0
- package/resources/skills/skills/rust/reqwest/SKILL.md +37 -0
- package/resources/skills/skills/rust/sccache/SKILL.md +28 -0
- package/resources/skills/skills/rust/serde/SKILL.md +30 -0
- package/resources/skills/skills/rust/snapshot-testing/SKILL.md +30 -0
- package/resources/skills/skills/rust/sqlx-cli/SKILL.md +33 -0
- package/resources/skills/skills/rust/tracing/SKILL.md +36 -0
- package/resources/skills/skills/rust/typos-spellcheck/SKILL.md +31 -0
- package/resources/skills/skills/rust/uniffi/SKILL.md +38 -0
- package/resources/skills/skills/rust/wasm-rust/SKILL.md +27 -0
- package/resources/skills/skills/security/agentshield/SKILL.md +119 -0
- package/src/commands/_index.ts +47 -3
- package/src/commands/cli.test.ts +192 -0
- package/src/commands/cli.ts +303 -0
- package/src/commands/current.ts +1 -1
- package/src/commands/debug.test.ts +62 -0
- package/src/commands/debug.ts +212 -0
- package/src/commands/discover.scoring.test.ts +216 -0
- package/src/commands/discover.test.ts +145 -0
- package/src/commands/discover.ts +2618 -0
- package/src/commands/eval-behavior.test.ts +56 -0
- package/src/commands/eval-behavior.ts +189 -0
- package/src/commands/eval.test.ts +102 -0
- package/src/commands/eval.ts +348 -0
- package/src/commands/evolve.ts +291 -0
- package/src/commands/failures.test.ts +78 -0
- package/src/commands/failures.ts +393 -0
- package/src/commands/feedback.ts +219 -0
- package/src/commands/init.ts +26 -0
- package/src/commands/launch.e2e.test.ts +9 -1
- package/src/commands/launch.ts +174 -11
- package/src/commands/lint-skill.ts +157 -0
- package/src/commands/marketplace.ts +763 -2
- package/src/commands/new.ts +1 -1
- package/src/commands/optimizer.ts +92 -28
- package/src/commands/profile-draft-skill.test.ts +96 -0
- package/src/commands/profile-draft-skill.ts +287 -0
- package/src/commands/profile-evolve.test.ts +126 -0
- package/src/commands/profile-evolve.ts +0 -0
- package/src/commands/profile-suggest.ts +223 -0
- package/src/commands/profile.ts +41 -0
- package/src/commands/quick.ts +2 -17
- package/src/commands/scan.ts +2 -2
- package/src/commands/score.ts +1 -1
- package/src/commands/share.ts +1 -1
- package/src/commands/sources.ts +2 -2
- package/src/commands/submit-profile.ts +262 -0
- package/src/commands/upgrade.ts +1 -1
- package/src/commands/use.ts +35 -5
- package/src/commands/validate.ts +1 -1
- package/src/index.ts +66 -0
- package/src/lib/analytics.ts +48 -2
- package/src/lib/claude-binary.ts +39 -0
- package/src/lib/cli-extractor.ts +77 -0
- package/src/lib/cluster-skills.test.ts +268 -0
- package/src/lib/cluster-skills.ts +290 -0
- package/src/lib/credentials-sync.test.ts +208 -0
- package/src/lib/credentials-sync.ts +205 -0
- package/src/lib/mcp-materializer.test.ts +1 -1
- package/src/lib/persona-playbooks.test.ts +111 -0
- package/src/lib/pr-poster.test.ts +243 -0
- package/src/lib/pr-poster.ts +285 -0
- package/src/lib/pr-throttle.test.ts +148 -0
- package/src/lib/pr-throttle.ts +209 -0
- package/src/lib/profile-generator.test.ts +1 -1
- package/src/lib/profile-generator.ts +2 -2
- package/src/lib/profile-linter.test.ts +6 -3
- package/src/lib/profile-linter.ts +71 -8
- package/src/lib/profile-loader.test.ts +1 -1
- package/src/lib/profile-loader.ts +16 -0
- package/src/lib/resolver-local.test.ts +1 -1
- package/src/lib/resolver-npx.test.ts +76 -1
- package/src/lib/resolver-npx.ts +35 -3
- package/src/lib/resolver-plugins.test.ts +1 -1
- package/src/lib/runtime-materializer.test.ts +191 -7
- package/src/lib/runtime-materializer.ts +310 -42
- package/src/lib/scan-plugins.test.ts +1 -1
- package/src/lib/skill-linter.test.ts +174 -0
- package/src/lib/skill-linter.ts +507 -0
- package/src/lib/skill-subset.test.ts +95 -0
- package/src/lib/skill-subset.ts +166 -0
- package/src/lib/star-prompt.ts +1 -1
- package/src/lib/uvx-installer.test.ts +229 -0
- package/src/lib/uvx-installer.ts +278 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cross-compile
|
|
3
|
+
description: Use when building a Rust binary for a different target — ARM, musl, Windows, Android — without setting up native toolchains.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(cross:*), Bash(rustup:*), Bash(docker:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# cross — zero-fuss cross-compilation
|
|
8
|
+
|
|
9
|
+
Wraps Docker containers with the right linkers/sysroots so you don't deal with them.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- Static musl binary (deploy to Alpine / scratch container): `cross build --release --target x86_64-unknown-linux-musl`
|
|
13
|
+
- aarch64 (Raspberry Pi, ARM server): `cross build --release --target aarch64-unknown-linux-gnu`
|
|
14
|
+
- Windows from Linux/Mac: `cross build --release --target x86_64-pc-windows-gnu`
|
|
15
|
+
- Test on a non-native target: `cross test --target <triple>`
|
|
16
|
+
- Custom toolchain: `Cross.toml` at repo root to pin image / env vars
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
- cross (`cargo install cross --git https://github.com/cross-rs/cross`)
|
|
20
|
+
- Docker (or Podman with `CROSS_CONTAINER_ENGINE=podman`)
|
|
21
|
+
- The target installed once: `rustup target add <triple>` (cross handles the rest)
|
|
22
|
+
|
|
23
|
+
## Notes
|
|
24
|
+
- For `wasm32-unknown-unknown` use cargo directly with `--target` — cross isn't needed.
|
|
25
|
+
- musl builds are larger statically; strip with `strip` or `[profile.release] strip = true`.
|
|
26
|
+
- macOS targets from Linux are NOT supported by cross (licensing). Use a real Mac or GitHub Actions runner.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: embedded
|
|
3
|
+
description: Use when flashing, debugging, or developing for microcontrollers in Rust (Cortex-M, RISC-V, ESP32). Covers probe-rs, cargo-embed, defmt, embassy async runtime.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(probe-rs:*), Bash(cargo-embed:*), Bash(cargo-binutils:*), Bash(rustup:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rust embedded — probe-rs + embassy
|
|
8
|
+
|
|
9
|
+
Modern Rust embedded stack: probe-rs replaces OpenOCD, defmt replaces printf, embassy provides async on bare metal.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Target setup** (Cortex-M example): `rustup target add thumbv7em-none-eabihf` (M4F) or `thumbv6m-none-eabi` (M0)
|
|
13
|
+
- **Project layout**: `no_std` binary crate; `[build] target = "thumbv7em-none-eabihf"` in `.cargo/config.toml`
|
|
14
|
+
- **HAL** (Hardware Abstraction Layer): pick per chip — `stm32f4xx-hal`, `rp2040-hal`, `esp-hal`, etc.
|
|
15
|
+
- **Flash + run**: `cargo embed --release` (uses `Embed.toml` config, opens RTT terminal)
|
|
16
|
+
- **Just flash**: `cargo flash --chip STM32F411VETx --release`
|
|
17
|
+
- **Debug**: `probe-rs gdb --chip <name>` then connect with arm-none-eabi-gdb / VSCode probe-rs-debugger
|
|
18
|
+
- **Logging on-device**: `defmt` + `defmt-rtt` — host-side decoded via `defmt-print` (probe-rs integrates it)
|
|
19
|
+
- **Async on bare metal**: `embassy-executor` + `embassy-time` + `embassy-{stm32,rp,esp32}` — proper async without an OS
|
|
20
|
+
- **Binary size analysis**: `cargo size --release` (needs `cargo-binutils` + `llvm-tools-preview`)
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
- cargo
|
|
24
|
+
- probe-rs CLI (installs `probe-rs`, `cargo-embed`, `cargo-flash`)
|
|
25
|
+
- `rustup component add llvm-tools-preview` + `cargo install cargo-binutils`
|
|
26
|
+
- USB debugger: ST-Link, J-Link, CMSIS-DAP, Black Magic Probe, etc.
|
|
27
|
+
- Linux: udev rules — see https://probe.rs/docs/getting-started/probe-setup/
|
|
28
|
+
|
|
29
|
+
## Notes
|
|
30
|
+
- `no_std` means no `std::*` — use `core::*` and `alloc::*` (if you opt into an allocator).
|
|
31
|
+
- Panic behavior: declare one — `panic-halt`, `panic-probe`, `panic-rtt-target`. The linker errors if none.
|
|
32
|
+
- Embassy vs RTIC: embassy = async-first, easier; RTIC = priority-based preemptive, deterministic. Pick by problem.
|
|
33
|
+
- For ESP32 (Xtensa or RISC-V), use the `esp-rs` toolchain (espup) — the upstream rustc only covers RISC-V ESP32-C* parts.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: error-handling
|
|
3
|
+
description: Use when designing Rust error types — choosing between thiserror (libraries) and anyhow (apps), wrapping foreign errors, returning Result from main.
|
|
4
|
+
allowed-tools: Bash(cargo:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rust Error Handling
|
|
8
|
+
|
|
9
|
+
Pick the right tool for the layer.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Library crate**: define a typed error with `thiserror::Error` — callers should be able to `match` on variants.
|
|
13
|
+
```rust
|
|
14
|
+
#[derive(thiserror::Error, Debug)]
|
|
15
|
+
pub enum MyError {
|
|
16
|
+
#[error("io: {0}")] Io(#[from] std::io::Error),
|
|
17
|
+
#[error("bad input")] BadInput,
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
- **Binary / app**: use `anyhow::Result<T>` for fast prototyping and `.context("doing X")` to add breadcrumbs.
|
|
21
|
+
- **main**: return `anyhow::Result<()>` so `?` works at the top level — exit code becomes 1 on Err with a stderr trace.
|
|
22
|
+
- **Propagate, don't `.unwrap()`**: use `?`. Reserve `.unwrap()` / `.expect("invariant: ...")` for things that genuinely cannot happen.
|
|
23
|
+
- **Convert across layers**: `#[from]` in thiserror auto-implements `From`, so `?` upcasts without a `.map_err()`.
|
|
24
|
+
|
|
25
|
+
## Prerequisites
|
|
26
|
+
- cargo
|
|
27
|
+
- crates: `thiserror`, `anyhow` (add via `cargo add`)
|
|
28
|
+
|
|
29
|
+
## Notes
|
|
30
|
+
- Don't expose anyhow in a library's public API — it erases type info and hurts downstream `match`-ability. Wrap with thiserror at the boundary.
|
|
31
|
+
- `.expect()` messages should describe the broken invariant ("config loaded before this call"), not just restate the operation.
|
|
32
|
+
- `Result<T, Box<dyn Error + Send + Sync>>` is the stdlib alternative to anyhow when you don't want a dep.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: just-runner
|
|
3
|
+
description: Use when authoring or running project task recipes — Rust ecosystem's de-facto replacement for Make. Justfile syntax.
|
|
4
|
+
allowed-tools: Bash(just:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# just — sane task runner
|
|
8
|
+
|
|
9
|
+
Make without the tab/dependency-graph pain. Ubiquitous in Rust repos.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- List recipes: `just` or `just --list`
|
|
13
|
+
- Run a recipe: `just <name>` · pass args: `just test foo`
|
|
14
|
+
- Recipe with deps: `release: test lint` runs test + lint first
|
|
15
|
+
- Set vars: `just <var>=val build`
|
|
16
|
+
- Project-local: `Justfile` at repo root
|
|
17
|
+
- User-local: `~/.justfile` (run with `just -g`)
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
- just (distro pkg preferred — apt/brew/pacman/dnf all have it)
|
|
21
|
+
|
|
22
|
+
## Notes
|
|
23
|
+
- Default shell is `sh` on Unix, `cmd` on Windows. Set `set shell := ["bash", "-uc"]` at the top of the Justfile for portable bash semantics.
|
|
24
|
+
- Use `@` prefix to silence the recipe echo (`@cargo test`).
|
|
25
|
+
- For Rust projects, common recipes: `check`, `test`, `lint` (= `cargo clippy --all -- -D warnings`), `fmt`, `ci` (= chain of all of the above).
|
|
26
|
+
- Don't reinvent: if a `Justfile` exists, run those recipes rather than re-typing cargo flags.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mdbook
|
|
3
|
+
description: Use when authoring Rust project documentation as a static site — Rust Book / The Cargo Book / clap docs style.
|
|
4
|
+
allowed-tools: Bash(mdbook:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# mdbook
|
|
8
|
+
|
|
9
|
+
Markdown → static HTML site. The standard for Rust ecosystem long-form docs.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- New book: `mdbook init <dir>` (or in place: `mdbook init`)
|
|
13
|
+
- Dev server with live reload: `mdbook serve --open`
|
|
14
|
+
- Build: `mdbook build` → outputs to `book/`
|
|
15
|
+
- Test code samples in the book compile: `mdbook test`
|
|
16
|
+
- Lint links: `mdbook-linkcheck` (separate preprocessor crate)
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
- mdbook
|
|
20
|
+
|
|
21
|
+
## Notes
|
|
22
|
+
- Chapter list lives in `src/SUMMARY.md` — order there controls sidebar order.
|
|
23
|
+
- Code fences default to `rust` and get `mdbook test`'ed when language is `rust` (not `rust,ignore`).
|
|
24
|
+
- For API-reference style docs, prefer `cargo doc` — mdbook is for prose / tutorials.
|
|
25
|
+
- Deploy `book/` directly to GitHub Pages, Netlify, or any static host.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: napi-rs
|
|
3
|
+
description: Use when exposing Rust to Node.js — write a native addon via N-API. The path NextSwc, Parcel, and Prisma's query engine take.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(napi:*), Bash(npm:*), Bash(node:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# napi-rs — Rust → Node.js native addons
|
|
8
|
+
|
|
9
|
+
Stable ABI (N-API), no rebuild on Node version bumps. Cross-platform binaries shipped via per-platform npm packages.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Init**: `npx @napi-rs/cli new my-addon` (asks for target platforms, tooling)
|
|
13
|
+
- **Expose a fn**:
|
|
14
|
+
```rust
|
|
15
|
+
use napi_derive::napi;
|
|
16
|
+
#[napi] fn sum(a: i32, b: i32) -> i32 { a + b }
|
|
17
|
+
#[napi] async fn read_file(path: String) -> napi::Result<String> { Ok(tokio::fs::read_to_string(path).await?) }
|
|
18
|
+
```
|
|
19
|
+
- **Build local**: `napi build --platform --release`
|
|
20
|
+
- **Run JS**: `import { sum } from './index.js'; console.log(sum(2,3));`
|
|
21
|
+
- **Multi-platform release**: GitHub Actions matrix builds per-target binaries; CLI publishes platform-suffixed packages (`@scope/my-addon-linux-x64-gnu`) plus a parent that picks the right one at install time.
|
|
22
|
+
- **TypeScript**: `.d.ts` is auto-generated from `#[napi]` annotations
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
- cargo
|
|
26
|
+
- Node 16+ and npm/pnpm/yarn
|
|
27
|
+
- `@napi-rs/cli` (npm install -g or via npx)
|
|
28
|
+
|
|
29
|
+
## Notes
|
|
30
|
+
- Async functions return Promises automatically — no manual `napi::JsFunction` wrapping needed.
|
|
31
|
+
- The N-API surface is small but stable; you don't get full V8 access (use `neon` if you need that, but neon is less stable across Node versions).
|
|
32
|
+
- For pure-JS interop without native addons, look at `wasm-bindgen` + `wasm-pack --target nodejs` — slower but no per-platform binaries.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-std
|
|
3
|
+
description: Use when writing Rust without the standard library — embedded, WASM, kernel, bootloader, or library code that must work in `no_std` consumers.
|
|
4
|
+
allowed-tools: Bash(cargo:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# `#![no_std]` — Rust without std
|
|
8
|
+
|
|
9
|
+
`std` = `core` + `alloc` + OS bindings. Removing std loses heap allocation, threads, file I/O, and networking. You keep types, iterators, slices, traits.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Mark the crate**: `#![no_std]` at the top of `lib.rs` or `main.rs`
|
|
13
|
+
- **Use `core::*` and `alloc::*`** instead of `std::*`:
|
|
14
|
+
```rust
|
|
15
|
+
use core::fmt::Write;
|
|
16
|
+
extern crate alloc;
|
|
17
|
+
use alloc::{vec::Vec, string::String, boxed::Box};
|
|
18
|
+
```
|
|
19
|
+
- **Provide an allocator** (if you want `alloc`): `#[global_allocator] static A: MyAlloc = MyAlloc;` (heap crate per target, e.g. `embedded-alloc` for Cortex-M)
|
|
20
|
+
- **Panic handler**: pick one and add as a dep — `panic-halt`, `panic-abort`, or roll your own `#[panic_handler] fn panic(_: &PanicInfo) -> ! { loop {} }`
|
|
21
|
+
- **Cargo features for std/no-std libraries**:
|
|
22
|
+
```toml
|
|
23
|
+
[features]
|
|
24
|
+
default = ["std"]
|
|
25
|
+
std = []
|
|
26
|
+
```
|
|
27
|
+
Then in code: `#![cfg_attr(not(feature = "std"), no_std)]`
|
|
28
|
+
- **Common substitutes**:
|
|
29
|
+
- `std::collections::HashMap` → `hashbrown::HashMap` (with `alloc`) or fixed-size `heapless::IndexMap`
|
|
30
|
+
- `std::sync::Mutex` → `spin::Mutex` (spinlock) or `critical-section::Mutex` (interrupt-safe)
|
|
31
|
+
- `std::format!` → `heapless::String` + `core::fmt::Write` (no allocations)
|
|
32
|
+
- `std::error::Error` → not in core; use `core::error::Error` (stable 1.81+) or `snafu`/`thiserror-no-std`
|
|
33
|
+
|
|
34
|
+
## Prerequisites
|
|
35
|
+
- cargo
|
|
36
|
+
- A target without std (or std intentionally excluded): `wasm32-unknown-unknown`, any `thumbv*`, `riscv*-none-elf`
|
|
37
|
+
|
|
38
|
+
## Notes
|
|
39
|
+
- **Audit deps**: many crates have a `default-features = false` flag that disables std — set it explicitly. `cargo tree -e features` shows where std leaks back in.
|
|
40
|
+
- `heapless` crate provides `Vec<T, N>` and `String<N>` with const-generic capacity — no allocator needed.
|
|
41
|
+
- For libraries published to crates.io, gating `std` behind a feature is the polite default — downstream embedded users will love you.
|
|
42
|
+
- WASM `wasm32-unknown-unknown` has no OS, so `std::fs` / `std::net` / `std::thread` panic at runtime even though they compile. Treat as effectively no_std.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: property-testing
|
|
3
|
+
description: Use when testing parsers, serializers, math/algorithms, anything with invariants — generate thousands of inputs and check properties hold. Covers proptest and quickcheck.
|
|
4
|
+
allowed-tools: Bash(cargo:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# proptest / quickcheck — property-based testing
|
|
8
|
+
|
|
9
|
+
Instead of "for these 3 inputs, output is X", you state "for ALL inputs, this property holds" and the framework hunts counter-examples.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Setup proptest**: dev-dep `proptest`; test wrapper:
|
|
13
|
+
```rust
|
|
14
|
+
use proptest::prelude::*;
|
|
15
|
+
proptest! {
|
|
16
|
+
#[test]
|
|
17
|
+
fn roundtrip(s in "\\PC*") {
|
|
18
|
+
let parsed: MyStruct = s.parse().unwrap();
|
|
19
|
+
prop_assert_eq!(parsed.to_string(), s);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
- **Common strategies**: `any::<u32>()`, `0..1000usize`, `prop::collection::vec(any::<u8>(), 0..100)`, regex strings `"\\PC*"`
|
|
24
|
+
- **Shrinking**: framework auto-shrinks failing inputs to a minimal counter-example (proptest's killer feature)
|
|
25
|
+
- **Persistent failures**: `proptest-regressions/*.txt` files lock in past failures — commit them
|
|
26
|
+
- **Quickcheck alternative**: simpler API, no shrinking config — `#[quickcheck] fn p(xs: Vec<i32>) -> bool { ... }`
|
|
27
|
+
|
|
28
|
+
## Prerequisites
|
|
29
|
+
- cargo
|
|
30
|
+
- dev-dep: `proptest` or `quickcheck` + `quickcheck_macros`
|
|
31
|
+
|
|
32
|
+
## Notes
|
|
33
|
+
- Property tests pair perfectly with `serde` roundtrip (serialize → deserialize → equal?), parsers (parse → display → reparse → equal?), and algorithmic invariants (sort → is sorted, original len, same multiset).
|
|
34
|
+
- Slow (~100ms+ per case × 256 cases). Don't put property tests in tight inner-loop CI; mark with `#[ignore]` and run separately if they get heavy.
|
|
35
|
+
- proptest's regression files are gold — they replay yesterday's bug for free.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pyo3
|
|
3
|
+
description: Use when exposing Rust code to Python — write a CPython extension module in Rust, ship as a wheel via maturin.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(maturin:*), Bash(python:*), Bash(pip:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# PyO3 + maturin — Rust → Python
|
|
8
|
+
|
|
9
|
+
Used by `cryptography`, `polars`, `tokenizers`, `pydantic-core`. The path for "Rust speed in Python".
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Init**: `maturin new --bindings pyo3 my_ext`
|
|
13
|
+
- **Cargo.toml**:
|
|
14
|
+
```toml
|
|
15
|
+
[lib]
|
|
16
|
+
crate-type = ["cdylib"]
|
|
17
|
+
[dependencies]
|
|
18
|
+
pyo3 = { version = "0.22", features = ["extension-module"] }
|
|
19
|
+
```
|
|
20
|
+
- **Expose a fn**:
|
|
21
|
+
```rust
|
|
22
|
+
use pyo3::prelude::*;
|
|
23
|
+
#[pyfunction] fn sum(a: i64, b: i64) -> i64 { a + b }
|
|
24
|
+
#[pymodule] fn my_ext(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(sum, m)?)?; Ok(()) }
|
|
25
|
+
```
|
|
26
|
+
- **Develop loop**: `maturin develop --release` installs into the active venv; `import my_ext; my_ext.sum(2,3)`
|
|
27
|
+
- **Build wheel**: `maturin build --release` → `target/wheels/*.whl`
|
|
28
|
+
- **Publish to PyPI**: `maturin publish` (or `maturin upload`)
|
|
29
|
+
- **Async** (call async Rust from Python): `pyo3-asyncio` integrates tokio with Python's asyncio
|
|
30
|
+
|
|
31
|
+
## Prerequisites
|
|
32
|
+
- cargo
|
|
33
|
+
- Python 3.8+ in a venv (recommended) or system Python
|
|
34
|
+
- maturin (`pipx install maturin`)
|
|
35
|
+
|
|
36
|
+
## Notes
|
|
37
|
+
- Use a venv — `maturin develop` installs INTO whatever Python is active. Wrong env = wrong wheel installed.
|
|
38
|
+
- For multi-Python-version wheels: `maturin build --release --interpreter python3.10 python3.11 python3.12` or use `cibuildwheel` in CI.
|
|
39
|
+
- GIL handling: `Python::with_gil(|py| ...)` for any PyObject work. Release the GIL during pure Rust compute with `py.allow_threads(|| ...)`.
|
|
40
|
+
- Distribute as `abi3` (stable ABI) via `pyo3 = { features = ["abi3-py38"] }` so ONE wheel covers Python 3.8+.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ratatui-tui
|
|
3
|
+
description: Use when building a Rust terminal UI (TUI) — dashboards, file managers, monitors. Covers ratatui (the standard) + crossterm.
|
|
4
|
+
allowed-tools: Bash(cargo:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ratatui — Rust TUI framework
|
|
8
|
+
|
|
9
|
+
Successor to `tui-rs`. Powers `bottom`, `gitui`, `atuin`, `oha`, `lazygit`'s Rust clones, etc.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Setup**: `ratatui = "0.28"`, `crossterm = "0.28"` (default backend)
|
|
13
|
+
- **Skeleton**:
|
|
14
|
+
```rust
|
|
15
|
+
let mut terminal = ratatui::init();
|
|
16
|
+
loop {
|
|
17
|
+
terminal.draw(|f| ui(f, &state))?;
|
|
18
|
+
if let Event::Key(k) = crossterm::event::read()? { handle(k, &mut state); }
|
|
19
|
+
if state.should_quit { break; }
|
|
20
|
+
}
|
|
21
|
+
ratatui::restore();
|
|
22
|
+
```
|
|
23
|
+
- **Widgets**: `Block`, `Paragraph`, `List`, `Table`, `Gauge`, `Chart`, `Tabs`, `Sparkline`, `Canvas`
|
|
24
|
+
- **Layout**: `Layout::new(Direction::Vertical, [Constraint::Length(3), Constraint::Min(0)])`
|
|
25
|
+
- **State**: stateful widgets (`ListState`, `TableState`) — pass `&mut state` to `render_stateful_widget`
|
|
26
|
+
- **Async**: spawn a `tokio` task that pushes events into an mpsc; the render loop selects between input + tick + app events
|
|
27
|
+
|
|
28
|
+
## Prerequisites
|
|
29
|
+
- cargo
|
|
30
|
+
- crates: `ratatui`, `crossterm`
|
|
31
|
+
|
|
32
|
+
## Notes
|
|
33
|
+
- Always pair `ratatui::init()` with `ratatui::restore()` — set a panic hook to call `restore()` or your terminal stays in raw mode after a crash.
|
|
34
|
+
- Don't redraw every event — throttle to ~30-60 fps or only on dirty state. Otherwise input latency degrades on slow terminals.
|
|
35
|
+
- For complex apps, look at `tui-realm` (component model) or `cursive` (different paradigm, less popular).
|
|
36
|
+
- Test renders with `ratatui::backend::TestBackend` — captures the buffer for snapshot assertions.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-plz
|
|
3
|
+
description: Use when automating crates.io releases for a workspace — version bumps, CHANGELOG generation, GitHub Release PRs based on Conventional Commits.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(release-plz:*), Bash(git:*), Bash(gh:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# release-plz — automated release PRs
|
|
8
|
+
|
|
9
|
+
Reads Conventional Commits, bumps versions, generates CHANGELOG.md, opens a release PR. Merge → publishes to crates.io and tags GitHub release.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **One-time setup**: install + run `release-plz init` at the workspace root
|
|
13
|
+
- **Manual local dry-run**: `release-plz update` (writes Cargo.toml + CHANGELOG.md changes, no push)
|
|
14
|
+
- **GitHub Actions** (the typical path): drop the official workflow at `.github/workflows/release-plz.yml` — needs `CARGO_REGISTRY_TOKEN` secret + a PAT with PR/contents write
|
|
15
|
+
- **Per-crate config**: `release-plz.toml` to tweak version bumps, changelog body templates, dependency-update strategy
|
|
16
|
+
- **Skip a crate**: `[[package]] name = "internal" release = false`
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
- release-plz CLI
|
|
20
|
+
- Conventional Commit messages (`feat:`, `fix:`, `chore:`, breaking via `!:` or footer `BREAKING CHANGE:`)
|
|
21
|
+
- crates.io account + token
|
|
22
|
+
|
|
23
|
+
## Notes
|
|
24
|
+
- Replaces `cargo-release` for most workspaces. `cargo-release` is still useful for hand-curated releases.
|
|
25
|
+
- Generated PRs are idempotent — push more commits, the PR updates.
|
|
26
|
+
- For pre-1.0 crates, configure `[workspace] semver-check = false` in release-plz.toml to allow breaking bumps without yanking 1.x rules.
|
|
27
|
+
- Combine with the `commit-message-guard` hook in cue's core profile to enforce Conventional Commits.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reqwest
|
|
3
|
+
description: Use when making HTTP requests from Rust — JSON APIs, file downloads, streaming. Covers reqwest (async), reqwest-middleware for retries, blocking variant, hyper for low-level.
|
|
4
|
+
allowed-tools: Bash(cargo:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# reqwest — Rust HTTP client
|
|
8
|
+
|
|
9
|
+
The default high-level client. Async via tokio; blocking feature flag for sync.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Setup**: `reqwest = { version = "0.12", features = ["json", "rustls-tls"] }` (prefer rustls — pure-Rust, no openssl headache)
|
|
13
|
+
- **GET JSON**:
|
|
14
|
+
```rust
|
|
15
|
+
let user: User = reqwest::get(url).await?.json().await?;
|
|
16
|
+
```
|
|
17
|
+
- **POST JSON + auth**:
|
|
18
|
+
```rust
|
|
19
|
+
let client = reqwest::Client::new();
|
|
20
|
+
let res = client.post(url).bearer_auth(token).json(&body).send().await?.error_for_status()?;
|
|
21
|
+
```
|
|
22
|
+
- **Streaming download**: `.bytes_stream()` returns a `Stream<Item = Result<Bytes>>`
|
|
23
|
+
- **Multipart upload**: `reqwest::multipart::Form::new().file("field", path).await?`
|
|
24
|
+
- **Reuse the client**: build once, clone everywhere (it's `Arc` internally). Don't `Client::new()` per call.
|
|
25
|
+
- **Retries / circuit-break**: `reqwest-middleware` + `reqwest-retry` for exponential backoff
|
|
26
|
+
- **Blocking**: enable `blocking` feature, use `reqwest::blocking::Client` (good for CLIs without tokio)
|
|
27
|
+
- **Low-level**: drop to `hyper` only when you need raw HTTP/2 frames, custom connectors, or extreme perf
|
|
28
|
+
|
|
29
|
+
## Prerequisites
|
|
30
|
+
- cargo
|
|
31
|
+
- crates: `reqwest` (+ features), usually `tokio` and `serde_json`
|
|
32
|
+
|
|
33
|
+
## Notes
|
|
34
|
+
- `.error_for_status()?` turns 4xx/5xx into `Err` — chain after `send()` unless you explicitly handle the body of error responses.
|
|
35
|
+
- For self-signed TLS in dev: `.danger_accept_invalid_certs(true)`. Never in prod.
|
|
36
|
+
- `reqwest::Client` holds a connection pool — don't disable it (pool size defaults are fine).
|
|
37
|
+
- For unit tests: `wiremock` or `mockito` to spin up a fake server; don't mock reqwest itself.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sccache
|
|
3
|
+
description: Use when Rust cold builds are slow, CI rebuild times hurt, or switching branches forces full recompiles. Drop-in compiler cache.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(sccache:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# sccache
|
|
8
|
+
|
|
9
|
+
Caches rustc outputs (and gcc/clang). Big wins on CI and branch switching.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- One-shot: `RUSTC_WRAPPER=sccache cargo build`
|
|
13
|
+
- Persistent (project): `.cargo/config.toml` →
|
|
14
|
+
```toml
|
|
15
|
+
[build]
|
|
16
|
+
rustc-wrapper = "sccache"
|
|
17
|
+
```
|
|
18
|
+
- Persistent (shell): `export RUSTC_WRAPPER=sccache` in `~/.bashrc` / `~/.zshrc`
|
|
19
|
+
- Inspect: `sccache --show-stats`
|
|
20
|
+
- Cloud cache backends: `SCCACHE_BUCKET=...` (S3), `SCCACHE_GCS_BUCKET=...`, `SCCACHE_REDIS=...`
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
- sccache (`cargo install sccache --locked` or distro package)
|
|
24
|
+
|
|
25
|
+
## Notes
|
|
26
|
+
- Does NOT help with incremental rebuilds in the same workspace — those already work. Wins are cross-branch and cross-machine (CI).
|
|
27
|
+
- Don't enable both sccache and `[profile.dev] incremental = true` cache hits will conflict; sccache works best with incremental disabled in CI.
|
|
28
|
+
- Local-only filesystem cache lives in `~/.cache/sccache`.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: serde
|
|
3
|
+
description: Use when (de)serializing Rust data to JSON, TOML, YAML, MessagePack, etc. Covers derive macros, attributes, custom (de)serializers, common lifetime/Cow gotchas.
|
|
4
|
+
allowed-tools: Bash(cargo:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# serde — universal serialization
|
|
8
|
+
|
|
9
|
+
The Rust ecosystem's standard. Every non-trivial project pulls it in.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **JSON**: `serde` + `serde_json`. Derive: `#[derive(Serialize, Deserialize)]`
|
|
13
|
+
- **TOML/YAML**: swap `serde_json` for `toml` / `serde_yaml` (or `serde_yml`)
|
|
14
|
+
- **Binary**: `bincode`, `rmp-serde` (MessagePack), `postcard` (no_std)
|
|
15
|
+
- **Field rename**: `#[serde(rename = "fooBar")]` · case style: `#[serde(rename_all = "camelCase")]`
|
|
16
|
+
- **Optional field**: `Option<T>` + `#[serde(skip_serializing_if = "Option::is_none")]`
|
|
17
|
+
- **Default on missing**: `#[serde(default)]` or `#[serde(default = "my_fn")]`
|
|
18
|
+
- **Enum repr**: `#[serde(tag = "type")]` (internally tagged), `#[serde(untagged)]` (try each variant)
|
|
19
|
+
- **Flatten nested**: `#[serde(flatten)]` for `{ "inner": {...} }` → flat shape
|
|
20
|
+
- **Custom (de)serializer per field**: `#[serde(deserialize_with = "path")]`
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
- cargo
|
|
24
|
+
- crates: `serde = { version = "1", features = ["derive"] }`, plus a format crate
|
|
25
|
+
|
|
26
|
+
## Notes
|
|
27
|
+
- For zero-copy deserialization, use `&'a str` / `Cow<'a, str>` and add `#[serde(borrow)]` — saves allocs when the source bytes outlive the struct.
|
|
28
|
+
- `#[serde(untagged)]` is convenient but slow (tries each variant); prefer `tag` when possible.
|
|
29
|
+
- `serde_json::Value` is the escape hatch for unknown shapes; downcast to concrete types ASAP for perf and clarity.
|
|
30
|
+
- For numbers from JSON: deserialize into `f64`/`i64` and convert — JSON has no native int/float distinction.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: snapshot-testing
|
|
3
|
+
description: Use when testing CLI output, API responses, rendered templates, error messages — anything where the assertion is "output looks like this big chunk of text". Covers cargo-insta.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(cargo-insta:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# insta — snapshot testing
|
|
8
|
+
|
|
9
|
+
Saves the first run's output as a `.snap` file; future runs diff against it. Eliminates dozens of brittle `assert_eq!` lines.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **In a test**: `insta::assert_snapshot!(rendered)` (plain text) · `assert_debug_snapshot!(value)` (Debug) · `assert_json_snapshot!(value)` (serde Serialize → JSON)
|
|
13
|
+
- **First run + accept**: `cargo insta test --review` — diffs new snaps interactively
|
|
14
|
+
- **Auto-accept (CI bootstrap)**: `INSTA_UPDATE=always cargo test`
|
|
15
|
+
- **Redactions** (mask non-deterministic fields like timestamps/uuids):
|
|
16
|
+
```rust
|
|
17
|
+
insta::assert_json_snapshot!(response, { ".id" => "[id]", ".created_at" => "[ts]" });
|
|
18
|
+
```
|
|
19
|
+
- **Inline snapshots** (small values, lives in the test file): `assert_snapshot!(value, @"expected text");`
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
- cargo
|
|
23
|
+
- crate: `insta`
|
|
24
|
+
- CLI: `cargo-insta` (for `cargo insta review/test`)
|
|
25
|
+
|
|
26
|
+
## Notes
|
|
27
|
+
- Commit `.snap` files. They ARE the assertion.
|
|
28
|
+
- `cargo insta review` workflow: run tests → see diffs → press `a` to accept or `r` to reject per snapshot.
|
|
29
|
+
- For HTTP API tests, pair with `wiremock`/`mockito` for fixtures and snapshot the response body.
|
|
30
|
+
- Don't snapshot wall-clock timestamps or random IDs — redact them or inject a deterministic clock/RNG.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sqlx-cli
|
|
3
|
+
description: Use when managing database migrations or query caching for a Rust app using sqlx, sea-orm, or diesel.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(sqlx:*), Bash(sea-orm-cli:*), Bash(diesel:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rust DB Tooling
|
|
8
|
+
|
|
9
|
+
Migration + ORM CLIs.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **sqlx** (compile-time-checked queries, no ORM):
|
|
13
|
+
- Init: `sqlx database create` (uses `DATABASE_URL`)
|
|
14
|
+
- New migration: `sqlx migrate add <name>` (or `--source migrations/`)
|
|
15
|
+
- Apply: `sqlx migrate run`
|
|
16
|
+
- Offline cache (so build doesn't need live DB): `cargo sqlx prepare`
|
|
17
|
+
- **SeaORM** (full async ORM):
|
|
18
|
+
- Generate entities from DB: `sea-orm-cli generate entity -o src/entity`
|
|
19
|
+
- Migration: `sea-orm-cli migrate init` then `sea-orm-cli migrate up`
|
|
20
|
+
- **Diesel** (sync, mature, schema-first):
|
|
21
|
+
- Setup: `diesel setup`
|
|
22
|
+
- New migration: `diesel migration generate <name>`
|
|
23
|
+
- Apply: `diesel migration run`
|
|
24
|
+
|
|
25
|
+
## Prerequisites
|
|
26
|
+
- sqlx-cli (with features matching your DB), sea-orm-cli, or diesel_cli
|
|
27
|
+
- `DATABASE_URL` env var (sqlx, diesel) or a `cli` config (SeaORM)
|
|
28
|
+
- For diesel: `libpq-dev` (postgres) or `libmysqlclient-dev` (mysql) build deps
|
|
29
|
+
|
|
30
|
+
## Notes
|
|
31
|
+
- sqlx's compile-time check is great but requires either a live DB at build time OR `cargo sqlx prepare` committing `.sqlx/` cache files. Commit them.
|
|
32
|
+
- Don't mix migration systems — pick one per project.
|
|
33
|
+
- For brand-new projects with an async stack, sqlx is the lightest path. SeaORM is the choice when you actually want an ORM. Diesel is sync — fine for CLI tools, awkward in async services.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tracing
|
|
3
|
+
description: Use when adding logging, structured logs, spans, or live runtime introspection to a Rust app. Covers tracing, tracing-subscriber, tokio-console, OpenTelemetry.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(tokio-console:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# tracing — modern Rust observability
|
|
8
|
+
|
|
9
|
+
Replaces `log` for new code. Structured + async-aware (spans cross await points).
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Setup**: `tracing` + `tracing-subscriber`. Init at start of `main`:
|
|
13
|
+
```rust
|
|
14
|
+
tracing_subscriber::fmt()
|
|
15
|
+
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
|
16
|
+
.init();
|
|
17
|
+
```
|
|
18
|
+
- **Emit**: `tracing::{trace, debug, info, warn, error}!("msg {field}", field = value)`
|
|
19
|
+
- **Structured fields**: `info!(user_id = %uuid, count = 5, "request done");`
|
|
20
|
+
- **Spans**: `let _s = tracing::info_span!("op", id = %req_id).entered();` (sync) or `.instrument(span)` on a future (async)
|
|
21
|
+
- **Auto-instrument fns**: `#[tracing::instrument]` macro
|
|
22
|
+
- **JSON logs** (for prod): `tracing_subscriber::fmt().json().init()`
|
|
23
|
+
- **Filter via env**: `RUST_LOG=info,my_crate=debug,hyper=warn`
|
|
24
|
+
- **Runtime introspection**: enable `console-subscriber` + `RUSTFLAGS="--cfg tokio_unstable"`, then run `tokio-console`
|
|
25
|
+
- **OpenTelemetry export**: `tracing-opentelemetry` + `opentelemetry-otlp` for OTLP/Jaeger/Tempo
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
- cargo
|
|
29
|
+
- crates: `tracing`, `tracing-subscriber`
|
|
30
|
+
- For runtime view: `tokio-console` CLI + `console-subscriber` crate
|
|
31
|
+
|
|
32
|
+
## Notes
|
|
33
|
+
- `%value` = use Display; `?value` = use Debug; bare `value` = use the trait it implements.
|
|
34
|
+
- Spans propagate across `.await` only if you `.instrument(span)` the future explicitly — otherwise context is lost at the suspend point.
|
|
35
|
+
- Don't `#[instrument]` hot-path fns — span overhead adds up. Reserve for request-level boundaries.
|
|
36
|
+
- For libraries: emit tracing events, don't init a subscriber. Subscriber init is the binary's job.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typos-spellcheck
|
|
3
|
+
description: Use when spell-checking Rust source, docs, comments — `typos` CLI catches common misspellings without false positives on code identifiers.
|
|
4
|
+
allowed-tools: Bash(typos:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# typos — source-code spellcheck
|
|
8
|
+
|
|
9
|
+
Fast (Rust-written, walks ignoring `.gitignore` + `target/`), accurate (curated dict + identifier-aware).
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Check current dir**: `typos`
|
|
13
|
+
- **Auto-fix**: `typos --write-changes` (or `-w`)
|
|
14
|
+
- **Specific files**: `typos src/lib.rs README.md`
|
|
15
|
+
- **Diff-only** (CI on PRs): `typos --diff`
|
|
16
|
+
- **Config file** (`typos.toml` or `_typos.toml` at repo root):
|
|
17
|
+
```toml
|
|
18
|
+
[default.extend-words]
|
|
19
|
+
abbrv = "abbrv" # allow this spelling
|
|
20
|
+
[files]
|
|
21
|
+
extend-exclude = ["vendored/**", "*.snap"]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
- typos (`cargo install typos-cli --locked` or distro pkg)
|
|
26
|
+
|
|
27
|
+
## Notes
|
|
28
|
+
- Default dict is curated — false-positive rate is genuinely low. Add false positives to `extend-words` rather than disabling.
|
|
29
|
+
- Use `# typos: ignore line` (or `// typos: ignore line`) to silence one occurrence.
|
|
30
|
+
- Wire as both a pre-commit hook and a CI job; the auto-fix output makes it cheap to keep clean.
|
|
31
|
+
- For prose-only checks (style, grammar), reach for `vale` instead — typos is intentionally narrow.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uniffi
|
|
3
|
+
description: Use when exposing one Rust library to multiple languages (Kotlin/Swift/Python/Ruby) from a single UDL spec. Mozilla's approach; used by Bitwarden, Matrix SDK.
|
|
4
|
+
allowed-tools: Bash(cargo:*), Bash(uniffi-bindgen:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# UniFFI — one Rust → many languages
|
|
8
|
+
|
|
9
|
+
Write the interface once (`.udl` or proc-macro), generate idiomatic Kotlin/Swift/Python/Ruby bindings. Avoids hand-writing JNI/JNA + Swift-C-bridge + ctypes for each platform.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
- **Proc-macro flavor** (newer, no .udl file):
|
|
13
|
+
```rust
|
|
14
|
+
#[uniffi::export]
|
|
15
|
+
pub fn add(a: i32, b: i32) -> i32 { a + b }
|
|
16
|
+
uniffi::setup_scaffolding!();
|
|
17
|
+
```
|
|
18
|
+
Cargo.toml: `crate-type = ["cdylib", "staticlib"]` + `uniffi` dep + `[build-dependencies] uniffi = { features = ["build"] }`
|
|
19
|
+
- **Generate bindings**:
|
|
20
|
+
```sh
|
|
21
|
+
cargo build --release
|
|
22
|
+
uniffi-bindgen generate --library target/release/libmylib.so --language kotlin --out-dir out/kotlin
|
|
23
|
+
uniffi-bindgen generate --library ... --language swift --out-dir out/swift
|
|
24
|
+
uniffi-bindgen generate --library ... --language python --out-dir out/python
|
|
25
|
+
```
|
|
26
|
+
- **iOS**: build for `aarch64-apple-ios` + `x86_64-apple-ios-sim` + lipo into XCFramework
|
|
27
|
+
- **Android**: `cargo-ndk` to cross-compile for `aarch64-linux-android` etc.
|
|
28
|
+
|
|
29
|
+
## Prerequisites
|
|
30
|
+
- cargo
|
|
31
|
+
- uniffi-bindgen CLI (`cargo install uniffi-bindgen`)
|
|
32
|
+
- Per-target toolchains for the languages you generate
|
|
33
|
+
|
|
34
|
+
## Notes
|
|
35
|
+
- Mature & production-proven (Mozilla, Bitwarden, Matrix SDK ship UniFFI bindings).
|
|
36
|
+
- Type support is opinionated — primitives, strings, Vec, Option, HashMap, custom records/enums. Closures and traits work but with caveats.
|
|
37
|
+
- For one-target FFI (just Python), prefer PyO3 or just Node, prefer napi-rs — UniFFI shines when you need ≥2 targets from one codebase.
|
|
38
|
+
- The proc-macro flavor is now stable; new projects shouldn't use UDL files.
|