Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 40 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ Command-line interface for development and management of CyberFabric modules.

### Prerequisites

- Rust toolchain with `cargo`
- A local clone of this repository
- Rust toolchain with `cargo` (https://rust-lang.org/tools/install/)

### Install the CLI

Expand All @@ -19,7 +18,7 @@ This workspace exposes two binaries:
Install both from the repository root:

```bash
cargo install --path crates/cli --bin cyberfabric --bin cargo-cyberfabric
cargo install --git https://github.com/cyberfabric/cf-cli
```

After installation, you can use either form:
Expand All @@ -32,12 +31,41 @@ cyberfabric --help
cargo cyberfabric --help
```

For local development without installing:
## Typical usage flow

First you can create a new workspace with a basic hello-world module with:

```bash
cargo run -p cli -- --help
cyberfabric mod init /tmp/cf-demo
```

You can run it straight away and you will see in the console a hello world message:

```bash
cd /tmp/cf-demo
# When running or building we recommend using cargo-cyberfabric binary instead of the standalone binary.
cargo cyberfabric run -c ./config/quickstart.yml
```

Second, add a module to the workspace. You can choose among a set of templates: `background-worker`, `api-db-handler`,
and `rest-gateway`. For this example we'll use background-worker:

```bash
# bring the module to the workspace
cyberfabric mod add background-worker
# add the module to the config
cyberfabric config mod add background-worker -c ./config/quickstart.yml
```

Now, we run it again. We'll see every couple of seconds, the background worker printing a random Pokémon:

```bash
cargo cyberfabric run -c ./config/quickstart.yml
```

You can run the tool from any directory by specifying the path to the workspace with the `-p` flag. The default will be
the current directory. `cargo cyberfabric run -p /tmp/cf-demo -c /tmp/cf-demo/config/quickstart.yml`

## What the CLI can do

The current CLI surface is centered on CyberFabric workspace setup, configuration, code generation, and execution.
Expand Down Expand Up @@ -76,22 +104,17 @@ You need to provide the path to the configuration file with the `-c` flag. `-c c
- `lint` is declared but not implemented yet
- `test` is declared but not implemented yet

## Typical usage flow

Create a workspace, add a module, configure it, and run it:
## Command overview

```bash
cyberfabric mod init /tmp/cf-demo
cyberfabric mod add background-worker -p /tmp/cf-demo
cyberfabric config mod add background-worker -p /tmp/cf-demo -c /tmp/cf-demo/config/quickstart.yml
cyberfabric run -p /tmp/cf-demo -c /tmp/cf-demo/config/quickstart.yml
```
For the full command surface, arguments, and examples, check [SKILLS.md](SKILLS.md).

The `-p` is to specify the path. If you don't provide it, the default will be the current directory.
## Local development

## Command overview
To run the CLI from source:

For the full command surface, arguments, and examples, check [SKILLS.md](SKILLS.md).
```bash
cargo run -p cli -- --help
```

## License

Expand Down
12 changes: 12 additions & 0 deletions crates/cli/src/mod/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use cargo_generate::{GenerateArgs, TemplatePath, generate};
use clap::Args;
use std::path::PathBuf;

/// Content of SKILLS.md embedded at compile time
const SKILLS_MD_CONTENT: &str = include_str!("../../../../SKILLS.md");

#[derive(Args)]
pub struct InitArgs {
/// Path to initialize the project
Expand Down Expand Up @@ -70,6 +73,15 @@ impl InitArgs {
..Default::default()
})
.context("can't generate project")?;

// Create .agents/skills/cyberfabric/ directory and write SKILLS.md
let agents_skills_dir = self.path.join(".agents").join("skills").join("cyberfabric");
std::fs::create_dir_all(&agents_skills_dir)
.context("failed to create .agents/skills/cyberfabric/ directory")?;
let skills_md_path = agents_skills_dir.join("SKILLS.md");
std::fs::write(&skills_md_path, SKILLS_MD_CONTENT)
.context("failed to write SKILLS.md to .agents/skills/cyberfabric/")?;

println!("Project initialized at {}", self.path.display());
Ok(())
}
Expand Down