# Build Command

The `build` command extracts the Technical Execution section from your growth plan, uses an LLM to generate a focused implementation prompt, and lets you send that prompt to Cursor, Claude, or view it in the terminal.

## Prerequisites

Before running `build`, you need:

- A `growth-plan.md` file generated by the `plan` command. See [Plan](plan.md) for details.
- An API key configured for a cloud LLM provider (OpenAI, Gemini, Anthropic), or a local LLM server running (Ollama). The LLM is used to generate the implementation prompt and a growth loop definition. See [configuration](configuration.md) for setup instructions.

## Basic usage

Build a prompt using auto-detected plan and configured LLM settings:

```bash
uvx skene-growth build
```

The command looks for `growth-plan.md` in `./skene-context/` first, then falls back to the current directory.

Override LLM settings:

```bash
uvx skene-growth build --api-key "your-key" --provider gemini
```

Specify a custom plan file:

```bash
uvx skene-growth build --plan ./my-plan.md
```

Point to a context directory:

```bash
uvx skene-growth build --context ./my-context
```

## Flag reference

| Flag | Short | Description |
|------|-------|-------------|
| `--plan PATH` | | Path to growth plan markdown file |
| `--context PATH` | `-c` | Directory containing `growth-plan.md`. Auto-detected from `./skene-context/` if not specified. |
| `--api-key TEXT` | | API key for LLM provider (or `SKENE_API_KEY` env var) |
| `--provider TEXT` | `-p` | LLM provider: `openai`, `gemini`, `anthropic`/`claude`, `lmstudio`, `ollama`, `generic` |
| `--model TEXT` | `-m` | Model name (uses provider default if not provided) |
| `--base-url TEXT` | | Base URL for OpenAI-compatible API endpoint. Required when provider is `generic`. Also set via `SKENE_BASE_URL` env var or config. |
| `--debug` | | Log all LLM input/output to `.skene-growth/debug/` |
| `--no-fallback` | | Disable model fallback on rate limits. Retries the same model with exponential backoff instead of switching to a cheaper model. |
| `--target TEXT` | `-t` | Skip the interactive menu and send the prompt directly. Options: `cursor`, `claude`, `show`, `file`. |

## How it works

The build command follows a five-step pipeline:

### Step 1: Locate the growth plan

The command auto-detects the plan file in this order:

1. If `--context` is specified, looks for `growth-plan.md` inside that directory
2. Checks `./skene-context/growth-plan.md`
3. Checks `./growth-plan.md`

You can override this with `--plan` to specify an exact path.

### Step 2: Extract the Technical Execution section

The command parses the growth plan Markdown and extracts the **Technical Execution** section. This section is generated by the `plan` command's Council of Growth Engineers and contains:

- **The Next Build** -- What specific activation loop or feature to build
- **Confidence Score** -- A 0%-100% rating of the hypothesis
- **Exact Logic** -- The specific flow changes or implementation logic
- **Exact Data Triggers** -- Events that signal successful activation
- **Sequence** -- The Now / Next / Later roadmap

If the Technical Execution section cannot be found, the command exits with an error and prompts you to generate a proper plan first.

### Step 3: Generate an intelligent prompt with LLM

The extracted Technical Execution context is sent to your configured LLM with a meta-prompt. The LLM generates a focused, actionable implementation prompt that:

- States the engineering work based on the Technical Execution context
- Includes all relevant technical details (logic, triggers, sequence)
- References the growth plan file for additional context
- Asks for step-by-step implementation with code examples

If the LLM call fails, the command falls back to a static template that wraps the Technical Execution content in a basic prompt structure.

### Step 4: Choose a destination

After generating the prompt, the command presents an interactive menu:

```
Where do you want to send this prompt?
> Cursor (open via deep link)
  Claude (open in terminal)
  Show full prompt
  Cancel
```

Use arrow keys to navigate and Enter to select. If the `questionary` package is not installed, the command falls back to a numbered menu.

If `--target` is provided, this step is skipped entirely and the command proceeds directly to the specified destination.

### Step 5: Generate a growth loop definition

Regardless of which destination you choose, the command also generates a **growth loop definition** -- a structured JSON file that captures the implementation requirements. This runs in parallel with the destination action.

## Destinations

### Cursor

Selecting **Cursor** opens the Cursor editor via a deep link (`cursor://`). The prompt is saved to a file first (`.skene-build-prompt.md` in the plan's directory), then Cursor is launched with the full prompt content and a reference to the saved file.

This works on macOS, Linux, and Windows. Cursor must be installed on the system.

### Claude

Selecting **Claude** launches the Claude CLI (`claude`) in your current terminal session, passing it a reference to the saved prompt file. This requires the [Claude CLI](https://docs.anthropic.com/claude-code) to be installed.

### Show

Selecting **Show** prints the full prompt to the terminal inside a formatted panel. The prompt is also saved to a file so you can copy and use it with any tool.

### File

Selecting **File** (only available via `--target file`) saves the prompt to a file and exits immediately without opening any editor or printing the full prompt. This is the recommended target for scripting and CI/CD pipelines.

In all cases, the prompt is saved to `.skene-build-prompt.md` in the plan's parent directory (or the configured output directory).

## Growth loop definitions

Every successful `build` run produces a growth loop JSON file saved to `./skene-context/growth-loops/`. The filename follows the pattern `<loop_id>_<YYYYMMDD_HHMMSS>.json`.

The loop ID is derived from the "Next Build" field in the Technical Execution section, converted to snake_case with phase prefixes removed (e.g., "Phase 1: Share Flag" becomes `share_flag`).

### Schema

The growth loop JSON conforms to the `GROWTH_LOOP_VERIFICATION_SPEC` schema:

```json
{
  "loop_id": "share_flag",
  "name": "Share Flag",
  "description": "Detailed description of the growth loop",
  "requirements": {
    "files": [
      {
        "path": "src/components/ShareButton.tsx",
        "purpose": "Share button component for the main dashboard",
        "required": true,
        "checks": [
          {
            "type": "function_exists",
            "pattern": "handleShare",
            "description": "Share handler function must exist"
          }
        ]
      }
    ],
    "functions": [
      {
        "file": "src/components/ShareButton.tsx",
        "name": "handleShare",
        "required": true,
        "signature": "handleShare(url: string) -> void",
        "logic": "Takes a URL string, generates a shareable link with tracking parameters, copies it to clipboard, and triggers a share_initiated telemetry event."
      }
    ],
    "integrations": [
      {
        "type": "ui_component",
        "description": "Share button in dashboard header",
        "verification": "Component renders in dashboard layout"
      }
    ],
    "telemetry": [
      {
        "event_name": "share_initiated",
        "description": "User clicked the share button",
        "trigger_location": "src/components/ShareButton.tsx",
        "trigger_condition": "After user clicks share and link is copied",
        "properties": ["share_type", "source_page", "user_id"]
      }
    ]
  },
  "dependencies": [],
  "verification_commands": ["npm test -- --grep ShareButton"],
  "test_coverage": {
    "unit_tests": ["ShareButton renders correctly", "handleShare generates valid URL"],
    "integration_tests": ["Share flow completes end-to-end"],
    "manual_tests": ["Click share button and verify link is copied"]
  },
  "metrics": {
    "telemetry_events": ["share_initiated", "share_completed"],
    "success_criteria": ["Share rate > 5% of active users"]
  },
  "_metadata": {
    "source_plan_path": "/absolute/path/to/growth-plan.md",
    "saved_at": "2025-01-15T10:30:00",
    "target": "cursor",
    "prompt": "The full generated prompt text..."
  }
}
```

Key sections of the schema:

| Section | Description |
|---------|-------------|
| `requirements.files` | Files to create or modify, with verification checks (type, pattern, description) |
| `requirements.functions` | Functions to implement, including signature and logic description |
| `requirements.integrations` | Integration points (CLI flags, API endpoints, UI components, external services) |
| `requirements.telemetry` | Events to track, with trigger locations and conditions |
| `dependencies` | Other loop IDs this loop depends on |
| `verification_commands` | Commands to verify the implementation |
| `test_coverage` | Unit, integration, and manual test descriptions |
| `metrics` | Telemetry events and success criteria (KPIs) |
| `_metadata` | Build metadata: source plan path, timestamp, chosen destination, generated prompt |

Growth loop files accumulate over time. The `plan` command reads existing loops and instructs the council not to suggest duplicates, keeping successive iterations complementary.

## LLM configuration

The build command requires LLM configuration. It loads settings from your config file (`.skene-growth.config` or `~/.config/skene-growth/config`) and can be overridden with CLI flags.

If neither an API key nor a provider is configured, the command exits with an error listing all configuration options.

The LLM is used twice during a build:

1. To generate the implementation prompt from the Technical Execution context
2. To generate the growth loop definition JSON

If the LLM fails during prompt generation, the command falls back to a static template. If the LLM fails during growth loop generation, the command produces a minimal loop definition with empty arrays.

## Debug mode

The `--debug` flag logs all LLM input and output to `.skene-growth/debug/`:

```bash
uvx skene-growth build --debug
```

You can also enable debug mode permanently in your config file:

```toml
debug = true
```

## Next steps

- [Status](status.md) -- Check whether growth loop requirements have been implemented in your codebase
- [Chat](chat.md) -- Use the interactive terminal chat for ad-hoc growth analysis
- [Configuration](configuration.md) -- Set up persistent config so you do not need to pass flags every time
- [CLI Reference](../reference/cli.md) -- Full reference for all commands and flags
