Project-specific instructions for Claude Code.
Always ask before committing. Show the diff or summary and wait for explicit approval before running git commit.
Always ask before pushing. Never run git push or git push --tags without explicit user approval. This applies to every push — main branch, tags, all of it.
Always ask before tagging. Never run git tag without explicit user approval. Tags trigger CI releases to crates.io, npm, Homebrew, Scoop, and Docker — they cannot be easily undone.
Ask before destructive actions. This includes git checkout, git reset, file deletions, or anything that can't be easily undone.
Show work before publishing. Before running release workflows, publishing to package managers, or pushing tags, summarize what will happen and wait for approval.
ALWAYS follow the RELEASE.md checklist for every version. No exceptions — not for patch versions, not for "trivial" fixes. Every release must complete all steps: pre-release checks (fmt, clippy, test, build, update, audit), manual testing, version bumps, documentation review. Run the checklist, show the results, then ask for approval to commit/push/tag.
proc is a semantic CLI tool for process management written in Rust. It provides a unified interface for process and port operations across macOS, Linux, and Windows.
Tagline (use exactly): "Semantic CLI tool for process management. Target by port, PID, name or path."
Repository: https://github.com/yazeed/proc
src/
├── main.rs # CLI entry point, clap setup, command routing
├── lib.rs # Library exports
├── error.rs # Error types and exit codes
├── commands/ # One file per command
│ ├── mod.rs # Exports all commands
│ ├── kill.rs # proc kill
│ ├── stop.rs # proc stop (supports --signal)
│ ├── on.rs # proc on (bidirectional port/process lookup)
│ ├── by.rs # proc by (filter by name)
│ ├── find_in.rs # proc in (filter by directory, named find_in to avoid Rust keyword)
│ ├── list.rs # proc list
│ ├── info.rs # proc info
│ ├── ports.rs # proc ports
│ ├── tree.rs # proc tree
│ ├── stuck.rs # proc stuck
│ ├── unstick.rs # proc unstick
│ ├── freeze.rs # proc freeze (SIGSTOP)
│ ├── thaw.rs # proc thaw (SIGCONT)
│ ├── orphans.rs # proc orphans
│ ├── why.rs # proc why (ancestry tracing)
│ ├── free.rs # proc free (kill + verify port freed)
│ └── wait.rs # proc wait (block until exit)
├── core/ # Shared logic
│ ├── mod.rs # Exports
│ ├── filters.rs # Shared filter utilities (resolve_in_dir)
│ ├── target.rs # Target parsing (:port, PID, name) and resolution
│ ├── process.rs # Process operations
│ └── port.rs # Port operations
└── ui/ # Output formatting
├── mod.rs
├── format.rs # Shared formatting (format_duration, truncate_*, colorize_status)
└── output.rs # Printer, OutputFormat (Human/Json)
Each command follows this structure:
//! `proc <cmd>` - Brief description
//!
//! Examples:
//! proc cmd target # What it does
//! proc cmd :3000 # Port example
//! proc cmd --flag # Flag example
use crate::core::{...};
use crate::error::{ProcError, Result};
use crate::ui::{OutputFormat, Printer};
use clap::Args;
/// Brief doc for --help
#[derive(Args, Debug)]
pub struct CmdCommand {
/// Target description
pub target: String,
/// Skip confirmation prompt
#[arg(long, short = 'y')]
pub yes: bool,
/// Output as JSON
#[arg(long, short = 'j')]
pub json: bool,
/// Show verbose output
#[arg(long, short = 'v')]
pub verbose: bool,
}
impl CmdCommand {
pub fn execute(&self) -> Result<()> {
// 1. Setup printer
let format = if self.json { OutputFormat::Json } else { OutputFormat::Human };
let printer = Printer::new(format, self.verbose);
// 2. Parse and resolve targets
let targets = parse_targets(&self.target);
let (processes, not_found) = resolve_targets(&targets);
// 3. Warn about not-found targets
for target in ¬_found {
printer.warning(&format!("Target not found: {}", target));
}
// 4. Handle dry-run if applicable
// 5. Confirm destructive actions (unless --yes)
// 6. Execute operation
// 7. Print results
Ok(())
}
}- Unified targets:
:port,PID,namework everywhere - Multi-target: Comma-separated, deduplicated by PID
- Confirmation: Destructive commands require
--yesor interactive confirmation - Dry-run: Destructive commands support
--dry-run - JSON output: All commands support
--jsonfor scripting - Short flags:
-y(yes),-j(json),-v(verbose)
Use the shared modules instead of writing local helpers:
crate::core::resolve_in_dir— resolves--indirectory paths (handles., relative, absolute)crate::ui::format_duration— formats seconds as human-readable durationcrate::ui::truncate_string/truncate_path— truncates with…crate::ui::colorize_status— colors process status stringsprinter.print_confirmation(action, &processes)— unified⚠confirmation promptprinter.print_action_result(action, &succeeded, &failed)— unified result summary for destructive commands
Use ProcError variants from src/error.rs. Return Result<()> from execute methods.
cargo build # Debug build
cargo build --release # Release build
cargo test # Run tests
cargo fmt # Format code
cargo clippy # LintPre-commit hook runs cargo fmt --check automatically.
ALWAYS follow RELEASE.md for every release. Do not skip steps. This includes:
- Pre-release checks:
cargo fmt --check,cargo clippy,cargo test,cargo build --release,cargo update,cargo audit,cargo check --target x86_64-pc-windows-msvc - Manual testing with the release binary (
./target/release/proc --version,--help, new features) - Version bump in ALL files:
Cargo.toml,pkg/npm/package.json,flake.nix - Documentation:
CHANGELOG.md,README.md,ROADMAP.md,src/lib.rs— verify all reflect new changes - Commit, tag, push (tag push triggers CI for all package managers)
- Verify CI completes successfully
README.md— Main documentation, installation, examples, shell completions, man pageCHANGELOG.md— Keep a Changelog format, update with each releaseRELEASE.md— Release checklist and publishing processROADMAP.md— Version plans, feature status, under considerationPHILOSOPHY.md— Project manifesto, principles, feature testCONTRIBUTING.md— Contribution guidelinesSECURITY.md— Security policyskills/proc-cli/SKILL.md— Agent Skills definition for LLM tool useskills/proc-cli/reference.md— JSON output schemas for the skilldocs/commands/— GitHub Pages per-command documentation
See PHILOSOPHY.md for the full manifesto.
Principles: Semantic, Explicit, Complete, Fast, Obvious
The Feature Test — every feature must pass:
- Does it fit "process and port management"?
- Can it be expressed in one obvious command?
- Does it make the common case effortless?
- Is user intent explicit?
- Does it deepen proc's command of its domain?
- Does it follow our conventions?
Out of scope: Service management, containers, remote processes, GUIs, historical data.