Open source MIT

The easiest way to build a software factory that reflects your tastes.

Your coding agent reads the chats that you select. It finds the steps that you repeat and the decisions that you make. Then it writes them as a workflow in simple TypeScript. Cloving runs that workflow on your computer.

npm install --global cloving --ignore-scripts
Read the code on GitHub

The setup prompt tells Claude Code or Codex to install Cloving, connect your tickets and make a first run with you. Read the prompt first.

Workers
Claude Code, Codex
Control
Hands on to hands off
Records
On your Mac
License
MIT
Your chatsExample
  1. 1

    YouDo this ticket in a new branch.

  2. 2

    YouStop and show me the diff. I want to review it first.

  3. 3

    YouI do not approve this. Stop here.

your agent writes
workflows/develop-ticket.ts
export async function developTicket(input, decision) { "use workflow"; 3 if (decision !== undefined) return { kind: "blocked", reason: "The operator denied the work." }; 1 const turn = await protectedEffect({ capability: "claude", method: "run-turn", payload: input.ticket, }); 2 const gate = await decisionGate({ kind: "approval", prompt: "Review the work of the Claude worker.", }); … }
Lines from the minimal workflow in the Cloving README, shortened. Your agent reads only the chats that you select.
How it works

From your chats to your factory

Two prompts and one command. Your coding agent does the work, and you make the decisions.

  1. Step 1

    Install Cloving.

    Install the cloving command from npm. Or paste the setup prompt into Claude Code or Codex. Your agent installs Cloving, connects your tickets and makes a first run with a small task that you agree to.

    $ npm install --global cloving \
        --ignore-scripts
    $ cloving --version
    Read the setup prompt
  2. Step 2

    Tell your agent to start developing ticket XYZ with Cloving.

    Use your own words. Your agent runs the develop-ticket workflow for that ticket. When the run needs a decision, your agent shows you the diff, and you approve or deny.

    • YouStart developing ticket XYZ with Cloving.

    $ cloving run develop-ticket \
        --ticket XYZ

    Your agent can also write the ticket. The develop-prd workflow researches your code and the web, reviews a draft and posts it as a GitHub issue. Add the cloving: ready label when the issue is ready.

    • YouCreate a ticket that adds dark mode.

    $ cloving run develop-prd \
        --prompt "Add dark mode"

    The watch page also gives a prompt to copy for each workflow.

  3. Step 3

    Cloving runs your factory.

    Start the service in your repository. The watch page shows each run, each step and each decision as it occurs.

    $ cloving start
    $ cloving run develop-prompt \
        --prompt "Add a file HELLO.md with one line of text."
    $ cloving questions

    Watch page: http://127.0.0.1:3663/

Workflow SDK

A workflow is a TypeScript file

You do not learn a configuration language. A workflow is one async function. Your agent writes it, and you read it, test it and change it like other code.

From the README section "Develop a workflow". One Claude turn, then your approval.

import type { CycleOutcome } from "cloving/workflows";
import { decisionGate } from "cloving/workflows/steps/decision-gate";
import { protectedEffect } from "cloving/workflows/steps/protected-effect";

export async function developTicket(
  input: { readonly cycleId: string; readonly ticket: string },
  decision?: {
    readonly gateId: string;
    readonly decision: string;
    readonly answer: string | null;
  },
): Promise<CycleOutcome> {
  "use workflow";
  if (decision?.decision === "approved")
    return {
      kind: "handoff_requested",
      cycleId: input.cycleId,
      promotionId: `cloving-${input.cycleId}`,
    };
  if (decision !== undefined)
    return {
      kind: "blocked",
      cycleId: input.cycleId,
      reason: "The operator denied the work.",
      evidenceId: decision.gateId,
    };
  const turn = await protectedEffect({
    scope: { phase: "implement", operation: "claude-turn", round: 1 },
    capability: "claude",
    method: "run-turn",
    target: input.cycleId,
    payload: input.ticket,
    units: 1,
  });
  if (turn.kind !== "completed")
    return {
      kind: "blocked",
      cycleId: input.cycleId,
      reason: "The Claude turn did not complete.",
      evidenceId: "claude-turn",
    };
  const gate = await decisionGate({
    gateId: "review-1",
    kind: "approval",
    prompt: "Review the work of the Claude worker.",
  });
  if (gate.kind !== "opened")
    return {
      kind: "blocked",
      cycleId: input.cycleId,
      reason: "The review gate did not open.",
      evidenceId: "review-1",
    };
  return {
    kind: "waiting_for_decision",
    cycleId: input.cycleId,
    decisionId: gate.decisionId,
  };
}
  • "use workflow"

    The first statement. Cloving records each step of the run, so a GitHub step continues after a restart.

  • protectedEffect

    One step that changes something outside the workflow: a Claude turn, a pull request or a merge. The service does the step and keeps a record of it.

  • decisionGate

    One decision of a person: an approval or a question. The run waits until you answer.

  • CycleOutcome

    The result of the run. It waits for a decision, it is blocked, or it hands off the work.

Your agent finds your workflows in your chats.

Your agent reads only the chats that you select. It shows you the sequences of steps that repeat, and you choose one. Then it writes that sequence as a workflow file, with tests.

In development. Today, your coding agent does this step with a prompt. A Cloving command for this step is in development: #42, #43 and #44.

Read the prompt
Find workflows in my chats with coding agents, and write a draft Cloving workflow for one of them.

Rules:
- Read only the chats that I select. Ask me for the list first. Do not read other chats.
- Keep the chat text and private data out of the repository. Do not copy chat text, names of persons, secrets or local paths into a file of the repository. Keep your notes outside the repository.

Steps:
1. In the selected chats, find sequences of steps that repeat. For each sequence, list the steps, the tool of each step (for example git, a test command, gh or a model), and each decision of a person (for example "approve the diff").
2. Show me the list, and ask me which sequence to use.
3. Map each step that changes something outside the workflow to protectedEffect, with a capability and a method. Map each decision of a person to decisionGate.
4. Use only the capabilities that have a worker: claude (method run-turn) and github. Put each step that needs a different capability in a list of open points, not in the draft.
5. Write the draft in the form of workflows/develop-ticket.ts of the Cloving checkout: an exported async function with the directive "use workflow", and the step helpers from the subpaths of cloving/workflows.
6. Write a list of the human decisions in the draft: for each decisionGate, the question, the person who decides, and the result of each answer.
7. Write workflow tests with a fake step bridge, in the form of test/develop-workflow-fixture.ts.
8. Tell me which changes of the Cloving code the draft needs before the service can run it. The section "Develop a workflow" of the Cloving README lists them.
Your level of control

Your factory can be as involved or as hands off as you want it to be.

Each workflow sets who does each step. Move the control to see one run with more or less of you in it.

How involved do you want to be?
2 of 6 steps are yours

Your own workflow: an agentic review and a decisionGate in one file.

  1. Start

    You

    You start one run for an issue.

  2. Work tree

    Cloving

    Cloving makes a new branch in its own work tree.

  3. Worker turn

    Cloving

    Cloving starts your agent in the work tree and records the turn.

    runs your agent Claude Code or Codex Writes the code with TDD and runs the checks.
  4. Code review

    Cloving + you

    Cloving runs a review agent on the pull request. Then a decisionGate asks you to approve.

    runs your agent Your review agent Reviews the pull request and lists the findings.
  5. Merge

    Cloving

    After your approval, Cloving merges.

  6. Next

    Cloving

    A notify command tells you when a run needs you.

  7. Changes requested: the findings go back to the worker for a new round. Your workflow code sets how many rounds a run can have.
Why Cloving

A factory that fits how you work

It starts from your chats.

Your workflows come from your own work. Cloving adds no new roles or names for you to learn.

It is plain TypeScript.

You can read a workflow, type-check it, test it with a fake step bridge and see each change in a diff.

It stays on your computer.

Cloving keeps each run, each event and each decision in a database on your Mac. A GitHub step continues after a restart.

You choose how involved you are.

Approve each step yourself, or let the factory review, merge and take the next ticket. Each workflow sets the level.

Get started

Build your factory.

Install Cloving from npm. Then paste the setup prompt into Claude Code or Codex in your repository. Read it first. It tells your agent what to do and what not to do.

npm install --global cloving --ignore-scripts

For a first run by hand, read the First run section of the README.

Setup prompt for your coding agent
Set up Cloving for the repository in the current directory. Ask me for each value that you do not know. Do not push, publish or merge anything in this setup.

1. Check that this computer matches the os, cpu and engines that "npm view cloving os cpu engines" shows. Check that git and the claude command work. If I want develop-issue, check that gh has a login and that Greptile reviews the GitHub repository.
2. Install Cloving from npm: npm install --global cloving --ignore-scripts
3. Make sure that "cloving --version" works. If the node program of the search path does not match the engines of Cloving, tell me before you continue.
4. Ask me which tracker has my tickets. Write a ticket command for that tracker in ~/.local/bin. The command gets a ticket ID as its last argument and prints the text of the ticket. For develop-issue, the first line is "# " and the title, and one line is "GitHub issue: OWNER/REPOSITORY#NUMBER". Test the command with one ticket ID, and show me the output.
5. Start the service in a terminal session that stays open, for example a tmux session. In that session, in my repository, run: CLOVING_TICKET_COMMAND='["TICKET_COMMAND"]' cloving start
   For develop-issue, also set CLOVING_CHECK_COMMAND to the checks of my repository. Give me the address of the watch page.
6. Make a first run with develop-prompt and a small task that I agree to. Show me the output of "cloving questions" and the diff of the branch. Do not approve or deny. I decide.
7. Then run my first ticket: cloving run develop-ticket --ticket TICKET_ID
   Show me the diff again before I decide.