Function bodies 398 total
_has_project_content function · python · L27-L39 (13 LOC)lib/vibe/agents/generator.py
def _has_project_content(file_path: Path) -> bool:
"""Check if file exists and has project-specific (non-template) content."""
if not file_path.exists():
return False
try:
content = file_path.read_text()
# If it's empty or has placeholder patterns, it's not project-specific
if not content.strip():
return False
return not _is_generated_file(content)
except OSError:
return False_render_labels_section function · python · L42-L70 (29 LOC)lib/vibe/agents/generator.py
def _render_labels_section(labels: dict[str, list[str]]) -> list[str]:
"""Render the Available Labels section from config labels.
Returns a list of lines (without trailing newline) for embedding into
the generated output.
"""
lines: list[str] = []
lines.append("## Available Labels")
lines.append("")
lines.append(
"These labels are configured in `.vibe/config.json`. Apply them when creating tickets."
)
lines.append("")
category_titles = {
"type": "Type (exactly one required)",
"risk": "Risk (exactly one required)",
"area": "Area (at least one required)",
"special": "Special (as needed)",
}
for category in ("type", "risk", "area", "special"):
values = labels.get(category, [])
if values:
title = category_titles.get(category, category.title())
lines.append(f"**{title}:** {', '.join(values)}")
lines.append("")
return lines_render_ticket_discipline_section function · python · L73-L133 (61 LOC)lib/vibe/agents/generator.py
def _render_ticket_discipline_section() -> list[str]:
"""Render the Ticket Discipline section with enforcement rules.
Returns a list of lines for embedding into generated output.
"""
lines: list[str] = []
lines.append("## Ticket Discipline")
lines.append("")
lines.append("Follow these rules for every ticket and PR:")
lines.append("")
lines.append("### Labels Are Required")
lines.append("")
lines.append("Every ticket **must** have labels when created:")
lines.append("")
lines.append("- **Type** (exactly one): Bug, Feature, Chore, or Refactor")
lines.append("- **Area** (at least one): Frontend, Backend, Infra, or Docs")
lines.append("- **Risk** (exactly one): Low Risk, Medium Risk, or High Risk")
lines.append("")
lines.append("```bash")
lines.append(
'bin/ticket create "Fix login bug" '
'--description "Login returns 500 on special chars." '
'--label Bug --label Frontend --label "Low Risk"'
InstructionGenerator.generate method · python · L143-L152 (10 LOC)lib/vibe/agents/generator.py
def generate(self, format: AssistantFormat) -> str:
"""Generate instructions for the specified format."""
generators = {
AssistantFormat.CLAUDE: self._generate_claude,
AssistantFormat.CURSOR: self._generate_cursor,
AssistantFormat.COPILOT: self._generate_copilot,
AssistantFormat.CODEX: self._generate_codex,
AssistantFormat.GENERIC: self._generate_generic,
}
return generators[format]()InstructionGenerator.generate_all method · python · L154-L208 (55 LOC)lib/vibe/agents/generator.py
def generate_all(
self,
output_dir: Path,
formats: list[AssistantFormat] | None = None,
force: bool = False,
) -> dict[str, Path]:
"""Generate all instruction files to the specified directory.
Args:
output_dir: Directory to write files to
formats: List of formats to generate (default: CLAUDE, CURSOR, COPILOT)
force: If True, overwrite files even if they have project-specific content
Returns:
Dict mapping format name to output path (only for files that were written)
"""
if formats is None:
formats = [
AssistantFormat.CLAUDE,
AssistantFormat.CURSOR,
AssistantFormat.COPILOT,
]
results: dict[str, Path] = {}
skipped: dict[str, Path | str] = {}
for format in formats:
output_path = output_dir / format.output_path
# Check if path is a directory InstructionGenerator._header method · python · L215-L224 (10 LOC)lib/vibe/agents/generator.py
def _header(self, format_name: str) -> str:
"""Generate file header with timestamp."""
timestamp = datetime.now().strftime("%Y-%m-%d")
return f"""# AI Agent Instructions
# Format: {format_name}
# Generated: {timestamp}
# Source: agent_instructions/
#
# DO NOT EDIT DIRECTLY - regenerate with: bin/vibe generate-agent-instructions
"""InstructionGenerator._generate_claude method · python · L226-L349 (124 LOC)lib/vibe/agents/generator.py
def _generate_claude(self) -> str:
"""Generate CLAUDE.md format."""
lines = [self._header("Claude Code")]
lines.append("")
lines.append("# CLAUDE.md - AI Agent Instructions")
lines.append("")
# Project overview
if self.spec.project_name or self.spec.project_description:
lines.append("## Project Overview")
lines.append("")
if self.spec.project_name:
lines.append(f"**Project:** {self.spec.project_name}")
if self.spec.project_description:
lines.append(f"**Description:** {self.spec.project_description}")
if self.spec.tech_stack:
lines.append("")
lines.append("**Tech Stack:**")
for key, value in self.spec.tech_stack.items():
lines.append(f"- {key}: {value}")
lines.append("")
lines.append("---")
lines.append("")
# Core rules
Repobility · MCP-ready · https://repobility.com
InstructionGenerator._generate_cursor method · python · L351-L427 (77 LOC)lib/vibe/agents/generator.py
def _generate_cursor(self) -> str:
"""Generate .cursor/rules format.
Cursor uses a more concise format focused on rules.
"""
lines = [self._header("Cursor IDE")]
lines.append("")
# Project context (brief)
if self.spec.project_name:
lines.append(f"# Project: {self.spec.project_name}")
if self.spec.project_description:
lines.append(f"# {self.spec.project_description}")
lines.append("")
# Tech stack as context
if self.spec.tech_stack:
lines.append("# Tech Stack")
for key, value in self.spec.tech_stack.items():
lines.append(f"# - {key}: {value}")
lines.append("")
# Core rules - Cursor format prefers direct statements
if self.spec.core_rules:
lines.append("# Rules")
lines.append("")
for rule in self.spec.core_rules:
lines.append(f"{rule}")
linInstructionGenerator._generate_copilot method · python · L429-L504 (76 LOC)lib/vibe/agents/generator.py
def _generate_copilot(self) -> str:
"""Generate .github/copilot-instructions.md format.
GitHub Copilot uses markdown with specific conventions.
"""
lines = [self._header("GitHub Copilot")]
lines.append("")
lines.append("# Copilot Instructions")
lines.append("")
# Project context
if self.spec.project_name or self.spec.project_description:
lines.append("## About This Project")
lines.append("")
if self.spec.project_name:
lines.append(f"This is **{self.spec.project_name}**.")
if self.spec.project_description:
lines.append(self.spec.project_description)
lines.append("")
# Tech stack
if self.spec.tech_stack:
lines.append("## Technology Stack")
lines.append("")
for key, value in self.spec.tech_stack.items():
lines.append(f"- **{key}**: {value}")
InstructionGenerator._generate_generic method · python · L511-L599 (89 LOC)lib/vibe/agents/generator.py
def _generate_generic(self) -> str:
"""Generate generic AGENTS.md format."""
lines = [self._header("Generic AI Assistant")]
lines.append("")
lines.append("# AGENTS.md - AI Agent Instructions")
lines.append("")
lines.append(
"This file provides instructions for AI coding assistants working on this project."
)
lines.append("")
# Project overview
if self.spec.project_name or self.spec.project_description:
lines.append("## Project")
lines.append("")
if self.spec.project_name:
lines.append(f"**Name:** {self.spec.project_name}")
if self.spec.project_description:
lines.append(f"**Description:** {self.spec.project_description}")
lines.append("")
# Tech stack
if self.spec.tech_stack:
lines.append("## Tech Stack")
lines.append("")
for key, value in self.specInstructionSpec.from_files method · python · L99-L138 (40 LOC)lib/vibe/agents/spec.py
def from_files(
cls,
instructions_dir: Path,
config_labels: dict[str, list[str]] | None = None,
) -> InstructionSpec:
"""Load instruction spec from markdown files in a directory.
Expected files:
- CORE.md - Core rules and context
- COMMANDS.md - Available commands
- WORKFLOW.md - Workflow definitions
Args:
instructions_dir: Path to the agent_instructions/ directory.
config_labels: Label categories from .vibe/config.json (labels.type,
labels.risk, labels.area, labels.special). When provided, the
generated output will include an "Available Labels" section.
"""
spec = cls()
# Load CORE.md
core_path = instructions_dir / "CORE.md"
if core_path.exists():
spec._parse_core(core_path.read_text())
# Load COMMANDS.md
commands_path = instructions_dir / "COMMANDS.md"
if commands_path.exInstructionSpec._parse_core method · python · L140-L163 (24 LOC)lib/vibe/agents/spec.py
def _parse_core(self, content: str) -> None:
"""Parse CORE.md content."""
lines = content.split("\n")
current_section = None
section_content: list[str] = []
for line in lines:
# Handle both # and ## as section headers
if line.startswith("## "):
if current_section and section_content:
self._process_core_section(current_section, section_content)
current_section = line[3:].strip()
section_content = []
elif line.startswith("# ") and not line.startswith("## "):
# Top-level header - skip but reset section
if current_section and section_content:
self._process_core_section(current_section, section_content)
current_section = None
section_content = []
elif current_section:
section_content.append(line)
if current_section and sectioInstructionSpec._process_core_section method · python · L165-L203 (39 LOC)lib/vibe/agents/spec.py
def _process_core_section(self, section: str, content: list[str]) -> None:
"""Process a section from CORE.md."""
text = "\n".join(content).strip()
section_lower = section.lower()
if "project" in section_lower:
# Extract project info
for line in content:
if line.startswith("- **Name**:"):
self.project_name = line.split(":", 1)[1].strip()
elif line.startswith("- **Description**:"):
self.project_description = line.split(":", 1)[1].strip()
elif "tech stack" in section_lower:
for line in content:
if line.startswith("- "):
parts = line[2:].split(":", 1)
if len(parts) == 2:
self.tech_stack[parts[0].strip()] = parts[1].strip()
elif "rules" in section_lower or "must" in section_lower:
for line in content:
if line.startswith("- ") InstructionSpec._parse_commands method · python · L205-L259 (55 LOC)lib/vibe/agents/spec.py
def _parse_commands(self, content: str) -> None:
"""Parse COMMANDS.md content."""
lines = content.split("\n")
current_command = None
current_category = "general"
i = 0
while i < len(lines):
line = lines[i]
# Category header
if line.startswith("## "):
current_category = line[3:].strip().lower()
# Command definition
elif line.startswith("### "):
if current_command:
self.commands.append(current_command)
name = line[4:].strip()
description = ""
usage = ""
examples: list[str] = []
# Look for description and usage in following lines
i += 1
while i < len(lines) and not lines[i].startswith("### "):
subline = lines[i]
if subline.startswith("**Usage**:"):
uInstructionSpec._parse_workflow method · python · L261-L316 (56 LOC)lib/vibe/agents/spec.py
def _parse_workflow(self, content: str) -> None:
"""Parse WORKFLOW.md content."""
lines = content.split("\n")
current_workflow = None
current_steps: list[WorkflowStep] = []
i = 0
while i < len(lines):
line = lines[i]
# Workflow header
if line.startswith("## "):
if current_workflow and current_steps:
self.workflows[current_workflow] = current_steps
current_workflow = line[3:].strip()
current_steps = []
# Step
elif line.startswith("### "):
step_title = line[4:].strip()
step_description = ""
step_commands: list[str] = []
# Collect step content
i += 1
while (
i < len(lines)
and not lines[i].startswith("## ")
and not lines[i].startswith("### ")
Open data scored by Repobility · https://repobility.com
InstructionSpec.to_dict method · python · L318-L345 (28 LOC)lib/vibe/agents/spec.py
def to_dict(self) -> dict[str, Any]:
"""Convert spec to dictionary for serialization."""
return {
"project_name": self.project_name,
"project_description": self.project_description,
"tech_stack": self.tech_stack,
"core_rules": self.core_rules,
"commands": [
{
"name": c.name,
"description": c.description,
"usage": c.usage,
"examples": c.examples,
"category": c.category,
}
for c in self.commands
],
"workflows": {
name: [
{"title": s.title, "description": s.description, "commands": s.commands}
for s in steps
]
for name, steps in self.workflows.items()
},
"important_files": self.important_files,
"anti_patterns": self.antanalyze_cmd function · python · L39-L68 (30 LOC)lib/vibe/cli/figma.py
def analyze_cmd(project_path: str, output_json: bool, figma_context: bool) -> None:
"""Analyze frontend codebase for design system context.
Detects frameworks, UI libraries, design tokens, and existing components
to provide context for Figma AI prompts.
"""
path = Path(project_path).resolve()
if not path.exists():
click.secho(f"Error: Path {path} does not exist", fg="red", err=True)
sys.exit(1)
analyzer = FrontendAnalyzer(path)
try:
analysis = analyzer.analyze()
except (OSError, ValueError) as e:
click.secho(f"Error analyzing project: {e}", fg="red", err=True)
sys.exit(1)
if output_json:
click.echo(analysis.to_json())
elif figma_context:
context = analysis.get_figma_context()
if context:
click.echo(context)
else:
click.secho("No design system context detected", fg="yellow")
else:
_print_analysis_summary(analysis)_print_analysis_summary function · python · L71-L144 (74 LOC)lib/vibe/cli/figma.py
def _print_analysis_summary(analysis) -> None:
"""Print human-readable analysis summary."""
click.secho("\n📊 Frontend Analysis", fg="cyan", bold=True)
click.echo("=" * 40)
# Framework
if analysis.framework:
version = f" ({analysis.framework_version})" if analysis.framework_version else ""
click.echo(f"Framework: {click.style(analysis.framework + version, fg='green')}")
else:
click.echo("Framework: " + click.style("Not detected", fg="yellow"))
# UI Library
if analysis.ui_library:
version = f" ({analysis.ui_library_version})" if analysis.ui_library_version else ""
click.echo(f"UI Library: {click.style(analysis.ui_library + version, fg='green')}")
else:
click.echo("UI Library: " + click.style("Not detected", fg="yellow"))
# CSS Framework
if analysis.css_framework:
version = f" ({analysis.css_framework_version})" if analysis.css_framework_version else ""
click.echo(f"CSS Frameworkprompt_cmd function · python · L175-L278 (104 LOC)lib/vibe/cli/figma.py
def prompt_cmd(
project_path: str,
feature: str | None,
user_goal: str | None,
devices: str | None,
interactive: bool,
) -> None:
"""Generate an optimized Figma AI prompt with codebase context.
Analyzes your codebase and generates a Figma AI prompt that includes:
- Design system context (colors, fonts, spacing)
- Existing component patterns to match
- Common pitfall warnings
"""
path = Path(project_path).resolve()
analyzer = FrontendAnalyzer(path)
analysis = analyzer.analyze()
# Interactive mode or prompts for missing values
if interactive or (not feature and not user_goal):
# Feature type selection
if not feature:
feature_menu = NumberedMenu(
title="What type of feature are you designing?",
options=[
("Page", "A full page layout (dashboard, settings, profile)"),
("Form", "User input form (signup, checkout, settings)"),
_generate_figma_prompt function · python · L281-L347 (67 LOC)lib/vibe/cli/figma.py
def _generate_figma_prompt(analysis, feature: str, user_goal: str, devices: list[str]) -> str:
"""Generate an optimized Figma AI prompt."""
lines = []
# Header
lines.append(f"Design a {feature} that helps users {user_goal}.")
lines.append("")
# Design system context
context = analysis.get_figma_context()
if context:
lines.append("## Design System Context")
lines.append("Use these exact values to match the existing codebase:")
lines.append("")
lines.append(context)
lines.append("")
# Device targets
lines.append("## Target Devices")
for device in devices:
if device.lower() == "mobile":
lines.append("- Mobile (375px width)")
elif device.lower() == "tablet":
lines.append("- Tablet (768px width)")
else:
lines.append("- Desktop (1280px width)")
lines.append("")
# Existing components to reuse
if analysis.components:
ui_comps = tickets_cmd function · python · L374-L413 (40 LOC)lib/vibe/cli/figma.py
def tickets_cmd(figma_link: str, description: str, project_path: str, dry_run: bool) -> None:
"""Break down a Figma design into implementation tickets.
Analyzes the description and creates tickets for:
- Layout/structure components
- UI components (new ones needed)
- Feature integration
- Responsive adjustments
"""
path = Path(project_path).resolve()
analyzer = FrontendAnalyzer(path)
analysis = analyzer.analyze()
tickets = _generate_tickets(figma_link, description, analysis)
click.secho("\n🎫 Implementation Tickets", fg="cyan", bold=True)
click.echo("=" * 50)
for i, ticket in enumerate(tickets, 1):
click.echo()
click.secho(f"Ticket {i}: {ticket['title']}", fg="green", bold=True)
click.echo(f" Type: {ticket['type']}")
click.echo(f" Risk: {ticket['risk']}")
click.echo(f" Area: {ticket['area']}")
if ticket.get("blocked_by"):
click.echo(f" Blocked by: Ticket {ticket['b_generate_tickets function · python · L416-L504 (89 LOC)lib/vibe/cli/figma.py
def _generate_tickets(figma_link: str, description: str, analysis) -> list[dict[str, Any]]:
"""Generate ticket specifications from design description."""
tickets: list[dict[str, Any]] = []
# Ticket 1: Layout/Structure
tickets.append(
{
"title": f"Implement layout structure for {description}",
"type": "Feature",
"risk": "Low Risk",
"area": "Frontend",
"description": f"""## Summary
Implement the layout structure as shown in the Figma design.
## Design Reference
- Figma: {figma_link}
## Acceptance Criteria
- [ ] Layout matches design at all breakpoints
- [ ] Responsive behavior implemented
- [ ] Grid/flex structure follows existing patterns
## Implementation Notes
- Use existing layout components where possible
- Focus on structure first, then styling""",
}
)
# Ticket 2: UI Components
existing_ui = [c.name for c in analysis.components if c.component_type == "ui"]
tickets.append_create_tickets function · python · L507-L539 (33 LOC)lib/vibe/cli/figma.py
def _create_tickets(tickets: list[dict[str, Any]]) -> None:
"""Create tickets using the ticket CLI."""
import subprocess
created_ids: dict[int, str] = {}
for i, ticket in enumerate(tickets, 1):
cmd = [
"bin/ticket",
"create",
ticket["title"],
"--label",
ticket["type"],
"--label",
ticket["risk"],
"--label",
ticket["area"],
]
# Add blocking relationship if applicable
if ticket.get("blocked_by") and ticket["blocked_by"] in created_ids:
cmd.extend(["--blocked-by", created_ids[ticket["blocked_by"]]])
try:
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
click.secho(f"✓ Created ticket {i}", fg="green")
# Store ID for blocking relationships (simplified - real impl would parse ID from result.stdout)
created_Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
main function · python · L27-L36 (10 LOC)lib/vibe/cli/main.py
def main() -> None:
"""Vibe Code Boilerplate - AI-assisted development workflows."""
try:
from lib.vibe.update_check import check_for_update, format_update_notice
update_info = check_for_update()
if update_info:
click.echo(format_update_notice(update_info), err=True)
except Exception: # noqa: BLE001
pass # Never let update check break the CLIbump function · python · L47-L52 (6 LOC)lib/vibe/cli/main.py
def bump(bump_type: str) -> None:
"""Bump the project version (patch or minor)."""
current = get_version()
new = bump_version(current, bump_type)
write_version(new)
click.echo(f"{current} → {new}")update function · python · L58-L187 (130 LOC)lib/vibe/cli/main.py
def update(skip: bool, force: bool) -> None:
"""Check for and apply boilerplate updates."""
import subprocess
from lib.vibe.update_check import check_for_update, skip_update_check
if skip:
skip_update_check()
click.echo("Update notice dismissed for 7 days.")
return
click.echo("Checking for boilerplate updates...")
update_info = check_for_update(force=True)
if not update_info:
click.echo(f"Already up to date (v{get_version()}).")
return
current = update_info["current_version"]
upstream = update_info["upstream_version"]
click.echo(f"Update available: {current} -> {upstream}")
if not click.confirm("Create a PR to sync the latest boilerplate?"):
return
# Create branch
branch_name = f"chore/boilerplate-update-{upstream}"
try:
subprocess.run(
["git", "checkout", "-b", branch_name],
check=True,
capture_output=True,
text=True,
setup function · python · L198-L212 (15 LOC)lib/vibe/cli/main.py
def setup(force: bool, wizard: str | None, quick: bool) -> None:
"""Run the setup wizard to configure your project.
Use --quick for a fast setup (< 1 minute) with sensible defaults and no
prompts. Perfect for trying out the boilerplate or when you want to
configure integrations later.
"""
if wizard:
success = run_individual_wizard(wizard)
elif quick:
success = run_setup(force=force, quick=True)
else:
success = run_setup(force=force)
sys.exit(0 if success else 1)doctor function · python · L218-L225 (8 LOC)lib/vibe/cli/main.py
def doctor(verbose: bool, live: bool) -> None:
"""Check project health and configuration.
Use --live to perform actual API calls and verify that integrations
are working (e.g., test Linear API key, check Vercel auth).
"""
results = run_doctor(verbose=verbose, live_checks=live)
sys.exit(print_results(results))do function · python · L230-L283 (54 LOC)lib/vibe/cli/main.py
def do(ticket_id: str) -> None:
"""Start working on a ticket (creates worktree and branch from latest main)."""
import subprocess
from lib.vibe.config import load_config
from lib.vibe.git.branches import format_branch_name, get_main_branch
from lib.vibe.git.worktrees import create_worktree, get_primary_repo_root
from lib.vibe.state import record_ticket_branch
from lib.vibe.trackers.linear import LinearTracker
from lib.vibe.ui.components import Spinner
config = load_config()
tracker_type = config.get("tracker", {}).get("type")
# Get ticket info if tracker configured
title = None
if tracker_type == "linear":
tracker = LinearTracker()
with Spinner(f"Fetching ticket {ticket_id}"):
ticket = tracker.get_ticket(ticket_id)
if ticket:
title = ticket.title
click.echo(f"Found ticket: {ticket.title}")
# Create branch name
branch_name = format_branch_name(ticket_id, title)
_get_first_commit_headline function · python · L494-L508 (15 LOC)lib/vibe/cli/main.py
def _get_first_commit_headline(main_branch: str = "main") -> str | None:
"""Get the first commit message headline on this branch (relative to origin/<main_branch>)."""
try:
result = _subprocess.run(
["git", "log", f"origin/{main_branch}..HEAD", "--format=%s", "--reverse"],
capture_output=True,
text=True,
check=True,
)
lines = result.stdout.strip().splitlines()
if lines:
return lines[0].strip()
except _subprocess.CalledProcessError:
pass
return None_derive_pr_title function · python · L511-L573 (63 LOC)lib/vibe/cli/main.py
def _derive_pr_title(branch: str, config: dict) -> str:
"""Derive a meaningful PR title from branch name, tracker, or commit history.
Priority order:
1. Extract ticket ID from branch → fetch title from tracker → "TICKET-ID: Title"
2. No ticket ID but valid branch → first commit headline on branch
3. worktree-agent-* branch → warn and use first commit headline
4. Raw branch name as absolute last resort
"""
main_branch = config.get("branching", {}).get("main_branch", "main")
# Cache the first-commit headline so we only shell out once
headline = _get_first_commit_headline(main_branch)
# Step 1: Try to extract a ticket ID from the branch name
ticket_match = re.search(r"([A-Z]+-\d+)", branch)
ticket_id = ticket_match.group(1) if ticket_match else None
# Step 2: If we have a ticket ID, try to fetch the title from the tracker
if ticket_id:
tracker_type = config.get("tracker", {}).get("type")
if tracker_type:
About: code-quality intelligence by Repobility · https://repobility.com
_check_existing_prs_for_ticket function · python · L582-L619 (38 LOC)lib/vibe/cli/main.py
def _check_existing_prs_for_ticket(ticket_id: str) -> list[dict[str, object]]:
"""Query GitHub for open or recently-merged PRs referencing *ticket_id*.
Returns a list of dicts with ``number``, ``title``, ``state``, and ``url`` keys.
An empty list means no matching PRs were found (or ``gh`` is unavailable).
"""
import json as _json
try:
result = _subprocess.run(
[
"gh",
"pr",
"list",
"--search",
ticket_id,
"--state",
"all",
"--json",
"number,title,state,url",
"--limit",
"20",
],
capture_output=True,
text=True,
timeout=15,
)
if result.returncode == 0 and result.stdout.strip():
prs: list[dict[str, object]] = _json.loads(result.stdout)
# Filter to only PRs whose title actually contains_check_local_state_for_ticket_conflicts function · python · L622-L634 (13 LOC)lib/vibe/cli/main.py
def _check_local_state_for_ticket_conflicts(
ticket_id: str, current_branch: str
) -> list[dict[str, str]]:
"""Check .vibe/local_state.json for other branches associated with *ticket_id*.
Returns recorded branches that match the ticket but differ from *current_branch*.
"""
from lib.vibe.state import get_branches_for_ticket
recorded = get_branches_for_ticket(ticket_id)
return [
entry for entry in recorded if entry.get("branch") and entry["branch"] != current_branch
]_warn_duplicate_prs function · python · L637-L694 (58 LOC)lib/vibe/cli/main.py
def _warn_duplicate_prs(ticket_id: str, branch: str, *, skip_confirmation: bool = False) -> bool:
"""Run duplicate-PR checks and warn the user.
Returns ``True`` if it is safe to proceed (no duplicates found, or user
confirmed). Returns ``False`` if the user chose to abort.
"""
should_abort = False
# Check 1: Existing GitHub PRs for this ticket
existing_prs = _check_existing_prs_for_ticket(ticket_id)
if existing_prs:
merged_prs = [p for p in existing_prs if p.get("state") == "MERGED"]
open_prs = [p for p in existing_prs if p.get("state") == "OPEN"]
if merged_prs:
click.echo(
f"\n** WARNING: Found {len(merged_prs)} MERGED PR(s) for ticket "
f"{ticket_id}. This may be duplicate work. **",
err=True,
)
for p in merged_prs:
click.echo(
f" - PR #{p.get('number')}: {p.get('title')} ({p.get('url')})",
pr function · python · L701-L759 (59 LOC)lib/vibe/cli/main.py
def pr(title: str | None, body: str | None, web: bool) -> None:
"""Open a pull request for the current branch (run from your worktree when done)."""
import subprocess
from lib.vibe.config import load_config
from lib.vibe.git.branches import current_branch, get_main_branch
main_branch = get_main_branch()
branch = current_branch()
if branch == main_branch:
click.echo(
f"Cannot open PR from {main_branch}. Check out your feature branch first.", err=True
)
sys.exit(1)
config = load_config()
# Check for duplicate PRs before creating a new one
ticket_id = _extract_ticket_id(branch)
if ticket_id:
if not _warn_duplicate_prs(ticket_id, branch):
click.echo("PR creation cancelled.")
sys.exit(0)
args = ["gh", "pr", "create"]
if title:
args.extend(["--title", title])
else:
derived_title = _derive_pr_title(branch, config)
args.extend(["--title", deri_autolink_pr_to_ticket function · python · L762-L804 (43 LOC)lib/vibe/cli/main.py
def _autolink_pr_to_ticket(branch: str, pr_url: str, config: dict) -> None:
"""Best-effort: add a comment on the tracker ticket linking to the PR.
Extracts the ticket ID from the branch name, then posts a comment with
the PR URL if a tracker is configured. Failures are logged but never
prevent the PR from being created.
"""
if not pr_url:
return
ticket_match = re.search(r"([A-Z]+-\d+)", branch)
if not ticket_match:
return
ticket_id = ticket_match.group(1)
tracker_type = config.get("tracker", {}).get("type")
if not tracker_type:
return
try:
from lib.vibe.trackers.base import TrackerBase
tracker: TrackerBase | None = None
if tracker_type == "linear":
from lib.vibe.trackers.linear import LinearTracker
tracker = LinearTracker(
team_id=config.get("tracker", {}).get("config", {}).get("team_id")
)
elif tracker_type == "shortcut":
boilerplate_issue function · python · L819-L858 (40 LOC)lib/vibe/cli/main.py
def boilerplate_issue(title: str | None, body: str | None, print_only: bool) -> None:
"""Open the boilerplate repo's new-issue page (for reporting broken CLAUDE.md or recipes)."""
from urllib.parse import quote
try:
from lib.vibe.config import load_config
config = load_config()
base = (config.get("boilerplate") or {}).get("issues_url") or BOILERPLATE_ISSUES_URL
new_issue = base.rstrip("/").replace("/issues", "") + "/issues/new"
except (OSError, KeyError, RuntimeError):
new_issue = BOILERPLATE_NEW_ISSUE_URL
params = []
if title:
params.append(f"title={quote(title)}")
if body:
if body.startswith("@") or "/" in body:
try:
with open(body.lstrip("@")) as f:
body = f.read()
except OSError:
pass
params.append(f"body={quote(body)}")
if params:
new_issue += "?" + "&".join(params)
if print_only:
click.einit_actions function · python · L870-L959 (90 LOC)lib/vibe/cli/main.py
def init_actions(linear: bool, dry_run: bool, include_all: bool, interactive: bool) -> None:
"""Initialize GitHub Actions workflows, secrets, and labels.
Sets up:
- Core workflows (PR policy, security, lint, tests)
- Required labels (risk levels, types)
- Optionally: Linear integration workflows and secrets
LINEAR_API_KEY is read from the environment variable, not a CLI flag.
Set it before running: export LINEAR_API_KEY=lin_api_...
Examples:
bin/vibe init-actions # Core workflows only
bin/vibe init-actions --linear # Include Linear workflows
bin/vibe init-actions --interactive # Interactive workflow selection
bin/vibe init-actions --dry-run # Preview what would be done
"""
from lib.vibe.github_actions import init_github_actions
from lib.vibe.ui.components import MultiSelect
linear_api_key = os.environ.get("LINEAR_API_KEY")
# Interactive mode
if interacors_check function · python · L968-L994 (27 LOC)lib/vibe/cli/main.py
def cors_check(
url: str, origin: str, method: str, header: tuple[str, ...], json_output: bool
) -> None:
"""Check CORS configuration for a URL.
Diagnoses CORS issues by sending preflight and actual requests,
then analyzing the response headers.
Examples:
bin/vibe cors-check https://api.example.com/users
bin/vibe cors-check https://api.example.com/users -o http://myapp.com
bin/vibe cors-check https://api.example.com/users -m POST -H Authorization
"""
from lib.vibe.cors import check_cors, format_cors_result
result = check_cors(
url=url,
origin=origin,
method=method,
headers=list(header) if header else None,
)
click.echo(format_cors_result(result, json_output=json_output))
sys.exit(0 if result.success else 1)Repobility · MCP-ready · https://repobility.com
generate_agent_instructions function · python · L1260-L1384 (125 LOC)lib/vibe/cli/main.py
def generate_agent_instructions(
dry_run: bool,
force: bool,
formats: tuple[str, ...],
interactive: bool,
source_dir: Path,
output_dir: Path,
) -> None:
"""Generate assistant-specific instruction files from common spec.
Reads instruction spec from agent_instructions/ and generates:
- CLAUDE.md (Claude Code)
- .cursor/rules (Cursor IDE)
- .github/copilot-instructions.md (GitHub Copilot)
This allows maintaining a single source of truth for agent instructions.
"""
from lib.vibe.agents.generator import InstructionGenerator
from lib.vibe.agents.spec import AssistantFormat, InstructionSpec
from lib.vibe.ui.components import MultiSelect
source_path = Path(source_dir)
if not source_path.exists():
click.secho(f"Source directory not found: {source_path}", fg="red", err=True)
click.echo("Create agent_instructions/ with CORE.md, COMMANDS.md, WORKFLOW.md")
sys.exit(1)
# Determine which formats tocache_clear function · python · L1395-L1401 (7 LOC)lib/vibe/cli/main.py
def cache_clear(key: str | None) -> None:
"""Clear cached API responses."""
from lib.vibe.utils.cache import get_cache
c = get_cache()
count = c.invalidate(key)
click.echo(f"Cleared {count} cache entries.")cache_status function · python · L1405-L1422 (18 LOC)lib/vibe/cli/main.py
def cache_status() -> None:
"""Show cache status."""
from lib.vibe.utils.cache import get_cache
c = get_cache()
entries = c.status()
if not entries:
click.echo("Cache is empty.")
return
click.echo(f"\nCached entries ({len(entries)}):")
for entry in entries:
if "error" in entry:
click.echo(f" {entry['key']}: {entry['error']}")
else:
age = entry["age_seconds"]
remaining = entry["remaining_seconds"]
status = "expired" if entry["expired"] else f"{remaining}s remaining"
click.echo(f" {entry['key']}: cached {age}s ago ({status})")list_secrets function · python · L26-L65 (40 LOC)lib/vibe/cli/secrets.py
def list_secrets(provider: str | None) -> None:
"""List secrets from configured providers."""
config = load_config()
providers = config.get("secrets", {}).get("providers", [])
if not providers:
click.echo("No secret providers configured.")
return
if provider:
if provider not in providers:
click.echo(f"Provider '{provider}' not configured.")
sys.exit(1)
providers = [provider]
for prov in providers:
click.echo(f"\n{prov.upper()} Secrets:")
click.echo("-" * 40)
if prov == "github":
from lib.vibe.secrets.providers.github import GitHubSecretsProvider
github_config = config.get("github", {})
gh = GitHubSecretsProvider(
owner=github_config.get("owner"),
repo=github_config.get("repo"),
)
if not gh.authenticate():
click.echo(" Not authenticated. Run 'gh auth login'.")
allowlist_list function · python · L75-L91 (17 LOC)lib/vibe/cli/secrets.py
def allowlist_list() -> None:
"""List allowlist entries."""
entries = load_allowlist()
if not entries:
click.echo("No allowlist entries.")
return
click.echo("\nSecrets Allowlist:")
click.echo("-" * 60)
for i, entry in enumerate(entries, 1):
click.echo(f"\n{i}. Pattern: {entry.pattern}")
click.echo(f" Reason: {entry.reason}")
click.echo(f" Added by: {entry.added_by}")
if entry.file_path:
click.echo(f" File: {entry.file_path}")allowlist_add function · python · L99-L107 (9 LOC)lib/vibe/cli/secrets.py
def allowlist_add(pattern: str, reason: str, added_by: str, file: str | None) -> None:
"""Add an entry to the allowlist."""
entry = add_to_allowlist(
pattern=pattern,
reason=reason,
added_by=added_by,
file_path=file,
)
click.echo(f"Added allowlist entry for pattern: {entry.pattern}")sync function · python · L116-L213 (98 LOC)lib/vibe/cli/secrets.py
def sync(
env_file: str,
provider: str | None,
environment: str,
dry_run: bool,
interactive: bool,
) -> None:
"""Sync secrets from local env file to a provider."""
from pathlib import Path
env_path = Path(env_file)
if not env_path.exists():
click.echo(f"File not found: {env_file}", err=True)
sys.exit(1)
# Interactive provider selection
if not provider:
if interactive:
available = ["github", "vercel", "fly"]
click.echo("Available providers:")
for i, p in enumerate(available, 1):
click.echo(f" {i}. {p}")
choice = click.prompt("Select provider", type=int)
if 1 <= choice <= len(available):
provider = available[choice - 1]
else:
click.echo("Invalid selection.", err=True)
sys.exit(1)
else:
click.echo(
"Error: --provider is required. Use --interactive foget_tracker function · python · L29-L44 (16 LOC)lib/vibe/cli/ticket.py
def get_tracker():
"""Get the configured tracker instance (config file or LINEAR_* env for CI)."""
config = load_config()
tracker_type = config.get("tracker", {}).get("type")
tracker_config = config.get("tracker", {}).get("config", {})
if tracker_type == "linear":
return LinearTracker(team_id=tracker_config.get("team_id"))
if tracker_type == "shortcut":
return ShortcutTracker()
# CI: allow Linear via env when no tracker is configured (e.g. HUMAN follow-up workflow)
if os.environ.get("LINEAR_API_KEY"):
return LinearTracker(
team_id=tracker_config.get("team_id") or os.environ.get("LINEAR_TEAM_ID")
)
return NoneOpen data scored by Repobility · https://repobility.com
ensure_tracker_configured function · python · L47-L79 (33 LOC)lib/vibe/cli/ticket.py
def ensure_tracker_configured():
"""
Return the configured tracker, or prompt to run the tracker setup wizard.
Exits with a message if the user declines or setup does not configure a tracker.
"""
tracker = get_tracker()
if tracker is not None:
return tracker
click.echo(
"No ticketing system (e.g. Linear) is configured. Set up a tracker before creating or viewing tickets."
)
if not click.confirm("Run tracker setup now?", default=True):
click.echo(
"Run 'bin/vibe setup' or 'bin/vibe setup --wizard tracker' when ready.", err=True
)
sys.exit(1)
config = load_config()
if not run_tracker_wizard(config):
click.echo(
"Tracker setup was cancelled or failed. Run 'bin/vibe setup' to try again.", err=True
)
sys.exit(1)
save_config(config)
tracker = get_tracker()
if tracker is None:
click.echo(
"No tracker was selected. Run 'bin/vibe get function · python · L91-L109 (19 LOC)lib/vibe/cli/ticket.py
def get(ticket_id: str, children: bool) -> None:
"""Get details for a specific ticket."""
tracker = ensure_tracker_configured()
try:
# Use include_children if supported
with Spinner(f"Fetching ticket {ticket_id}"):
if hasattr(tracker, "get_ticket") and children:
ticket = tracker.get_ticket(ticket_id, include_children=True)
else:
ticket = tracker.get_ticket(ticket_id)
if ticket:
print_ticket(ticket, show_children=children)
else:
click.echo(f"Ticket not found: {ticket_id}")
sys.exit(1)
except NotImplementedError as e:
click.echo(str(e), err=True)
sys.exit(1)list_tickets function · python · L126-L194 (69 LOC)lib/vibe/cli/ticket.py
def list_tickets(
status: str | None,
label: tuple,
limit: int,
fetch_all: bool,
project: str | None,
parent: str | None,
priority: str | None,
assignee: str | None,
unassigned: bool,
) -> None:
"""List tickets from the tracker.
Examples:
bin/ticket list --status "In Progress"
bin/ticket list --project "Q1 Roadmap"
bin/ticket list --parent PROJ-100 # Show sub-tasks
bin/ticket list --priority urgent
bin/ticket list --assignee me
bin/ticket list --unassigned
bin/ticket list --all # Fetch all matching tickets
"""
tracker = ensure_tracker_configured()
effective_limit = 10000 if fetch_all else limit
try:
# Build kwargs for trackers that support extended filters
kwargs: dict = {
"status": status,
"labels": list(label) if label else None,
"limit": effective_limit,
}
# Add extended filters if supported
page 1 / 8next ›