Workflow definitions
You define and edit your workflows in the dashboard: open Configuration → Workflows, where each workflow is a named, ordered list of steps, stored per user and workspace. That is the source of truth at runtime.
The *.toml files in the workflows/ directory (relative to your config.toml) are the
defaults. The first time Takuto Core encounters a new user/workspace, it seeds that
workspace’s workflows from them; editing the TOML afterwards does not change workflows that
are already seeded — change those in the dashboard. Start your defaults from the examples
shipped in the Takuto Core repo:
cp workflows/implement_ticket.example.toml workflows/implement_ticket.toml
The rest of this page documents that TOML shape — it is the format of the seed files, and a handy reference for the same fields you edit in the dashboard.
File shape
Each file has a top-level name, an optional depends_on, and one or more [[steps]]:
name = "Implement Ticket"
[[steps]]
name = "Implement ticket"
prompt = """
Follow the instructions below:
{description}
"""
repeat = 1
Step fields
| Field | Description |
|---|---|
name | Human-readable step name (shown on the dashboard). |
prompt | Multi-line prompt sent to the agent. Ticket context is injected via placeholders. |
commands | A command step — deterministic shell commands instead of an agent prompt. Mutually exclusive with prompt/skills. Command steps consume no AI tokens. |
repeat | How many times to re-run this step (default 1). |
when | "always" (default) | "ticketing" | "no_ticketing" — gate a step on whether a ticketing system is configured. |
skills | Optional Claude/Cursor skills to invoke: [{ name = "skill-name", args = ["--flag"] }]. |
Chaining workflows with depends_on
A definition with depends_on = ["implement_ticket"] only becomes available on a
workflow card after the implement_ticket flow has completed. This is how the
“Merge base branch” and “Address PR comments” follow-ups are wired — they run in the
same worktree once the main flow is done.
Prompt placeholders
These are Takuto Core‘s runtime placeholders — single braces. Write them literally in your prompts. They are unrelated to this site’s build tokens.
| Placeholder | Description |
|---|---|
{description} | Ticket/issue description text. |
{ticket_key} | Ticket identifier (e.g. PROJ-123, #42). |
{ticket_summary} | Ticket title. |
{ticket_context} | Formatted summary: key, title, description, acceptance criteria. |
{ticket_type} | Type label (Bug, Story, Task). |
{acceptance_criteria} | Acceptance criteria field, if available. |
{base_branch} | Target branch for the PR (e.g. main, develop). |
{pr_url} | PR URL — available in review / merge-base steps. |
Linting, tests, and opening the PR are agent step prompts, not engine steps. A step that prints
TAKUTO_PR_URL: <url>or writes.takuto/outcome.tomllets Takuto Core record the PR URL and surface the Address PR Comments action.
The three example workflows
The setup wizard (and the example folder) ship three ready-to-use definitions.
1. implement_ticket.toml — the main pipeline
A full implement → review → commit → lint/test → PR pipeline. Note the two
Implement ticket steps gated by when: one for no-ticketing mode (uses
{description}) and one for ticketing mode (reads the ticket from the system prompt).
name = "Implement Ticket"
# Implement (no ticketing system)
[[steps]]
name = "Implement ticket"
prompt = """
Follow the instructions provided below:
{description}
BOUNDARIES: This step covers implementation only.
- Do NOT commit any changes — a dedicated "Commit changes" step follows.
- Do NOT create a PR — a dedicated "Create PR" step follows.
SCOPE CONSTRAINT: Only implement what is explicitly described above. Do not refactor
unrelated code; leave a # TODO if you spot something out of scope.
"""
when = "no_ticketing"
repeat = 1
# Implement (with ticketing system)
[[steps]]
name = "Implement ticket"
prompt = """
Follow the instructions in the system prompt.
(same boundaries and scope rules as above)
"""
when = "ticketing"
repeat = 1
# Review changes — run twice
[[steps]]
name = "Review changes"
prompt = """
Ticket context:
{ticket_context}
Review all changes on this branch relative to `{base_branch}`
(i.e. `git diff {base_branch}...HEAD`). Only address issues in code changed for this
ticket. Confirm each finding is genuine before fixing it. Do not create a PR.
"""
repeat = 2
# Commit changes
[[steps]]
name = "Commit changes"
prompt = """
Commit the work into logical, conventional commits. Never run git checkout/restore/
reset/clean/stash — only create commits. Do not create a PR.
"""
repeat = 1
# Lint and test
[[steps]]
name = "Lint and test"
prompt = """
Run the project's linter and fix all issues; run the test suite and fix failures
(never delete or skip tests); run the formatter. Commit with
`chore: fix lint warnings, format, and failing tests`. Do not create a PR.
"""
repeat = 1
# Create PR — via the create-pr skill
[[steps]]
name = "Create PR"
prompt = """
Ticket context:
{ticket_context}
The PR title must be a conventional commit message and must not contain the workflow
name, branch name, or ticket ID.
"""
[[steps.skills]]
name = "create-pr"
args = ["--no-draft"]
repeat = 1
2. address_pr_comments.toml — the review loop
Depends on implement_ticket. Uses {pr_url} to fetch unresolved review comments,
fix them, then re-run lint/tests.
name = "Address PR Comments"
depends_on = ["implement_ticket"]
[[steps]]
name = "Fix review comments"
prompt = """
Pull request URL: {pr_url}
Ticket context:
{ticket_context}
Retrieve all unresolved PR review comments. For each: make the change, verify it
locally, commit with a descriptive message, and push to the PR branch. Do not bypass
linting or tests.
"""
repeat = 1
[[steps]]
name = "Lint and test"
prompt = """
Run the linter, test suite, and formatter; fix all issues; commit with
`chore: fix lint warnings, format, and failing tests`.
"""
repeat = 1
3. merge_base.toml — keep the branch current
Depends on implement_ticket. Fetches and merges the base branch into the feature
branch, resolving conflicts, then re-runs lint/tests.
name = "Merge Base Branch"
depends_on = ["implement_ticket"]
[[steps]]
name = "Merge base branch"
prompt = """
Fetch the latest `{base_branch}` from remote and merge it into the current branch.
Resolve conflicts — prefer the current branch for feature code, the base branch for
config/dependency files unless they conflict with this ticket's work. Run lint and
tests after the merge, then commit and push.
"""
repeat = 1
Command steps and run commands
For deterministic work like linting or building, a command step (commands = [...])
runs shell commands directly and consumes no AI tokens. Separately, run commands
(configured per user from Configuration → Worktree Settings) appear as buttons on
completed workflow cards — e.g. “Dev Server”, “Storybook” — with automatic port
forwarding when a server starts.
See How it works for where these steps sit in the lifecycle.