Skip to content

Commit 203e8fb

Browse files
Rebrand: Revenue Holdings -> DevForge, rename package, update all references
1 parent 25c1a78 commit 203e8fb

5 files changed

Lines changed: 64 additions & 68 deletions

File tree

README.md

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,89 @@
1-
# Revenue Holdings CLI
1+
# DevForge CLI
22

33
[![GitHub stars](https://img.shields.io/github/stars/Coding-Dev-Tools/devforge?style=social)](https://github.com/Coding-Dev-Tools/devforge/stargazers)
44

5-
**The `rh` command — one install, ten developer CLI tools.**
5+
**The `devforge` command — one install, ten developer CLI tools.**
66

7-
[![PyPI](https://img.shields.io/pypi/v/revenueholdings)](https://pypi.org/project/revenueholdings/)
8-
[![Python Versions](https://img.shields.io/pypi/pyversions/revenueholdings)](https://pypi.org/project/revenueholdings/)
7+
[![PyPI](https://img.shields.io/pypi/v/devforge)](https://pypi.org/project/devforge/)
8+
[![Python Versions](https://img.shields.io/pypi/pyversions/devforge)](https://pypi.org/project/devforge/)
99
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
1010

11-
Ten production-ready CLI tools for API contracts, SQL generation, infrastructure diffs, config drift, API mocking, key management, env syncing, schema conversion, MCP servers, and dead code removal — in a single package. Install one meta-package and get immediate access to all tools via the unified `rh` command.
11+
Ten production-ready CLI tools for API contracts, SQL generation, infrastructure diffs, config drift, API mocking, key management, env syncing, schema conversion, MCP servers, and dead code removal — in a single package. Install one meta-package and get immediate access to all tools via the unified `devforge` command.
1212

1313
---
1414

15-
[🏠 Landing Page](https://coding-dev-tools.github.io/revenueholdings.dev/) · [📝 Blog](https://coding-dev-tools.github.io/revenueholdings.dev/blog.html) · [🐛 Report a Bug](https://github.com/Coding-Dev-Tools/devforge/issues)
15+
[🏠 Landing Page](https://coding-dev-tools.github.io/devforge/) · [📝 Blog](https://coding-dev-tools.github.io/devforge/blog.html) · [🐛 Report a Bug](https://github.com/Coding-Dev-Tools/devforge/issues)
1616

1717
---
1818

1919
## Why the Suite?
2020

21-
Instead of installing ten separate tools and learning ten different CLIs, `pip install revenueholdings[all]` gives you:
21+
Instead of installing ten separate tools and learning ten different CLIs, `pip install devforge[all]` gives you:
2222

23-
- **Single CLI** (`rh`) to invoke any tool — no context switching
23+
- **Single CLI** (`devforge`) to invoke any tool — no context switching
2424
- **Consistent flags, output formats, and help** across all tools
2525
- **Shared configuration** — one install, all tools
2626

2727
## Installation
2828

2929
```bash
3030
# Install everything (recommended)
31-
pip install revenueholdings[all]
31+
pip install devforge[all]
3232

3333
# Or install individual tools
34-
pip install revenueholdings[guard] # API Contract Guardian
35-
pip install revenueholdings[sql] # json2sql
36-
pip install revenueholdings[deploy] # DeployDiff
37-
pip install revenueholdings[drift] # ConfigDrift
38-
pip install revenueholdings[ghost] # APIGhost
39-
pip install revenueholdings[auth] # APIAuth
40-
pip install revenueholdings[envault] # Envault
41-
pip install revenueholdings[schema] # SchemaForge
42-
pip install revenueholdings[mcp] # click-to-mcp
43-
pip install revenueholdings[deadcode] # DeadCode
34+
pip install devforge[guard] # API Contract Guardian
35+
pip install devforge[sql] # json2sql
36+
pip install devforge[deploy] # DeployDiff
37+
pip install devforge[drift] # ConfigDrift
38+
pip install devforge[ghost] # APIGhost
39+
pip install devforge[auth] # APIAuth
40+
pip install devforge[envault] # Envault
41+
pip install devforge[schema] # SchemaForge
42+
pip install devforge[mcp] # click-to-mcp
43+
pip install devforge[deadcode] # DeadCode
4444
```
4545

4646
## Usage
4747

4848
```bash
49-
rh --version # Show version info
50-
rh tools # List all available tools
51-
rh tools guard # Show details about a specific tool
52-
rh versions # Show installed tool versions
49+
devforge --version # Show version info
50+
devforge tools # List all available tools
51+
devforge tools guard # Show details about a specific tool
52+
devforge versions # Show installed tool versions
5353
```
5454

55-
Run any tool directly through `rh`:
55+
Run any tool directly through `devforge`:
5656

5757
```bash
5858
# API Contract Guardian — detect OpenAPI breaking changes
59-
rh guard check spec-v1.yaml spec-v2.yaml
59+
devforge guard check spec-v1.yaml spec-v2.yaml
6060

6161
# json2sql — convert JSON to SQL INSERT statements
62-
rh sql convert data.json --dialect postgres
62+
devforge sql convert data.json --dialect postgres
6363

6464
# DeployDiff — preview infrastructure changes with cost estimates
65-
rh deploy preview plan.json
65+
devforge deploy preview plan.json
6666

6767
# ConfigDrift — catch config drift between environments
68-
rh drift check dev.yaml prod.yaml
68+
devforge drift check dev.yaml prod.yaml
6969

7070
# APIGhost — spawn mock API server from OpenAPI spec
71-
rh ghost serve openapi.yaml
71+
devforge ghost serve openapi.yaml
7272

7373
# APIAuth — generate API keys and JWTs
74-
rh auth generate --type api-key
74+
devforge auth generate --type api-key
7575

7676
# Envault — sync .env files across environments
77-
rh envault diff .env.dev .env.prod
77+
devforge envault diff .env.dev .env.prod
7878

7979
# SchemaForge — convert between ORM formats
80-
rh schema convert schema.prisma --to drizzle
80+
devforge schema convert schema.prisma --to drizzle
8181

8282
# click-to-mcp — wrap CLI as MCP server
83-
rh mcp wrap my-cli --transport http
83+
devforge mcp wrap my-cli --transport http
8484

8585
# DeadCode — find unused exports in React/Next.js
86-
rh deadcode scan src/
86+
devforge deadcode scan src/
8787
```
8888

8989
## Tools
@@ -103,14 +103,10 @@ rh deadcode scan src/
103103

104104
## Links
105105

106-
- [Landing Page](https://coding-dev-tools.github.io/revenueholdings.dev/)
106+
- [Landing Page](https://coding-dev-tools.github.io/devforge/)
107107
- [GitHub Organization](https://github.com/Coding-Dev-Tools)
108108
- [Report an Issue](https://github.com/Coding-Dev-Tools/devforge/issues)
109109

110110
## License
111111

112112
MIT — see [LICENSE](LICENSE) for details.
113-
114-
---
115-
116-
<sub>Built by [Revenue Holdings](https://coding-dev-tools.github.io/revenueholdings.dev/) — autonomous AI agents generating revenue 24/7.</sub>

pyproject.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ requires = ["setuptools>=68.0", "wheel"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
6-
name = "revenueholdings"
7-
version = "0.2.0"
6+
name = "devforge"
7+
version = "0.3.0"
88
description = "Unified CLI for 10 developer tools: API contracts, SQL generation, infra diffs, config drift, API mocking, key management, env syncing, schema conversion, MCP servers, and dead code removal"
99
readme = "README.md"
1010
requires-python = ">=3.10"
1111
license = "MIT"
12-
authors = [{name = "Revenue Holdings"}]
13-
keywords = ["revenueholdings", "cli", "devops", "developer-tools", "api-contract", "openapi", "json-to-sql", "infrastructure", "terraform", "cloudformation", "config-drift", "devsecops", "mocking", "api-keys", "env", "schema", "mcp", "dead-code"]
12+
authors = [{name = "DevForge"}]
13+
keywords = ["devforge", "cli", "devops", "developer-tools", "api-contract", "openapi", "json-to-sql", "infrastructure", "terraform", "cloudformation", "config-drift", "devsecops", "mocking", "api-keys", "env", "schema", "mcp", "dead-code"]
1414
classifiers = [
1515
"Development Status :: 4 - Beta",
1616
"Intended Audience :: Developers",
@@ -25,7 +25,7 @@ dependencies = [
2525
"rich>=13.0.0",
2626
]
2727

28-
# Optional groups — install with: pip install revenueholdings[all]
28+
# Optional groups — install with: pip install devforge[all]
2929
[project.optional-dependencies]
3030
guard = ["api-contract-guardian>=0.1.0"]
3131
sql = ["json2sql>=0.1.0"]
@@ -57,7 +57,7 @@ Repository = "https://github.com/Coding-Dev-Tools/devforge"
5757
"Issue Tracker" = "https://github.com/Coding-Dev-Tools/devforge/issues"
5858

5959
[project.scripts]
60-
rh = "revenueholdings.cli:app"
60+
devforge = "devforge.cli:app"
6161

6262
[tool.setuptools.packages.find]
6363
where = ["src"]
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
"""Revenue Holdings — unified CLI for all developer tools."""
1+
"""DevForge — unified CLI for all developer tools."""
22

3-
__version__ = "0.2.0"
3+
__version__ = "0.3.0"
44

55
# Tool registry: name -> (package, description, icon, pricing)
66
TOOLS = {
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
"""Revenue Holdings unified CLI entry point."""
1+
"""DevForge unified CLI entry point."""
22

33
import builtins as _builtins
44
import subprocess
55
import sys
66
import typer
7-
from revenueholdings import TOOLS, __version__
7+
from devforge import TOOLS, __version__
88
from rich.console import Console
99
from rich.panel import Panel
1010
from rich.table import Table
1111

1212
app = typer.Typer(
13-
name="rh",
14-
help="Revenue Holdings — unified CLI for developer tools.",
13+
name="devforge",
14+
help="DevForge — unified CLI for developer tools.",
1515
rich_markup_mode="rich",
1616
)
1717
console = Console()
1818

1919

2020
def _show_version(value: bool) -> None:
2121
if value:
22-
console.print(f"[bold]rh[/] v{__version__}Revenue Holdings CLI")
22+
console.print(f"[bold]devforge[/] v{__version__}DevForge CLI")
2323
raise typer.Exit()
2424

2525

@@ -41,7 +41,7 @@ def main_callback(
4141
def list_tools(
4242
name: str | None = typer.Argument(None, help="Show details for a specific tool."),
4343
):
44-
"""List available Revenue Holdings CLI tools."""
44+
"""List available DevForge CLI tools."""
4545
if name:
4646
tool = TOOLS.get(name)
4747
if not tool:
@@ -55,11 +55,11 @@ def list_tools(
5555
f"Pricing: [yellow]{tool['pricing']}[/yellow]\n"
5656
f"Status: [green]{tool['status']}[/green]\n"
5757
f"URL: {tool['url']}",
58-
title=f"rh {name}",
58+
title=f"devforge {name}",
5959
)
6060
)
6161
else:
62-
table = Table(title="Revenue Holdings CLI Tools")
62+
table = Table(title="DevForge CLI Tools")
6363
table.add_column("Command", style="cyan")
6464
table.add_column("Package", style="green")
6565
table.add_column("Description")
@@ -76,8 +76,8 @@ def list_tools(
7676
)
7777

7878
console.print(table)
79-
console.print("\n[dim]Install individually:[/dim] [green]pip install revenueholdings[guard][/green]")
80-
console.print("[dim]Install all:[/dim] [green]pip install revenueholdings[all][/green]")
79+
console.print("\n[dim]Install individually:[/dim] [green]pip install devforge[guard][/green]")
80+
console.print("[dim]Install all:[/dim] [green]pip install devforge[all][/green]")
8181

8282

8383
@app.command()
@@ -86,7 +86,7 @@ def install(
8686
..., help="Tool to install: " + ", ".join(TOOLS.keys()) + ", or 'all'"
8787
),
8888
):
89-
"""Install a Revenue Holdings tool."""
89+
"""Install a DevForge tool."""
9090
if tool == "all":
9191
targets = _builtins.list(TOOLS.keys())
9292
extras = ",".join(TOOLS.keys())
@@ -98,7 +98,7 @@ def install(
9898
console.print(f"Available: {', '.join(TOOLS.keys())}, 'all'")
9999
raise typer.Exit(code=1)
100100

101-
pkg = f"revenueholdings[{extras}]"
101+
pkg = f"devforge[{extras}]"
102102
console.print(f"[yellow]Installing {pkg}...[/yellow]")
103103
try:
104104
result = subprocess.run(
@@ -168,7 +168,7 @@ def dispatch(
168168
except FileNotFoundError:
169169
console.print(
170170
f"[red]Tool '{tool_name}' not installed.[/red]\n"
171-
f"Install with: [green]pip install revenueholdings[{tool_name}][/green]"
171+
f"Install with: [green]pip install devforge[{tool_name}][/green]"
172172
)
173173
raise typer.Exit(code=1) from None
174174

tests/test_cli.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
"""Tests for revenueholdings meta-package."""
1+
"""Tests for devforge meta-package."""
22
from __future__ import annotations
33

4-
from revenueholdings import TOOLS, __version__
5-
from revenueholdings.cli import app
4+
from devforge import TOOLS, __version__
5+
from devforge.cli import app
66
from typer.testing import CliRunner
77
from unittest import mock
88

@@ -13,7 +13,7 @@ class TestVersion:
1313
def test_version_flag(self):
1414
result = runner.invoke(app, ["--version"])
1515
assert result.exit_code == 0
16-
assert "revenueholdings" in result.stdout.lower() or "rh" in result.stdout.lower()
16+
assert "devforge" in result.stdout.lower()
1717
assert __version__ in result.stdout
1818

1919

@@ -37,7 +37,7 @@ def test_unknown_tool(self):
3737

3838

3939
class TestInstallCommand:
40-
@mock.patch("revenueholdings.cli.subprocess.run")
40+
@mock.patch("devforge.cli.subprocess.run")
4141
def test_install_specific_tool(self, mock_run):
4242
"""Install a specific tool by name."""
4343
mock_run.return_value = mock.MagicMock(returncode=0, stdout="", stderr="")
@@ -46,7 +46,7 @@ def test_install_specific_tool(self, mock_run):
4646
assert "Successfully" in result.stdout
4747
mock_run.assert_called_once()
4848

49-
@mock.patch("revenueholdings.cli.subprocess.run")
49+
@mock.patch("devforge.cli.subprocess.run")
5050
def test_install_all(self, mock_run):
5151
"""Install all tools via the 'all' alias."""
5252
mock_run.return_value = mock.MagicMock(returncode=0, stdout="", stderr="")
@@ -62,7 +62,7 @@ def test_install_unknown_tool(self):
6262
assert "Unknown" in result.stdout
6363
assert "Available:" in result.stdout
6464

65-
@mock.patch("revenueholdings.cli.subprocess.run")
65+
@mock.patch("devforge.cli.subprocess.run")
6666
def test_install_failure(self, mock_run):
6767
"""Handle pip install failure gracefully."""
6868
mock_run.return_value = mock.MagicMock(returncode=1, stdout="", stderr="Error message")
@@ -83,7 +83,7 @@ def test_versions_unknown_tool_fails(self):
8383
assert result.exit_code == 1
8484
assert "Unknown" in result.stdout
8585

86-
@mock.patch("revenueholdings.cli.subprocess.run")
86+
@mock.patch("devforge.cli.subprocess.run")
8787
def test_versions_specific_tool_not_installed(self, mock_run):
8888
"""Show 'not installed' for a tool that isn't installed."""
8989
mock_run.return_value = mock.MagicMock(

0 commit comments

Comments
 (0)