diff --git a/src/pipecat/cli/__init__.py b/src/pipecat/cli/__init__.py index e1206106a50..44d113fdfee 100644 --- a/src/pipecat/cli/__init__.py +++ b/src/pipecat/cli/__init__.py @@ -7,8 +7,10 @@ """Pipecat CLI - command-line tools for building Pipecat AI voice agents. This package provides command-line tools for: -- Scaffolding new Pipecat projects with `pipecat create` -- Making a project agent-ready (AGENTS.md + CLAUDE.md) with `pipecat init` +- Initializing a new Pipecat project with `pipecat init` (the entry point: writes the + coding-agent guide, then helps you build with a coding agent or scaffold a bot) +- Scaffolding a project with `pipecat create` +- Running behavioral evals against a bot with `pipecat eval` And allows installing extensions like Pipecat Cloud: - Deploying to Pipecat Cloud with `pipecat cloud` diff --git a/src/pipecat/cli/agent_templates/GETTING_STARTED.md b/src/pipecat/cli/agent_templates/GETTING_STARTED.md index f05456ea12f..305448963ff 100644 --- a/src/pipecat/cli/agent_templates/GETTING_STARTED.md +++ b/src/pipecat/cli/agent_templates/GETTING_STARTED.md @@ -1,10 +1,8 @@ # Getting Started — Building Pipecat Bots with a Coding Agent **This file is for you**: how to drive your coding agent well. The other -files here are for the **agent**: AGENTS.md teaches it how to build Pipecat -apps — scaffold with `pipecat create`, check APIs against live sources -instead of stale training data, verify its own work with headless evals — -and CLAUDE.md loads it into Claude Code. +files here (`AGENTS.md`, `CLAUDE.md`) are the agent's guide; it picks them +up automatically, so you don't need to read them. ## First: set up the Pipecat Context Hub diff --git a/src/pipecat/cli/commands/create.py b/src/pipecat/cli/commands/create.py index a9293a88b67..b4a58d4235a 100644 --- a/src/pipecat/cli/commands/create.py +++ b/src/pipecat/cli/commands/create.py @@ -169,7 +169,7 @@ def create_command( # command and routing the `quickstart` token preserves `pc create quickstart [-o ...]`. # # NOTE: this is the `pipecat create` scaffolder (formerly `pipecat init`). `pipecat init` - # is now a separate command that makes a project agent-ready (see commands/init.py). + # is now a separate command that initializes a new Pipecat project (see commands/init.py). if target == "quickstart": return quickstart_command(output_dir=output_dir) @@ -321,7 +321,7 @@ def scaffold_quickstart( Sets up a project with SmallWebRTC, Daily, Deepgram STT, OpenAI LLM, and Cartesia TTS — the fastest way to get a voice agent running. Shared by ``pipecat create quickstart`` (creates a ``pipecat-quickstart`` subfolder) and ``pipecat init - quickstart`` (scaffolds in-place into an already agent-ready directory, via + quickstart`` (scaffolds in-place into an already-initialized directory, via ``dest`` / ``in_place``). """ project_name = "pipecat-quickstart" diff --git a/src/pipecat/cli/commands/init.py b/src/pipecat/cli/commands/init.py index 7c5a517b73a..5dcaf3a7cc5 100644 --- a/src/pipecat/cli/commands/init.py +++ b/src/pipecat/cli/commands/init.py @@ -6,7 +6,7 @@ """``pipecat init`` — the single starting point for building a Pipecat app. -``pipecat init`` makes a project agent-ready, then routes you to a build method: +``pipecat init`` initializes a new Pipecat project, then routes you to a build method: - ``AGENTS.md`` — the coding-agent guide (read natively by most coding agents). - ``CLAUDE.md`` — a one-line ``@AGENTS.md`` import so Claude Code loads it too. @@ -21,7 +21,7 @@ hand off to a coding agent (which later scaffolds with ``pipecat create``), or scaffold a runnable bot right now (it runs the ``pipecat create`` wizard in-place in the same directory). ``pipecat init quickstart`` skips the question and scaffolds the canned -quickstart bot in-place — agent-ready *and* runnable in one step. +quickstart bot in-place — the coding-agent guide *and* a runnable bot in one step. ``pipecat create`` remains the scaffolder itself: coding agents and automation call it directly (non-interactively); ``init`` is the human entry point that wraps it. @@ -71,7 +71,7 @@ def _guide_footer() -> str: def _write_agent_guide(target_dir: Path, force: bool) -> None: """Write the core agent guide — AGENTS.md and CLAUDE.md — into a directory. - These make the project agent-ready and are wanted on *every* path (coding agent, + These set up the project for coding agents and are wanted on *every* path (coding agent, scaffold-now, quickstart), so they're written upfront. ``AGENTS.md`` is pipecat-owned and always (re)written, so re-running refreshes it after a Pipecat upgrade; ``CLAUDE.md`` is the developer's own entry point and is only overwritten with ``force``. @@ -142,7 +142,7 @@ def _is_interactive() -> bool: return sys.stdin.isatty() and sys.stdout.isatty() -def _print_agent_ready(target_dir: Path) -> None: +def _print_ready(target_dir: Path) -> None: """Print the guidance shown when the developer keeps the coding-agent path. Names the project directory so the developer knows where to open their session, @@ -152,7 +152,7 @@ def _print_agent_ready(target_dir: Path) -> None: """ where = "here" if target_dir.resolve() == Path.cwd() else f"in [bold]{target_dir}[/bold]" console.print( - f"\n[bold]Project is agent-ready.[/bold]\n\n" + f"\n[bold]Your project is ready.[/bold]\n\n" f"Read [bold]{_GETTING_STARTED_FILE}[/bold] for how to prompt your agent, then open a " f"coding session {where} to start building." ) @@ -170,7 +170,7 @@ def _route_build_method(target_dir: Path) -> None: already_scaffolded = (target_dir / "server").exists() if already_scaffolded or not _is_interactive(): _write_developer_guide(target_dir) - _print_agent_ready(target_dir) + _print_ready(target_dir) return import questionary @@ -189,7 +189,7 @@ def _route_build_method(target_dir: Path) -> None: # `ask()` returns None on Ctrl-C / EOF — fall through to the safe agent path. if choice != "scaffold": _write_developer_guide(target_dir) - _print_agent_ready(target_dir) + _print_ready(target_dir) return # Scaffold now: run the `create` wizard in-place. The scaffold lands in the same @@ -213,11 +213,11 @@ def _route_build_method(target_dir: Path) -> None: def _init_quickstart(force: bool) -> None: - """``pipecat init quickstart``: the canned quickstart, made agent-ready. + """``pipecat init quickstart``: the canned quickstart, with the coding-agent guide. Writes the agent guide into ``pipecat-quickstart/`` and scaffolds the quickstart - bot in-place there, so the learner's first project is both runnable and - agent-ready. The human counterpart to ``pipecat create quickstart`` (which omits + bot in-place there, so the learner's first project is both runnable and set up for + coding agents. The human counterpart to ``pipecat create quickstart`` (which omits the guide). Non-interactive — it's a fixed preset, so there's no build-method question. @@ -245,8 +245,7 @@ def init_command( ctx: typer.Context, target: str | None = typer.Argument( None, - help="Directory to make agent-ready (or 'quickstart' for the canned bot). " - "Created if missing.", + help="Directory to initialize (or 'quickstart' for the canned bot). Created if missing.", ), force: bool = typer.Option( False, @@ -254,7 +253,7 @@ def init_command( help=f"Also overwrite an existing {_CLAUDE_FILE} ({_AGENTS_FILE} is always refreshed).", ), ): - """Make a project agent-ready, then choose how to build. + """Initialize a new Pipecat project, then choose how to build. Writes AGENTS.md + CLAUDE.md + GETTING_STARTED.md, then (interactively) hands you off to a coding agent or scaffolds a runnable bot in-place with ``pipecat create``. @@ -263,11 +262,11 @@ def init_command( pipecat init # prompt for a directory, then choose how to build pipecat init my-bot # set up ./my-bot - pipecat init quickstart # agent-ready canned quickstart bot in ./pipecat-quickstart + pipecat init quickstart # canned quickstart bot in ./pipecat-quickstart pipecat init my-bot --force # overwrite existing files in ./my-bot pipecat init . # set up the current directory """ - # `pipecat init quickstart`: scaffold the canned bot in-place, made agent-ready. + # `pipecat init quickstart`: scaffold the canned bot in-place, with the coding-agent guide. if target == "quickstart": return _init_quickstart(force) @@ -278,7 +277,7 @@ def init_command( unexpected = " ".join(ctx.args) console.print( f"[red]Unexpected arguments:[/red] {unexpected}\n\n" - "`pipecat init` makes a project agent-ready (writes AGENTS.md, CLAUDE.md, " + "`pipecat init` initializes a new Pipecat project (writes AGENTS.md, CLAUDE.md, " "and GETTING_STARTED.md); it takes only an optional target directory and `--force`.\n" "To scaffold non-interactively, use [bold]`pipecat create`[/bold] — run " "`pipecat create --help`." diff --git a/src/pipecat/cli/main.py b/src/pipecat/cli/main.py index e05b5e6975f..5723c3ccd3f 100644 --- a/src/pipecat/cli/main.py +++ b/src/pipecat/cli/main.py @@ -75,12 +75,12 @@ def _build_app(): # positional target path followed by options (e.g. `pc create . --bot-type web`). app.command("create", help="Create a new Pipecat project")(create_command) - # `init` makes a project agent-ready (writes AGENTS.md + CLAUDE.md). ignore_unknown_options + # `init` initializes a new Pipecat project (writes AGENTS.md + CLAUDE.md). ignore_unknown_options # lets it catch legacy scaffolder flags (now `pipecat create`) and redirect with a clear # message instead of an opaque "no such option" error. app.command( "init", - help="Make a project agent-ready (writes AGENTS.md + CLAUDE.md)", + help="Initialize a new Pipecat project (writes AGENTS.md + CLAUDE.md)", context_settings={"ignore_unknown_options": True, "allow_extra_args": True}, )(init_command) diff --git a/tests/cli/test_init_agent_ready.py b/tests/cli/test_init_agent_ready.py index 023a9a579e3..7dd787a32c5 100644 --- a/tests/cli/test_init_agent_ready.py +++ b/tests/cli/test_init_agent_ready.py @@ -4,7 +4,7 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Tests for `pipecat init` — making a project agent-ready (AGENTS.md + CLAUDE.md).""" +"""Tests for `pipecat init` — initializing a project (AGENTS.md + CLAUDE.md).""" from pathlib import Path @@ -109,14 +109,14 @@ def test_legacy_scaffolder_flags_redirect(self, tmp_path): # Redirect must not write a half-initialized project. assert not (tmp_path / "AGENTS.md").exists() - def test_quickstart_scaffolds_and_makes_agent_ready(self, tmp_path, monkeypatch): + def test_quickstart_scaffolds_and_writes_guide(self, tmp_path, monkeypatch): # `init quickstart` is the human front door for the canned bot: it scaffolds the # quickstart in-place AND drops the agent guide, all in ./pipecat-quickstart. monkeypatch.chdir(tmp_path) result = runner.invoke(app, ["init", "quickstart"]) assert result.exit_code == 0, result.output project = tmp_path / "pipecat-quickstart" - # Agent-ready files... + # Coding-agent guide files... assert (project / "AGENTS.md").exists() assert (project / "CLAUDE.md").read_text(encoding="utf-8").strip() == "@AGENTS.md" # ...plus a runnable bot in the same directory. @@ -173,7 +173,7 @@ def test_scaffold_branch_runs_create_in_place(self, tmp_path, monkeypatch, _sele # Scaffolding now ends in a built bot, so the from-scratch developer guide is # skipped — its place is taken by the scaffold's README (see test_quickstart_*). assert not (tmp_path / "GETTING_STARTED.md").exists() - # ...but the core agent-ready files are still written. + # ...but the core coding-agent guide files are still written. assert (tmp_path / "AGENTS.md").exists() assert (tmp_path / "CLAUDE.md").exists() @@ -186,7 +186,7 @@ def test_agent_branch_does_not_scaffold(self, tmp_path, monkeypatch, _select): ) result = runner.invoke(app, ["init", str(tmp_path)]) assert result.exit_code == 0, result.output - assert "agent-ready" in result.output.lower() + assert "your project is ready" in result.output.lower() assert not (tmp_path / "server").exists() # The coding-agent path gets the developer guide. assert (tmp_path / "GETTING_STARTED.md").exists()