BharatCode

Usage

Recipes

A recipe is a repeatable task captured as a parameterized prompt: a small JSON file with a title, a description, typed parameters, and a prompt template. Drop one in your project and the task — “add tests for this package”, “review this diff” — becomes a one-line slash command anyone on the team can run. Recipes are declarative, shareable, and version-controlled alongside your code.

What a recipe is

A recipe is a single *.recipe.json file. Its core is a prompt template that references parameters with {{name}} placeholders; when you run the recipe, BharatCode substitutes your values and seeds an agent turn with the result. Substitution is a plain, safe string-replacement pass — there is no arbitrary code execution in a recipe.

add-tests.recipe.jsonjsonc
{  "title": "Add tests for a package",  "description": "Write table-driven Go tests for a named package.",  "prompt": "Write table-driven tests for the package {{package}}. Read the existing tests in that package first and mirror their style. Focus on {{focus}}. Run `go test ./{{package}}/` and iterate until green.",  "parameters": [    {      "name": "package",      "type": "string",      "requirement": "required",      "description": "Workspace-relative package path, e.g. internal/recipe"    },    {      "name": "focus",      "type": "string",      "requirement": "optional",      "default": "the package's public functions and their error paths",      "description": "What the tests should focus on"    }  ],  "extensions": ["bash", "view", "edit", "grep"]}

The fields are:

  • title — a short, human-readable name (required).
  • description — a one-line summary shown in listings.
  • prompt — the template text, with {{name}} placeholders (required).
  • parameters — the typed slots available for substitution (see below).
  • instructions — an optional free-form preamble prepended to the rendered prompt.
  • extensions — an advisory list of tools the agent should have enabled while running the recipe.

Typed parameters

Each parameter declares a name, a type, and a requirement. The four types are:

  • string — any text value.
  • number — a value that represents a number (passed through as a string).
  • bool — must be true or false (case-insensitive).
  • select — one of the values listed in options (which must be non-empty).

The requirement controls how a value must be supplied:

  • required — you must supply a non-empty value (a non-empty default satisfies it).
  • optional — may be omitted; the default is used when no value is given.
  • user_prompt — the TUI interactively asks you for the value before running. (To the renderer it behaves like required.)

Validation happens before the agent runs

Rendering rejects a missing required value with no default, a bool that is not true/false, a select value outside its options, and any leftover {{}} placeholder that has no matching parameter. A malformed or invalid recipe is skipped at discovery with a warning rather than breaking the session.

Where recipes live

BharatCode discovers recipes from two directories, in precedence order:

  1. Global — the recipes/ directory next to your global config file (e.g. ~/.config/bharatcode/recipes/).
  2. Project .bharatcode/recipes/ in your project. When run without --project-dir, the current working directory is used, so project recipes are found from a repo root automatically.

A recipe's name is its filename stem — the file minus the .recipe.json extension. A project recipe shadows a global one with the same name, so a repo can override a team-wide default. Commit your .bharatcode/recipes/ directory and the whole team gets the same task templates.

Listing recipes

bharatcode recipes discovers every recipe in those directories and prints each one's name, title, and description as a table. When none are found, it reports the directories it searched so you know where to add one.

terminalbash
bharatcode recipes

Running a recipe

Inside the TUI, every discovered recipe is exposed as a slash command named after its file stem. Run the add-tests recipe with /add-tests. A recipe with a single parameter binds a bare argument directly, so the common case is one line:

in the TUItext
/add-tests internal/recipe

For recipes with user_prompt parameters, BharatCode collects each value interactively before rendering the final prompt and starting the run. The rendered prompt seeds the agent turn exactly as if you had typed it yourself.

Recipes vs. AGENTS.md vs. profiles

AGENTS.md sets standing context for every turn; profiles switch models and settings. A recipe is narrower and more reusable than either: a single, parameterized task you invoke on demand. Reach for a recipe whenever you find yourself typing the same shaped prompt with small variations.