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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- Expanded all existing Rust skills with project-context discovery, workspace-aware validation, and domain-specific safety guidance.
|
|
6
|
+
- Added Rust skills for web APIs, databases, embedded/no_std, procedural macros, and build/cross-compilation.
|
|
7
|
+
- Updated README skill selection guidance and example prompts for all bundled skills.
|
|
8
|
+
|
|
9
|
+
## 0.1.0
|
|
10
|
+
|
|
11
|
+
- Initial npm-ready Pi package bootstrap.
|
|
12
|
+
- Added Rust project context extension tool.
|
|
13
|
+
- Added 13 Rust skills covering project bootstrap, code review, debugging, testing, Tokio async, CLI, WASM, FFI, performance, security, crate publishing, refactoring, and CI/toolchain setup.
|
|
14
|
+
- Added validation and skill listing scripts.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Local checks
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm test
|
|
7
|
+
npm run list
|
|
8
|
+
npm pack --dry-run
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Skill rules
|
|
12
|
+
|
|
13
|
+
Each skill must live in its own directory with a `SKILL.md` file and valid frontmatter:
|
|
14
|
+
|
|
15
|
+
```yaml
|
|
16
|
+
---
|
|
17
|
+
name: lowercase-skill-name
|
|
18
|
+
description: Specific trigger description explaining when Pi should use this skill.
|
|
19
|
+
license: MIT
|
|
20
|
+
---
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Use lowercase letters, numbers, and hyphens for skill names. Keep descriptions specific so Pi loads the right skill at the right time.
|
|
24
|
+
|
|
25
|
+
## Release process
|
|
26
|
+
|
|
27
|
+
1. Update `CHANGELOG.md`.
|
|
28
|
+
2. Update `package.json` version.
|
|
29
|
+
3. Run `npm test`.
|
|
30
|
+
4. Run `npm pack --dry-run` and verify the files list.
|
|
31
|
+
5. Publish with `npm publish --access public`.
|
|
32
|
+
6. Create a matching git tag.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 gripebomb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# pi-rust-skills
|
|
2
|
+
|
|
3
|
+
Rust programming skills and a lightweight Rust project context tool for [Pi Coding Agent](https://pi.dev/).
|
|
4
|
+
|
|
5
|
+
This package is meant to be published to npm and installed by Pi users with:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pi install npm:pi-rust-skills
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For a scoped package, rename the package to something like `@gripebomb/pi-rust-skills` and install it with:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pi install npm:@gripebomb/pi-rust-skills
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## What it includes
|
|
18
|
+
|
|
19
|
+
### Extension tool
|
|
20
|
+
|
|
21
|
+
- `rust_project_context` — read-only helper that inspects a Rust/Cargo project and returns:
|
|
22
|
+
- Rust/Cargo/rustup/rustfmt/clippy version information.
|
|
23
|
+
- Cargo.toml preview.
|
|
24
|
+
- `cargo metadata --no-deps` output.
|
|
25
|
+
- Optional `cargo tree -e features` output.
|
|
26
|
+
|
|
27
|
+
### Skills
|
|
28
|
+
|
|
29
|
+
| Skill | Purpose |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `/skill:rust-project-bootstrap` | Create or restructure Rust crates/workspaces. |
|
|
32
|
+
| `/skill:rust-code-review` | Review Rust code for correctness, idioms, safety, and maintainability. |
|
|
33
|
+
| `/skill:rust-debugging` | Diagnose compiler errors, panics, failing tests, and Cargo issues. |
|
|
34
|
+
| `/skill:rust-testing` | Add unit, integration, doc, async, property, and regression tests. |
|
|
35
|
+
| `/skill:rust-async-tokio` | Build/review Tokio and async Rust systems. |
|
|
36
|
+
| `/skill:rust-cli` | Build Rust command-line applications. |
|
|
37
|
+
| `/skill:rust-web-api` | Build Rust HTTP APIs and web services. |
|
|
38
|
+
| `/skill:rust-database` | Build Rust database layers, migrations, and query tests. |
|
|
39
|
+
| `/skill:rust-wasm` | Build Rust WebAssembly projects. |
|
|
40
|
+
| `/skill:rust-ffi` | Implement and review Rust FFI boundaries. |
|
|
41
|
+
| `/skill:rust-embedded-no-std` | Build embedded and no_std Rust projects. |
|
|
42
|
+
| `/skill:rust-proc-macro` | Build and test Rust procedural macros. |
|
|
43
|
+
| `/skill:rust-build-cross` | Configure build scripts, native dependencies, and cross-compilation. |
|
|
44
|
+
| `/skill:rust-performance` | Profile and optimize Rust code. |
|
|
45
|
+
| `/skill:rust-security-audit` | Audit Rust projects for security issues. |
|
|
46
|
+
| `/skill:rust-crate-publishing` | Prepare crates for crates.io publishing. |
|
|
47
|
+
| `/skill:rust-refactor-migration` | Safely refactor and modernize Rust codebases. |
|
|
48
|
+
| `/skill:rust-toolchain-ci` | Configure Rust toolchains, lint policy, and CI. |
|
|
49
|
+
|
|
50
|
+
### Skill selection guide
|
|
51
|
+
|
|
52
|
+
- Start with `/skill:rust-project-bootstrap` for new crates, workspaces, or major project reshaping.
|
|
53
|
+
- Use `/skill:rust-debugging` when a command fails, code panics, or behavior is wrong.
|
|
54
|
+
- Use `/skill:rust-code-review` for risk-focused review before merging or publishing.
|
|
55
|
+
- Use `/skill:rust-testing` when the main task is coverage, regression tests, or test strategy.
|
|
56
|
+
- Use a domain skill when the code has a clear surface: `/skill:rust-cli`, `/skill:rust-web-api`, `/skill:rust-database`, `/skill:rust-async-tokio`, `/skill:rust-wasm`, `/skill:rust-ffi`, `/skill:rust-embedded-no-std`, `/skill:rust-proc-macro`, or `/skill:rust-build-cross`.
|
|
57
|
+
- Use `/skill:rust-performance`, `/skill:rust-security-audit`, `/skill:rust-crate-publishing`, `/skill:rust-refactor-migration`, or `/skill:rust-toolchain-ci` for cross-cutting project work.
|
|
58
|
+
|
|
59
|
+
### Skills that combine well
|
|
60
|
+
|
|
61
|
+
- CLI or web API work often pairs with `/skill:rust-testing`, `/skill:rust-toolchain-ci`, and `/skill:rust-crate-publishing`.
|
|
62
|
+
- Async services often pair `/skill:rust-async-tokio` with `/skill:rust-web-api`, `/skill:rust-database`, and `/skill:rust-performance`.
|
|
63
|
+
- FFI, embedded, proc macro, and cross-build tasks often pair with `/skill:rust-security-audit` and `/skill:rust-testing`.
|
|
64
|
+
- Release preparation often pairs `/skill:rust-crate-publishing` with `/skill:rust-code-review`, `/skill:rust-security-audit`, and `/skill:rust-toolchain-ci`.
|
|
65
|
+
|
|
66
|
+
## Local development
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/gripebomb/pi-rust-skills.git
|
|
70
|
+
cd pi-rust-skills
|
|
71
|
+
npm test
|
|
72
|
+
npm run list
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Try it locally in Pi:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pi install ./pi-rust-skills
|
|
79
|
+
# or from inside the parent directory:
|
|
80
|
+
pi -e ./pi-rust-skills
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Then invoke a skill:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
/skill:rust-code-review Review this Rust project and suggest fixes.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Package structure
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
pi-rust-skills/
|
|
93
|
+
├── extensions/
|
|
94
|
+
│ └── rust-skills.ts
|
|
95
|
+
├── skills/
|
|
96
|
+
│ ├── rust-project-bootstrap/SKILL.md
|
|
97
|
+
│ ├── rust-code-review/SKILL.md
|
|
98
|
+
│ └── ...
|
|
99
|
+
├── references/
|
|
100
|
+
├── scripts/
|
|
101
|
+
├── examples/
|
|
102
|
+
├── package.json
|
|
103
|
+
└── README.md
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Pi discovers resources through the `pi` manifest in `package.json`:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"keywords": ["pi-package"],
|
|
111
|
+
"pi": {
|
|
112
|
+
"extensions": ["./extensions"],
|
|
113
|
+
"skills": ["./skills"]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Publishing to npm
|
|
119
|
+
|
|
120
|
+
Before publishing, update these fields in `package.json`:
|
|
121
|
+
|
|
122
|
+
- `name` if you want a scoped package, for example `@gripebomb/pi-rust-skills`.
|
|
123
|
+
- `author`.
|
|
124
|
+
- `repository`, `homepage`, and `bugs`.
|
|
125
|
+
- `version`.
|
|
126
|
+
|
|
127
|
+
Then run:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm test
|
|
131
|
+
npm pack --dry-run
|
|
132
|
+
npm login
|
|
133
|
+
npm publish --access public
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
After npm publication, install through Pi:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pi install npm:pi-rust-skills
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
If you publish as a scoped package:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
pi install npm:@gripebomb/pi-rust-skills
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Getting listed on pi.dev/packages
|
|
149
|
+
|
|
150
|
+
Pi's package catalog displays npm packages tagged with the `pi-package` keyword. This package already includes that keyword and a `pi` manifest.
|
|
151
|
+
|
|
152
|
+
The catalog appears to crawl npm metadata; after publishing, allow time for the package page to update. Use a clear npm description because the catalog shows package names, descriptions, resource types, npm links, repository links, and install commands.
|
|
153
|
+
|
|
154
|
+
## Security notes
|
|
155
|
+
|
|
156
|
+
Pi packages can execute code and influence agent behavior. This package keeps the bundled extension read-only and uses skills as instruction files, but users should still review package contents before installing.
|
|
157
|
+
|
|
158
|
+
The `rust_project_context` tool runs read-only commands such as `rustc --version`, `cargo --version`, `cargo metadata --no-deps`, and optionally `cargo tree -e features`.
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a vulnerability
|
|
4
|
+
|
|
5
|
+
Open a private security advisory on the repository if available, or email the maintainer listed in the package metadata.
|
|
6
|
+
|
|
7
|
+
## Package behavior
|
|
8
|
+
|
|
9
|
+
The extension included in this package is intentionally read-only. It inspects Rust project metadata and toolchain versions. It does not write files, delete files, send network traffic, or publish crates.
|
|
10
|
+
|
|
11
|
+
The skills are instruction documents. They can guide an agent to run commands in a user's project, so users should review the skill contents before installing or invoking them.
|
|
12
|
+
|
|
13
|
+
## Maintainer checklist
|
|
14
|
+
|
|
15
|
+
- Keep extension tools read-only unless a future version clearly documents write behavior.
|
|
16
|
+
- Avoid adding install scripts to `package.json`.
|
|
17
|
+
- Keep dependencies minimal.
|
|
18
|
+
- Review generated or contributed skills for dangerous instructions.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Example Prompts
|
|
2
|
+
|
|
3
|
+
Use these prompts in Pi after installing the package.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
/skill:rust-project-bootstrap Create a new Rust CLI called log-sifter that reads stdin and filters lines with clap flags.
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
/skill:rust-code-review Review this Rust workspace for ownership problems, API compatibility risks, unwraps in production code, and missing tests.
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
/skill:rust-debugging Fix the current borrow checker error without adding unnecessary clones, then rerun the original failing command.
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
/skill:rust-testing Add tests around the parser module and create a failing regression test for the bug in issue #12.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
/skill:rust-async-tokio Review this Tokio worker pool for cancellation, backpressure, and lock-across-await risks.
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
/skill:rust-cli Add a `scan` subcommand with stable JSON output, documented exit codes, and integration tests.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
/skill:rust-web-api Add an Axum endpoint for creating projects with validation errors, tracing, and HTTP integration tests.
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
/skill:rust-database Add SQLx migrations and repository tests for storing job runs with transaction rollback on failure.
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
/skill:rust-wasm Build this crate for the browser with wasm-bindgen, TypeScript declarations, and wasm-pack tests.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
/skill:rust-ffi Review this C ABI boundary for ownership transfer, null pointer handling, panic safety, and generated headers.
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
/skill:rust-embedded-no-std Make this driver crate no_std-compatible and add target build checks plus host-side tests.
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
/skill:rust-proc-macro Add a derive macro with trybuild compile-fail tests and inspect the expanded output.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
/skill:rust-build-cross Fix this build.rs script so it handles pkg-config, rerun directives, and Linux/macOS/Windows targets.
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
/skill:rust-performance Profile this parser, add a Criterion benchmark, and only optimize changes that improve the baseline.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
/skill:rust-security-audit Audit this crate for path traversal, command injection, unsafe code, and dependency issues.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
/skill:rust-crate-publishing Prepare this crate for crates.io. Do not publish; only perform dry-run checks.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
/skill:rust-refactor-migration Split the large `client` module into smaller modules while preserving the public API and adding compatibility re-exports.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
/skill:rust-toolchain-ci Add GitHub Actions for fmt, clippy, tests, docs, MSRV, and npm package validation for this Pi package.
|
|
75
|
+
```
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { access, readFile } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
const MAX_STDOUT = 80_000;
|
|
10
|
+
const MAX_FILE_PREVIEW = 24_000;
|
|
11
|
+
|
|
12
|
+
type RunResult = {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
command: string;
|
|
15
|
+
stdout: string;
|
|
16
|
+
stderr: string;
|
|
17
|
+
error?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type RustProjectContextParams = {
|
|
21
|
+
cwd?: string;
|
|
22
|
+
includeMetadata?: boolean;
|
|
23
|
+
includeTree?: boolean;
|
|
24
|
+
includeCargoToml?: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
async function exists(filePath: string): Promise<boolean> {
|
|
28
|
+
try {
|
|
29
|
+
await access(filePath);
|
|
30
|
+
return true;
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function truncate(value: string, max = MAX_STDOUT): string {
|
|
37
|
+
if (value.length <= max) return value;
|
|
38
|
+
return `${value.slice(0, max)}\n\n[truncated ${value.length - max} characters]`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function run(command: string, args: string[], cwd: string, timeout = 20_000): Promise<RunResult> {
|
|
42
|
+
try {
|
|
43
|
+
const result = await execFileAsync(command, args, {
|
|
44
|
+
cwd,
|
|
45
|
+
timeout,
|
|
46
|
+
maxBuffer: MAX_STDOUT * 2,
|
|
47
|
+
windowsHide: true,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
ok: true,
|
|
52
|
+
command: [command, ...args].join(" "),
|
|
53
|
+
stdout: truncate(result.stdout ?? ""),
|
|
54
|
+
stderr: truncate(result.stderr ?? ""),
|
|
55
|
+
};
|
|
56
|
+
} catch (error) {
|
|
57
|
+
const err = error as Error & { stdout?: string; stderr?: string; code?: string | number };
|
|
58
|
+
return {
|
|
59
|
+
ok: false,
|
|
60
|
+
command: [command, ...args].join(" "),
|
|
61
|
+
stdout: truncate(err.stdout ?? ""),
|
|
62
|
+
stderr: truncate(err.stderr ?? ""),
|
|
63
|
+
error: err.message,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function section(title: string, body: string): string {
|
|
69
|
+
return `## ${title}\n\n${body.trim() || "(no output)"}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function formatRun(result: RunResult): string {
|
|
73
|
+
const status = result.ok ? "ok" : "failed";
|
|
74
|
+
const parts = [`$ ${result.command}`, `status: ${status}`];
|
|
75
|
+
|
|
76
|
+
if (result.error) parts.push(`error: ${result.error}`);
|
|
77
|
+
if (result.stdout.trim()) parts.push(`stdout:\n${result.stdout.trim()}`);
|
|
78
|
+
if (result.stderr.trim()) parts.push(`stderr:\n${result.stderr.trim()}`);
|
|
79
|
+
|
|
80
|
+
return parts.join("\n");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function readOptionalCargoToml(cwd: string): Promise<string> {
|
|
84
|
+
const cargoToml = path.join(cwd, "Cargo.toml");
|
|
85
|
+
if (!(await exists(cargoToml))) return "Cargo.toml not found in this directory.";
|
|
86
|
+
|
|
87
|
+
const content = await readFile(cargoToml, "utf8");
|
|
88
|
+
return truncate(content, MAX_FILE_PREVIEW);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export default function rustSkillsExtension(pi: ExtensionAPI) {
|
|
92
|
+
pi.registerTool({
|
|
93
|
+
name: "rust_project_context",
|
|
94
|
+
label: "Rust Project Context",
|
|
95
|
+
description:
|
|
96
|
+
"Inspect a Rust project or workspace using read-only Rust/Cargo commands and return toolchain, manifest, metadata, and dependency context.",
|
|
97
|
+
promptSnippet: "Inspect Rust/Cargo project context before planning Rust code changes.",
|
|
98
|
+
promptGuidelines: [
|
|
99
|
+
"Use rust_project_context when the user asks to change, review, debug, test, or publish an existing Rust project and Cargo.toml is likely present.",
|
|
100
|
+
"Use rust_project_context output to choose the right Rust skill, target crate, feature flags, workspace member, and validation commands.",
|
|
101
|
+
"Do not use rust_project_context as a replacement for reading source files; it only provides project-level context.",
|
|
102
|
+
],
|
|
103
|
+
parameters: Type.Object({
|
|
104
|
+
cwd: Type.Optional(
|
|
105
|
+
Type.String({
|
|
106
|
+
description:
|
|
107
|
+
"Directory to inspect. Defaults to the current working directory where Pi is running.",
|
|
108
|
+
}),
|
|
109
|
+
),
|
|
110
|
+
includeMetadata: Type.Optional(
|
|
111
|
+
Type.Boolean({
|
|
112
|
+
description:
|
|
113
|
+
"Run cargo metadata --no-deps --format-version 1. Defaults to true.",
|
|
114
|
+
}),
|
|
115
|
+
),
|
|
116
|
+
includeTree: Type.Optional(
|
|
117
|
+
Type.Boolean({
|
|
118
|
+
description:
|
|
119
|
+
"Run cargo tree -e features. Defaults to false because it can be noisy on large projects.",
|
|
120
|
+
}),
|
|
121
|
+
),
|
|
122
|
+
includeCargoToml: Type.Optional(
|
|
123
|
+
Type.Boolean({
|
|
124
|
+
description: "Include a preview of Cargo.toml. Defaults to true.",
|
|
125
|
+
}),
|
|
126
|
+
),
|
|
127
|
+
}),
|
|
128
|
+
async execute(_toolCallId, params: RustProjectContextParams) {
|
|
129
|
+
const cwd = path.resolve(params.cwd ?? process.cwd());
|
|
130
|
+
const includeMetadata = params.includeMetadata ?? true;
|
|
131
|
+
const includeTree = params.includeTree ?? false;
|
|
132
|
+
const includeCargoToml = params.includeCargoToml ?? true;
|
|
133
|
+
|
|
134
|
+
const cargoTomlPath = path.join(cwd, "Cargo.toml");
|
|
135
|
+
const hasCargoToml = await exists(cargoTomlPath);
|
|
136
|
+
|
|
137
|
+
const checks: string[] = [];
|
|
138
|
+
checks.push(`cwd: ${cwd}`);
|
|
139
|
+
checks.push(`Cargo.toml: ${hasCargoToml ? cargoTomlPath : "not found"}`);
|
|
140
|
+
|
|
141
|
+
const outputs: string[] = [section("Rust workspace detection", checks.join("\n"))];
|
|
142
|
+
|
|
143
|
+
const versionCommands: Array<[string, string[]]> = [
|
|
144
|
+
["rustc", ["--version"]],
|
|
145
|
+
["cargo", ["--version"]],
|
|
146
|
+
["rustup", ["show", "active-toolchain"]],
|
|
147
|
+
["rustfmt", ["--version"]],
|
|
148
|
+
["cargo", ["clippy", "--version"]],
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
const versionResults = await Promise.all(versionCommands.map(([cmd, args]) => run(cmd, args, cwd, 10_000)));
|
|
152
|
+
outputs.push(section("Toolchain", versionResults.map(formatRun).join("\n\n")));
|
|
153
|
+
|
|
154
|
+
if (includeCargoToml) {
|
|
155
|
+
outputs.push(section("Cargo.toml preview", await readOptionalCargoToml(cwd)));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (hasCargoToml && includeMetadata) {
|
|
159
|
+
const metadata = await run("cargo", ["metadata", "--no-deps", "--format-version", "1"], cwd, 30_000);
|
|
160
|
+
outputs.push(section("cargo metadata --no-deps", formatRun(metadata)));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (hasCargoToml && includeTree) {
|
|
164
|
+
const tree = await run("cargo", ["tree", "-e", "features"], cwd, 30_000);
|
|
165
|
+
outputs.push(section("cargo tree -e features", formatRun(tree)));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const text = outputs.join("\n\n---\n\n");
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
content: [{ type: "text", text }],
|
|
172
|
+
details: {
|
|
173
|
+
cwd,
|
|
174
|
+
hasCargoToml,
|
|
175
|
+
includeMetadata,
|
|
176
|
+
includeTree,
|
|
177
|
+
includeCargoToml,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-rust-skills",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Rust programming skills and a lightweight Rust project context tool for Pi Coding Agent.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "gripebomb",
|
|
8
|
+
"homepage": "https://github.com/gripebomb/pi-rust-skills#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/gripebomb/pi-rust-skills.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/gripebomb/pi-rust-skills/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"pi-package",
|
|
18
|
+
"pi",
|
|
19
|
+
"pi-coding-agent",
|
|
20
|
+
"pi-extension",
|
|
21
|
+
"agent-skills",
|
|
22
|
+
"skills",
|
|
23
|
+
"rust",
|
|
24
|
+
"cargo",
|
|
25
|
+
"clippy",
|
|
26
|
+
"rustfmt",
|
|
27
|
+
"tokio"
|
|
28
|
+
],
|
|
29
|
+
"files": [
|
|
30
|
+
"extensions/",
|
|
31
|
+
"skills/",
|
|
32
|
+
"references/",
|
|
33
|
+
"scripts/",
|
|
34
|
+
"examples/",
|
|
35
|
+
"README.md",
|
|
36
|
+
"CHANGELOG.md",
|
|
37
|
+
"CONTRIBUTING.md",
|
|
38
|
+
"SECURITY.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"exports": {
|
|
42
|
+
".": "./extensions/rust-skills.ts"
|
|
43
|
+
},
|
|
44
|
+
"pi": {
|
|
45
|
+
"extensions": [
|
|
46
|
+
"./extensions"
|
|
47
|
+
],
|
|
48
|
+
"skills": [
|
|
49
|
+
"./skills"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"list": "node ./scripts/list-skills.mjs",
|
|
54
|
+
"test": "node ./scripts/validate-skills.mjs",
|
|
55
|
+
"validate": "node ./scripts/validate-skills.mjs",
|
|
56
|
+
"pack:dry": "npm pack --dry-run",
|
|
57
|
+
"prepack": "node ./scripts/validate-skills.mjs"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
61
|
+
"typebox": "*"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {},
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=20"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Rust Agent Guide
|
|
2
|
+
|
|
3
|
+
This package is designed to make Pi Coding Agent better at Rust work without forcing every Rust instruction into the base prompt. Pi loads skill descriptions at startup and the full skill content only when a task matches or when the user invokes `/skill:name`.
|
|
4
|
+
|
|
5
|
+
## Recommended agent flow
|
|
6
|
+
|
|
7
|
+
1. Inspect the repository shape.
|
|
8
|
+
2. If a Cargo project is present, call `rust_project_context`.
|
|
9
|
+
3. Read the most relevant skill:
|
|
10
|
+
- New project: `/skill:rust-project-bootstrap`
|
|
11
|
+
- Review: `/skill:rust-code-review`
|
|
12
|
+
- Build failure: `/skill:rust-debugging`
|
|
13
|
+
- Tests: `/skill:rust-testing`
|
|
14
|
+
- Async: `/skill:rust-async-tokio`
|
|
15
|
+
- CLI: `/skill:rust-cli`
|
|
16
|
+
- Web APIs: `/skill:rust-web-api`
|
|
17
|
+
- Database work: `/skill:rust-database`
|
|
18
|
+
- WASM: `/skill:rust-wasm`
|
|
19
|
+
- FFI: `/skill:rust-ffi`
|
|
20
|
+
- Embedded/no_std: `/skill:rust-embedded-no-std`
|
|
21
|
+
- Proc macros: `/skill:rust-proc-macro`
|
|
22
|
+
- Build scripts/cross-compilation: `/skill:rust-build-cross`
|
|
23
|
+
- Performance: `/skill:rust-performance`
|
|
24
|
+
- Security: `/skill:rust-security-audit`
|
|
25
|
+
- Publishing crates: `/skill:rust-crate-publishing`
|
|
26
|
+
- Refactors: `/skill:rust-refactor-migration`
|
|
27
|
+
- CI/toolchain: `/skill:rust-toolchain-ci`
|
|
28
|
+
4. Make small, testable changes.
|
|
29
|
+
5. Run `cargo fmt`, `cargo clippy`, and `cargo test` when practical.
|
|
30
|
+
6. Report what changed and what validation passed.
|
|
31
|
+
|
|
32
|
+
## Default validation commands
|
|
33
|
+
|
|
34
|
+
Use the narrowest command that proves the change, then broaden if the change is cross-cutting.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cargo fmt
|
|
38
|
+
cargo check --all-targets --all-features
|
|
39
|
+
cargo clippy --all-targets --all-features -- -D warnings
|
|
40
|
+
cargo test --all-features
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
For workspaces:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cargo check --workspace --all-targets --all-features
|
|
47
|
+
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
48
|
+
cargo test --workspace --all-features
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Dependency policy
|
|
52
|
+
|
|
53
|
+
Do not add dependencies by default. Add a dependency only when it meaningfully reduces risk, complexity, or maintenance burden. Prefer well-maintained crates with clear licensing, active releases, and a small feature surface.
|
|
54
|
+
|
|
55
|
+
## Safety policy for generated Rust
|
|
56
|
+
|
|
57
|
+
- No `unsafe` unless the task requires it.
|
|
58
|
+
- No `unwrap` or `expect` in production code unless the invariant is documented and truly unrecoverable.
|
|
59
|
+
- No network calls, file deletes, or shell execution in tests unless explicitly required and sandboxed.
|
|
60
|
+
- Prefer deterministic tests.
|
|
61
|
+
|
|
62
|
+
## Reporting format
|
|
63
|
+
|
|
64
|
+
For substantial tasks, end with:
|
|
65
|
+
|
|
66
|
+
```markdown
|
|
67
|
+
## What changed
|
|
68
|
+
|
|
69
|
+
## Validation
|
|
70
|
+
|
|
71
|
+
## Notes and follow-ups
|
|
72
|
+
```
|