Skip to content

init_cmd

init_cmd

Project initialization command for Marianne CLI.

Implements mzt init — scaffolds a new Marianne project with a starter score and .marianne/ directory. This is the first-run experience for new users.

The generated score is a practical template with comments explaining every field. Users edit it with their task, then run it.

Functions

init

init(score_name=Argument(None, help="Score name (e.g. 'my-project'). Same as --name."), path=Option('.', '--path', '-p', help='Directory to initialize (default: current directory)'), name=Option('my-score', '--name', '-n', help='Name for the starter score'), force=Option(False, '--force', '-f', help='Overwrite existing files'), json_output=Option(False, '--json', '-j', help='Output result as JSON'))

Scaffold a new Marianne project with a starter score.

Creates a starter score YAML and .marianne/ project directory. Edit the score with your task, then run it with the conductor.

Examples:

mzt init mzt init my-project mzt init --path ./my-project mzt init --name data-pipeline mzt init --force mzt init --json

Source code in src/marianne/cli/commands/init_cmd.py
def init(
    score_name: str | None = typer.Argument(
        None,
        help="Score name (e.g. 'my-project'). Same as --name.",
    ),
    path: Path = typer.Option(
        ".",
        "--path",
        "-p",
        help="Directory to initialize (default: current directory)",
    ),
    name: str = typer.Option(
        "my-score",
        "--name",
        "-n",
        help="Name for the starter score",
    ),
    force: bool = typer.Option(
        False,
        "--force",
        "-f",
        help="Overwrite existing files",
    ),
    json_output: bool = typer.Option(
        False,
        "--json",
        "-j",
        help="Output result as JSON",
    ),
) -> None:
    """Scaffold a new Marianne project with a starter score.

    Creates a starter score YAML and .marianne/ project directory.
    Edit the score with your task, then run it with the conductor.

    Examples:
        mzt init
        mzt init my-project
        mzt init --path ./my-project
        mzt init --name data-pipeline
        mzt init --force
        mzt init --json
    """
    # Resolve name: positional arg is convenience shorthand for --name.
    # --name flag takes precedence when both are provided (flag is explicit).
    if score_name is not None and name == "my-score":
        name = score_name

    # Validate name before touching the filesystem
    name_error = _validate_name(name)
    if name_error:
        output_error(
            name_error,
            hints=["Use a simple name like 'my-score' or 'data-pipeline'."],
            json_output=json_output,
        )
        raise typer.Exit(1)

    target = path.resolve()
    score_file = target / f"{name}.yaml"
    marianne_dir = target / ".marianne"

    # Safety: refuse to overwrite without --force
    if not force:
        if score_file.exists():
            output_error(
                f"Score already exists: {score_file}",
                severity="warning",
                hints=["Use --force to overwrite."],
                json_output=json_output,
            )
            raise typer.Exit(1)
        if marianne_dir.exists():
            output_error(
                f"Marianne project already initialized: {marianne_dir}",
                severity="warning",
                hints=["Use --force to reinitialize."],
                json_output=json_output,
            )
            raise typer.Exit(1)

    # Create .marianne/ directory
    marianne_dir.mkdir(parents=True, exist_ok=True)

    # Create workspaces/ directory so `mzt validate` passes immediately
    workspaces_dir = target / "workspaces"
    workspaces_dir.mkdir(parents=True, exist_ok=True)

    # Generate and write starter score
    score_content = _generate_starter_score(name)
    score_file.write_text(score_content)

    _logger.info("init.complete", extra={"target_path": str(target), "score_name": name})

    # Output
    if json_output:
        output_json({
            "success": True,
            "name": name,
            "score_file": str(score_file),
            "target_path": str(target),
        })
    else:
        console.print(
            f"\n[bold green]Marianne project initialized[/bold green] in {target}\n"
        )
        console.print(
            f"  Created: [bold]{name}.yaml[/bold]"
            "        (starter score — edit with your task)"
        )
        console.print(
            "  Created: [bold].marianne/[/bold]"
            "              (project config directory)"
        )
        console.print()
        console.print("[dim]Next steps:[/dim]")
        console.print("  0. [bold]mzt doctor[/bold]              (check your environment)")
        console.print(f"  1. Edit [bold]{name}.yaml[/bold] with your task")
        console.print(
            f"  2. [bold]mzt start[/bold] && "
            f"[bold]mzt run {name}.yaml[/bold]"
        )
        console.print(f"  3. [bold]mzt status {name}[/bold] to watch progress")
        console.print()