Skip to content

Commit 7bc9a40

Browse files
authored
Merge pull request #128 from Miyamura80/ralph/onboarding-cli
feat: Interactive onboarding CLI with Typer
2 parents ca989c2 + 2aa1add commit 7bc9a40

11 files changed

Lines changed: 766 additions & 77 deletions

File tree

.github/workflows/linter_require_ruff.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
- name: Add uv to path
2626
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
2727
- name: Setup
28-
run: make setup
28+
run: uv sync && make install_tools
2929
- name: Run ruff
3030
run: make ruff
3131
- name: Run complexity check

CLAUDE.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ Super-opinionated Python stack for fast development. Python >= 3.12 required. Us
99
## Common Commands
1010

1111
```bash
12-
# Setup & Run
13-
make init name=... description=... # Initialize project name and description
14-
make setup # Create/update .venv and sync dependencies
15-
make all # Run main.py with setup
12+
# Onboarding & Setup
13+
make onboard # Interactive onboarding CLI (rename, deps, env, hooks, media)
14+
make all # Sync deps and run main.py
1615

1716
# Testing
1817
make test # Run pytest on tests/
@@ -138,6 +137,7 @@ Structure as: `init()` → `continue(id)` → `cleanup(id)`
138137
- **Protected Branch**: `main` is protected. Do not push directly to `main`. Use PRs.
139138
- **Merge Strategy**: Squash and merge.
140139
- **Never force push**: Do not use `git push --force` or `--force-with-lease`. If you hit a git issue, stop and ask the user for guidance.
140+
- **Pre-commit CI gate**: Always run `make ci` before committing any changes. Ensure it passes with zero errors. Do not commit if `make ci` fails - fix all issues first, then commit.
141141

142142
## Deprecated
143143

Makefile

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,9 @@ help: ## Show this help message
3636
########################################################
3737

3838
### Initialization
39-
.PHONY: init banner logo
40-
init: ## Initialize project (usage: make init name=my-project description="my description")
41-
@if [ -z "$(name)" ] || [ -z "$(description)" ]; then \
42-
echo "$(RED)Error: Both 'name' and 'description' parameters are required$(RESET)"; \
43-
echo "Usage: make init name=<project_name> description=<project_description>"; \
44-
exit 1; \
45-
fi
46-
@echo "$(YELLOW)🚀 Initializing project $(name)...$(RESET)"
47-
@sed -i.bak "s/name = \"python-template\"/name = \"$(name)\"/" pyproject.toml && rm pyproject.toml.bak
48-
@sed -i.bak "s/description = \"Add your description here\"/description = \"$(description)\"/" pyproject.toml && rm pyproject.toml.bak
49-
@sed -i.bak "s/# Python-Template/# $(name)/" README.md && rm README.md.bak
50-
@sed -i.bak "s/<b>Opinionated Python project stack. 🔋 Batteries included. <\/b>/<b>$(description)<\/b>/" README.md && rm README.md.bak
51-
@echo "$(GREEN)✅ Updated project name and description.$(RESET)"
39+
.PHONY: onboard banner logo
40+
onboard: check_uv ## Run interactive onboarding CLI
41+
@$(PYTHON) onboard.py
5242

5343
banner: check_uv ## Generate project banner image
5444
@echo "$(YELLOW)🔍Generating banner...$(RESET)"
@@ -84,31 +74,10 @@ check_jq:
8474
jq --version; \
8575
fi
8676

87-
########################################################
88-
# Setup githooks for linting
89-
########################################################
90-
setup_githooks:
91-
@echo "$(YELLOW)🔨Setting up githooks on post-commit...$(RESET)"
92-
chmod +x .githooks/post-commit
93-
git config core.hooksPath .githooks
94-
95-
9677
########################################################
9778
# Python dependency-related
9879
########################################################
9980

100-
### Setup & Dependencies
101-
setup: check_uv ## Create venv and sync dependencies
102-
@echo "$(YELLOW)🔎Looking for .venv...$(RESET)"
103-
@if [ ! -d ".venv" ]; then \
104-
echo "$(YELLOW)VS Code is not detected. Creating a new one...$(RESET)"; \
105-
uv venv; \
106-
else \
107-
echo "$(GREEN)✅.venv is detected.$(RESET)"; \
108-
fi
109-
@echo "$(YELLOW)🔄Updating python dependencies...$(RESET)"
110-
@uv sync
111-
11281
view_python_venv_size:
11382
@echo "$(YELLOW)🔍Checking python venv size...$(RESET)"
11483
@PYTHON_VERSION=$$(cat .python-version | cut -d. -f1,2) && \
@@ -126,7 +95,8 @@ view_python_venv_size_by_libraries:
12695
########################################################
12796

12897
### Running
129-
all: setup setup_githooks ## Setup and run main application
98+
all: check_uv ## Sync dependencies and run main application
99+
@uv sync
130100
@echo "$(GREEN)🏁Running main application...$(RESET)"
131101
@$(PYTHON) main.py
132102
@echo "$(GREEN)✅ Main application run completed.$(RESET)"

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@ Opinionated Python stack for fast development. The `saas` branch extends `main`
5555

5656
## Quick Start
5757

58-
- `make init name=my-project description="My project description"` - initialize project
59-
- `make all` - runs `main.py`
58+
- `make onboard` - interactive onboarding CLI (rename, deps, env, hooks, media)
59+
- `make all` - sync deps and run `main.py`
6060
- `make fmt` - runs `ruff format` + JSON formatting
61-
- `make banner` - create a new banner that makes the README nice 😊
6261
- `make test` - runs all tests in `tests/`
6362
- `make ci` - runs all CI checks (ruff, vulture, ty, etc.)
6463

6564

6665

66+
6767
## Configuration
6868

6969
```python

init/generate_banner.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class BannerDescription(dspy.Signature):
1515
"""Generate a creative description of a person/animal/object holding a banner. Go for a japanese style, creative and fun, but make sense."""
1616

1717
title: str = dspy.InputField()
18-
suggestion: str = dspy.InputField(
19-
desc="Optional suggestion to guide the banner description generation"
18+
theme: str = dspy.InputField(
19+
desc="Optional theme/style suggestion to guide the banner description generation"
2020
)
2121
banner_description: str = dspy.OutputField(
2222
desc="A creative description of a person/animal/object holding a banner with the given title. Do not mention any colors"
@@ -26,7 +26,13 @@ class BannerDescription(dspy.Signature):
2626
client = genai.Client(api_key=global_config.GEMINI_API_KEY)
2727

2828

29-
async def generate_banner(title: str, suggestion: str | None = None) -> Image.Image:
29+
async def generate_banner(title: str, theme: str | None = None) -> Image.Image:
30+
"""Generate a banner image for the project.
31+
32+
Args:
33+
title: The project title to display on the banner.
34+
theme: Optional theme/style suggestion to guide image generation.
35+
"""
3036
# First, use LLM to generate a creative banner description
3137
inf_module = DSPYInference(
3238
pred_signature=BannerDescription,
@@ -35,7 +41,7 @@ async def generate_banner(title: str, suggestion: str | None = None) -> Image.Im
3541

3642
result = await inf_module.run(
3743
title=title,
38-
suggestion=suggestion or "",
44+
theme=theme or "",
3945
)
4046

4147
print(result.banner_description)
@@ -72,5 +78,5 @@ async def generate_banner(title: str, suggestion: str | None = None) -> Image.Im
7278

7379
if __name__ == "__main__":
7480
title = "Python-Template"
75-
suggestion = "use a snake in the image"
76-
asyncio.run(generate_banner(title, suggestion))
81+
theme = "use a snake in the image"
82+
asyncio.run(generate_banner(title, theme))

init/generate_logo.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ class WordmarkDescription(dspy.Signature):
1616
"""Generate a creative description for a horizontal wordmark logo with text. The wordmark should be clean, modern, and professional."""
1717

1818
project_name: str = dspy.InputField()
19-
suggestion: str = dspy.InputField(
20-
desc="Optional suggestion to guide the wordmark description generation"
19+
theme: str = dspy.InputField(
20+
desc="Optional theme/style suggestion to guide the wordmark description generation"
2121
)
2222
wordmark_description: str = dspy.OutputField(
2323
desc="A creative description for a horizontal wordmark logo that includes the project name as text. Focus on typography, icon placement, and professional branding. The wordmark should be wide and horizontal."
@@ -93,7 +93,7 @@ def invert_colors(img: Image.Image) -> Image.Image:
9393

9494

9595
async def generate_logo(
96-
project_name: str, suggestion: str | None = None, output_dir: Path | None = None
96+
project_name: str, theme: str | None = None, output_dir: Path | None = None
9797
) -> dict[str, Image.Image]:
9898
"""Generate logo assets using AI-powered pipeline with consistent branding:
9999
1. Generate light mode wordmark with greenscreen
@@ -107,7 +107,7 @@ async def generate_logo(
107107
108108
Args:
109109
project_name: Name of the project
110-
suggestion: Optional suggestion to guide the logo generation
110+
theme: Optional theme/style suggestion to guide the logo generation
111111
output_dir: Output directory for the generated images. Defaults to docs/public/
112112
113113
Returns:
@@ -128,7 +128,7 @@ async def generate_logo(
128128
wordmark_inf = DSPYInference(pred_signature=WordmarkDescription, observe=False)
129129
wordmark_result = await wordmark_inf.run(
130130
project_name=project_name,
131-
suggestion=suggestion or "",
131+
theme=theme or "",
132132
)
133133

134134
print(f"Wordmark description: {wordmark_result.wordmark_description}")
@@ -264,5 +264,5 @@ async def generate_logo(
264264

265265
if __name__ == "__main__":
266266
project_name = "Python-Template"
267-
suggestion = "incorporate python snake and modern tech aesthetics, simple and clean"
268-
asyncio.run(generate_logo(project_name, suggestion))
267+
theme = "incorporate python snake and modern tech aesthetics, simple and clean"
268+
asyncio.run(generate_logo(project_name, theme))

0 commit comments

Comments
 (0)