agentic-jumpstart-architecture

Architecture guidelines for Jarvy CLI - codebase structure, tool implementation patterns, registry system, platform-specific code organization, and module conventions.

16 stars

Best use case

agentic-jumpstart-architecture is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Architecture guidelines for Jarvy CLI - codebase structure, tool implementation patterns, registry system, platform-specific code organization, and module conventions.

Teams using agentic-jumpstart-architecture should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/agentic-jumpstart-architecture/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/development/agentic-jumpstart-architecture/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/agentic-jumpstart-architecture/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How agentic-jumpstart-architecture Compares

Feature / Agentagentic-jumpstart-architectureStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Architecture guidelines for Jarvy CLI - codebase structure, tool implementation patterns, registry system, platform-specific code organization, and module conventions.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Jarvy Architecture Guidelines

This skill provides comprehensive architecture guidance for the Jarvy CLI project.

## Project Overview

Jarvy is a cross-platform CLI tool that provisions development environments from a `jarvy.toml` config file using native package managers (Homebrew, apt/dnf, winget).

## Directory Structure

```
jarvy/
├── src/
│   ├── main.rs              # CLI entry point (clap derive macros)
│   ├── lib.rs               # Public re-exports for integration tests
│   ├── config.rs            # jarvy.toml parsing with serde
│   ├── error_codes.rs       # Standardized exit codes
│   ├── analytics.rs         # OpenTelemetry/tracing setup
│   ├── posthog.rs           # PostHog analytics client
│   ├── setup.rs             # Setup command implementation
│   ├── bootstrap.rs         # Bootstrap command implementation
│   ├── init.rs              # Global initialization logic
│   ├── report.rs            # Tool status reporting
│   ├── provisioner.rs       # Core provisioning orchestration
│   ├── tools/
│   │   ├── mod.rs           # Tool module registry and re-exports
│   │   ├── registry.rs      # Global OnceLock<RwLock<HashMap>> registry
│   │   ├── common.rs        # Shared utilities
│   │   ├── _template.rs     # Scaffold template for new tools
│   │   └── {tool}/          # Tool implementations
│   │       ├── mod.rs       # Re-exports the handler
│   │       └── {tool}.rs    # Implementation
│   └── tests/               # Unit test modules
├── tests/                   # Integration tests
├── crates/
│   └── cargo-jarvy/         # Cargo subcommand for scaffolding
└── Cargo.toml
```

## Core Patterns

### 1. Tool Implementation Pattern

Every tool follows a three-layer architecture:

```rust
// src/tools/{name}/{name}.rs

use crate::tools::common::{InstallError, cmd_satisfies, has, run};
#[cfg(target_os = "linux")]
use crate::tools::common::{detect_linux_pm, PkgOps, default_use_sudo};

/// Registry adapter: allows tools::add("{name}", version) to dispatch here
pub fn add_handler(min_hint: &str) -> Result<(), InstallError> {
    ensure(min_hint)
}

/// Main entry: probe first; install if needed
pub fn ensure(min_hint: &str) -> Result<(), InstallError> {
    if cmd_satisfies("{binary}", min_hint) {
        return Ok(());
    }
    install()
}

fn install() -> Result<(), InstallError> {
    #[cfg(target_os = "macos")]
    { return install_macos(); }
    #[cfg(target_os = "linux")]
    { return install_linux(); }
    #[cfg(target_os = "windows")]
    { return install_windows(); }
    #[allow(unreachable_code)]
    Err(InstallError::Unsupported)
}

#[cfg(target_os = "macos")]
fn install_macos() -> Result<(), InstallError> {
    if !has("brew") {
        return Err(InstallError::Prereq("Homebrew not found. Install https://brew.sh"));
    }
    run("brew", &["install", "{formula}"])?;
    Ok(())
}

#[cfg(target_os = "linux")]
fn install_linux() -> Result<(), InstallError> {
    let pm = detect_linux_pm().ok_or(InstallError::Prereq(
        "No supported package manager (apt/dnf/yum/zypper/pacman/apk)"
    ))?;
    let _ = PkgOps::update(pm, default_use_sudo());
    PkgOps::install(pm, "{package}", default_use_sudo())
}

#[cfg(target_os = "windows")]
fn install_windows() -> Result<(), InstallError> {
    if !has("winget") {
        return Err(InstallError::Prereq("winget not found"));
    }
    run("winget", &["install", "-e", "--id", "{WingetId}"])?;
    Ok(())
}
```

### 2. Registry Pattern

Tools are registered in a global thread-safe registry:

```rust
// src/tools/registry.rs
use std::sync::{OnceLock, RwLock};
use std::collections::HashMap;

pub type ToolAdder = fn(version: &str) -> Result<(), InstallError>;

static REGISTRY: OnceLock<RwLock<HashMap<String, ToolAdder>>> = OnceLock::new();

fn registry() -> &'static RwLock<HashMap<String, ToolAdder>> {
    REGISTRY.get_or_init(|| RwLock::new(HashMap::new()))
}

pub fn register_tool(name: &str, handler: ToolAdder) -> bool {
    let key = name.to_ascii_lowercase();
    let mut map = registry().write().expect("registry rwlock poisoned");
    map.insert(key, handler).is_none()
}

pub fn get_tool(name: &str) -> Option<ToolAdder> {
    let key = name.to_ascii_lowercase();
    let map = registry().read().expect("registry rwlock poisoned");
    map.get(&key).copied()
}

pub fn add(name: &str, version: &str) -> Result<(), InstallError> {
    let key = name.to_ascii_lowercase();
    let map = registry().read().expect("registry rwlock poisoned");
    if let Some(handler) = map.get(&key) {
        let f = *handler;
        drop(map);
        f(version)
    } else {
        Err(InstallError::Parse("unknown tool"))
    }
}
```

### 3. Error Handling Pattern

Use `thiserror` for structured errors:

```rust
// src/tools/common.rs
#[derive(thiserror::Error, Debug)]
pub enum InstallError {
    #[error("unsupported platform")]
    Unsupported,
    #[error("prerequisite missing: {0}")]
    Prereq(&'static str),
    #[error("invalid permissions: {0}")]
    InvalidPermissions(&'static str),
    #[error("command failed: {cmd} (code: {code:?})\n{stderr}")]
    CommandFailed { cmd: String, code: Option<i32>, stderr: String },
    #[error("io error: {0}")]
    Io(#[from] std::io::Error),
    #[error("parse error: {0}")]
    Parse(&'static str),
}
```

### 4. Platform Detection Pattern

```rust
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "lowercase")]
pub enum Os {
    Linux,
    Macos,
    Windows,
}

pub fn current_os() -> Os {
    #[cfg(target_os = "linux")]   { Os::Linux }
    #[cfg(target_os = "macos")]   { Os::Macos }
    #[cfg(target_os = "windows")] { Os::Windows }
}

#[cfg(target_os = "linux")]
pub fn detect_linux_pm() -> Option<PackageManager> {
    // Returns Apt, Dnf, Yum, Zypper, Pacman, or Apk
}
```

### 5. Configuration Pattern

Support both simple and detailed formats in `jarvy.toml`:

```toml
[privileges]
use_sudo = true

[privileges.per_os]
linux = true
macos = false

[provisioner]
# Simple format
git = "2.40"

# Detailed format
docker = { version = "24.0", version_manager = true, use_sudo = false }
```

Parsed with serde untagged enums:

```rust
#[derive(Deserialize)]
#[serde(untagged)]
pub enum ToolConfig {
    Detailed { version: String, version_manager: Option<bool>, use_sudo: Option<bool> },
    Simple(String),
}
```

## Adding a New Tool

### Step 1: Create the tool directory

```bash
cargo run -p cargo-jarvy -- new-tool {toolname}
# Or manually:
mkdir -p src/tools/{toolname}
```

### Step 2: Create mod.rs

```rust
// src/tools/{toolname}/mod.rs
#![allow(clippy::module_inception)]
pub mod {toolname};
```

### Step 3: Create the implementation

Use the template in `src/tools/_template.rs` as a starting point.

### Step 4: Register in src/tools/mod.rs

```rust
// Add module declaration
pub mod {toolname};

// In register_all():
let _ = register_tool("{toolname}", crate::tools::{toolname}::{toolname}::add_handler);
```

## Common Utilities Reference

### Command Execution

```rust
// Run a command and capture output
run(cmd: &str, args: &[&str]) -> Result<Output, InstallError>

// Run with optional sudo (non-Windows)
run_maybe_sudo(use_sudo: bool, cmd: &str, args: &[&str]) -> Result<Output, InstallError>

// Check if command exists on PATH
has(cmd: &str) -> bool

// Check if command output contains version prefix
cmd_satisfies(cmd: &str, min_prefix: &str) -> bool

// Require command or return error
require(cmd: &str, remediation: &'static str) -> Result<(), InstallError>

// Require one of multiple commands
require_any<'a>(candidates: &[&'a str], remediation: &'static str) -> Result<&'a str, InstallError>
```

### Package Manager Operations

```rust
// Update package lists
PkgOps::update(pm: PackageManager, use_sudo: Option<bool>) -> Result<(), InstallError>

// Install a package
PkgOps::install(pm: PackageManager, pkg: &str, use_sudo: Option<bool>) -> Result<(), InstallError>
```

## Exit Codes

| Code | Constant | Meaning |
|------|----------|---------|
| 0 | SUCCESS | Command completed successfully |
| 2 | CONFIG_ERROR | jarvy.toml missing or malformed |
| 3 | PREREQ_MISSING | Required package manager not found |
| 5 | PERMISSION_REQUIRED | Elevated privileges needed |

## CLI Structure

Commands defined with clap derive:

```rust
#[derive(Parser)]
#[clap(name = "jarvy", version, author, about)]
struct Cli {
    #[clap(subcommand)]
    command: Option<Commands>,
}

#[derive(Subcommand)]
enum Commands {
    Setup { #[clap(short, long)] file: String },
    Bootstrap {},
    Configure {},
    Get { file: String, output_format: OutputFormat, output: Option<String> },
    #[clap(external_subcommand)]
    External(Vec<String>),
}
```

## Telemetry Architecture

- **PostHog**: Product analytics for usage events and errors
- **OpenTelemetry**: Structured logging via OTLP (HTTP/protobuf)
- **Configuration**: `~/.jarvy/config.toml` with `telemetry = true/false`
- **Environment**: `JARVY_OTLP_ENDPOINT` for custom collectors

## Key Dependencies

| Crate | Purpose |
|-------|---------|
| clap | CLI parsing with derive macros |
| serde/toml | Configuration parsing |
| thiserror | Structured error types |
| tracing | Logging and instrumentation |
| opentelemetry-otlp | Telemetry export |
| inquire | Interactive prompts |
| assert_cmd | Integration testing |

## Conventions

1. **Rust Edition**: 2024
2. **Commit Messages**: Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`, `test:`)
3. **Formatting**: Always run `cargo fmt --all`
4. **Linting**: `cargo clippy --all-features -- -D warnings` must pass
5. **Dependencies**: Prefer stdlib and existing deps over new crates
6. **Platform Code**: Use `#[cfg(target_os = "...")]` attributes

Related Skills

agentic_architecture

16
from diegosouzapw/awesome-omni-skill

Enforces high-level architectural thinking, separation of concerns, and scalability checks before coding.

agentic-structure

16
from diegosouzapw/awesome-omni-skill

Collaborative programming framework for production-ready development. Use when starting features, writing code, handling security/errors, adding comments, discussing requirements, or encountering knowledge gaps. Applies to all development tasks for clear, safe, maintainable code.

agentic-jumpstart-frontend

16
from diegosouzapw/awesome-omni-skill

Frontend UI patterns with shadcn/ui, Radix UI, Tailwind CSS v4, and Lucide icons. Use when building UI components, styling, layouts, buttons, cards, dialogs, forms, responsive design, or when the user mentions UI, styling, Tailwind, components, or design.

agentic-jumpstart-code-quality

16
from diegosouzapw/awesome-omni-skill

Code quality guidelines for Jarvy CLI - Rust formatting, Clippy linting, error handling patterns, documentation standards, and Conventional Commits.

Advanced Clean Hexagonal Architecture

16
from diegosouzapw/awesome-omni-skill

Apply Clean Architecture and Hexagonal (Ports & Adapters) patterns for domain isolation and testability. Use when designing system boundaries, creating ports/adapters, or structuring domain-driven applications.

ADR (Architecture Decision Record)

16
from diegosouzapw/awesome-omni-skill

Create and maintain Architecture Decision Records following a consistent template

acc-architecture-doc-template

16
from diegosouzapw/awesome-omni-skill

Generates ARCHITECTURE.md files for PHP projects. Creates layer documentation, component descriptions, and architectural diagrams.

1k-architecture

16
from diegosouzapw/awesome-omni-skill

OneKey monorepo architecture and code organization. Use when understanding project structure, package relationships, import rules, or component organization. Triggers on architecture, structure, packages, imports, hierarchy, dependencies, monorepo, organization.

microservices-architecture

16
from diegosouzapw/awesome-omni-skill

Microservices architecture patterns and best practices. Use when designing distributed systems, breaking down monoliths, or implementing service communication.

architecture-patterns

16
from diegosouzapw/awesome-omni-skill

Padrões de arquitetura de software - Decisões OBJETIVAS sobre design de sistemas

rails-architecture

16
from diegosouzapw/awesome-omni-skill

Guides modern Rails 8 code architecture decisions and patterns. Use when deciding where to put code, choosing between patterns (service objects vs concerns vs query objects), designing feature architecture, refactoring for better organization, or when user mentions architecture, code organization, design patterns, or layered design.

mvvm-architecture

16
from diegosouzapw/awesome-omni-skill

Expert MVVM decisions for iOS/tvOS: choosing between ViewModel patterns (state enum vs published properties vs Combine), service layer boundaries, dependency injection strategies, and testing approaches. Use when designing ViewModel architecture, debugging data flow issues, or deciding where business logic belongs. Trigger keywords: MVVM, ViewModel, ObservableObject, @StateObject, service layer, dependency injection, unit test, mock, architecture