Terminal-first Git Forge workflow automation
ForgeFlow is a high-performance CLI tool for automating Git forge workflows. Browse repositories, fetch resources, and submit changes—all without leaving your terminal. Built with Rust for speed and reliability.
Originally designed for virtualization and kernel development teams, ForgeFlow works with any Git forge (GitCode, GitLab, GitHub) and streamlines the entire contribution pipeline.
- ⚡ Blazing Fast — Rust-powered with minimal startup time and memory footprint
- 📂 Remote Browsing — Explore repository contents without cloning
- 📥 One-Command Fetch — Download files or entire directories instantly
- 🚀 Atomic Submissions — Branch, commit, and create PRs in a single operation
- 📝 Audit-Ready Commits — Automatic Signed-off-by trailers, trace metadata, and compliance formatting
- 🔧 Multi-Provider — Works with GitCode, GitLab, GitHub, and compatible forges
- 🔒 Secure by Default — Token-based auth, no credential storage in shell history
git clone https://github.com/nashzhou/forgeflow.git
cd forgeflow
cargo install --path .- Rust 1.75+ (Edition 2024)
- Git forge account with API access
Run the interactive setup wizard:
vkt config --setupOr manually create your configuration file:
mkdir -p ~/.config/vktThen create ~/.config/vkt/config.toml with your settings (see Configuration section).
# List repository root
vkt list
# Explore specific directories
vkt list scripts/qemu/
vkt list configs/ --recursive# Download a file
vkt get scripts/debug.sh -o ./local-scripts/
# Download an entire directory
vkt get templates/ --output ./templates/# Search for files containing "config"
vkt search "config"
# Regex search for test files
vkt search ".*_test\.rs$" --regex
# Search within a specific directory
vkt search "main" --path src/# Submit a file with automated PR creation
vkt submit ./my-script.sh \
--target scripts/tools/ \
--msg "feat: add debugging utility for virtio devices"Configuration is stored in TOML format at ~/.config/vkt/config.toml.
[user]
name = "Developer Name" # Required: Git commit author name
email = "dev@company.com" # Required: Git commit author email
auto_signoff = true # Optional: Add Signed-off-by automatically
[remote]
provider = "Gitcode" # Required: GitCode, GitLab, or GitHub
api_url = "https://api.gitcode.com/api/v5" # Required: API endpoint URL
token = "xxxxxxxxxxxx" # Required: Personal access token
[repo]
project_id = "owner/repo" # Required: Project identifier (owner/repo)
default_branch = "main" # Optional: Base branch for PRs (default: main)
[template]
pr_prefix = "[VIRT-TOOL]" # Optional: Prefix for PR titlesAll configuration values can be overridden via environment variables:
export VKT_USER_NAME="Override Name"
export VKT_USER_EMAIL="override@example.com"
export VKT_REMOTE_TOKEN="new-token"
export VKT_REPO_PROJECT_ID="different/project"[remote]
provider = "Gitcode"
api_url = "https://api.gitcode.com/api/v5"
token = "xxxxxxxxxxxxxxxxxxxx"GitLab support is planned. The provider will auto-detect from API URLs containing gitlab.
[remote]
provider = "GitLab"
api_url = "https://gitlab.com/api/v4"
token = "your-gitlab-token"GitHub support is planned. The provider will auto-detect from github.com URLs.
[remote]
provider = "GitHub"
api_url = "https://api.github.com"
token = "your-github-token"Note: Provider type is auto-detected from the API URL. You can also explicitly set it in the config.
List contents of a remote directory without cloning.
vkt list [PATH] [OPTIONS]Options:
-r, --recursive— Recursively list subdirectories
Examples:
# List root directory
vkt list
# List specific path
vkt list scripts/
# Recursive listing
vkt list tools/ --recursiveSample Output:
.assets/
exercises/
.gitignore
Cargo.toml
README.md
build.rs
info.tomlFetch files or directories from the remote repository.
vkt get <REMOTE_PATH> [OPTIONS]Options:
-o, --output <PATH>— Local destination path (default: current directory)-f, --force— Overwrite existing files without prompting
Examples:
# Fetch single file to current directory
vkt get configs/kernel-debug.config
# Fetch to specific location
vkt get scripts/qemu-launch.sh -o ~/bin/
# Fetch entire directory
vkt get templates/ -o ./my-templates/ --forceView and modify VKT configuration settings.
vkt config [KEY] [VALUE] [OPTIONS]Options:
-l, --list— List all configuration values--setup— Run interactive configuration setup
Examples:
# Show all configuration
vkt config
# Get a specific value
vkt config user.name
# Set a specific value
vkt config user.name "John Doe"
# Run interactive setup
vkt config --setupSample Output:
[user]
name = Developer Name
email = dev@company.com
auto_signoff = true
[remote]
provider = Gitcode
api_url = https://api.gitcode.com/api/v5
token = ********
[repo]
project_id = owner/repo
default_branch = main
[template]
pr_prefix = [VIRT-TOOL]Search for files and directories in the remote repository.
vkt search <PATTERN> [OPTIONS]Options:
-p, --path <PATH>— Limit search to specific directory-t, --file-type <TYPE>— Filter by type:fileordir-S, --case-sensitive— Use case-sensitive matching-r, --regex— Use regex pattern matching-m, --max-results <N>— Maximum number of results
Examples:
# Basic substring search
vkt search "config"
# Search within a directory
vkt search "main" --path src/
# Regex search for test files
vkt search ".*_test\.rs$" --regex
# Case-sensitive search
vkt search "README" --case-sensitive
# Find only directories
vkt search "utils" --type dir
# Limit results
vkt search ".rs" --max-results 20Sample Output:
src/config/
src/utils/
src/main.rs
src/config.rs
INFO: Found 4 matchesThe flagship feature: submit local files, create a branch, commit with trace metadata, and open a PR—all in one command.
vkt submit <LOCAL_PATH> --target <REMOTE_DIR> --msg <MESSAGE> [OPTIONS]Options:
-t, --target <DIR>— Target directory in remote repository (required)-m, --msg <MESSAGE>— Commit/PR message (required)-b, --branch <NAME>— Custom branch name (auto-generated if omitted)-f, --force— Skip confirmation prompts--dry-run— Preview actions without executing
Examples:
# Basic submission
vkt submit ./debug.sh \
--target scripts/tools/ \
--msg "feat: add virtio debugging script"
# With custom branch name
vkt submit ./config updates/ \
--target configs/kernel/ \
--msg "chore: update kernel configs for v6.8" \
--branch feat/kernel-configs-v6.8
# Dry run to preview changes
vkt submit ./new-feature.sh \
--target scripts/ \
--msg "feat: implement new workflow" \
--dry-runWhat Happens Behind the Scenes:
- Conflict Check — Verifies no file exists at the target path
- Branch Creation — Creates feature branch from default branch
- Content Upload — Uploads file(s) via API
- Commit Generation — Creates commit with:
- Your configured author info
- Signed-off-by trailer (if
auto_signoff = true) - Content hash for traceability
- Timestamp and metadata
- PR Creation — Opens merge request with:
- Prefixed title (from config)
- Auto-assigned reviewers
- Link to uploaded content
Sample Output:
✅ File uploaded: scripts/tools/debug.sh (4.2 KB)
✅ Branch created: feat/add-virtio-debugging-script
✅ Commit: 8a3f2d1 — feat: add virtio debugging script
✅ PR #42 created: "[TEAM] feat: add virtio debugging script"
🔗 https://gitcode.com/owner/repo/pull/42| Provider | Status | API Version | Notes |
|---|---|---|---|
| GitCode | ✅ Full | v5 | Primary target platform |
| GitLab | 🚧 Planned | v4 | Auto-detection ready |
| GitHub | 🚧 Planned | v3 | Auto-detection ready |
# Development build
cargo build
# Release build (optimized)
cargo build --release
# Run with logs
RUST_LOG=debug cargo run -- list# Run all tests
cargo test
# Run specific test
cargo test test_submit_command
# Test with coverage
cargo tarpaulin --out Html# Format code
cargo fmt
# Run linter
cargo clippy -- -D warnings
# Type check (fast)
cargo checkThis project is licensed under the MIT License. See the LICENSE file for details.
Made with 🦀 in Rust