Set up, explain, or change a Tessl factory on a repository: agents that act on events in the repo, such as triaging new tickets, shipping tickets as pull requests, answering reviews and fixing checks on those pull requests, reviewing code, or running a job on a schedule. Use when someone wants Tessl agents to do work in their repo, asks what a factory is or what theirs does, or wants to add to, change, or customize it.
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
The canonical home for this skill is tessl-labs/factory-setup
A factory is a set of automations on a repository. Each one is a rule: when something happens (a ticket is filed, a pull request gets a review, a time of day arrives), a Tessl agent runs a skill in the cloud and does one job.
Your job is to help the user pick the first automation that is useful to them, set it up safely, show it working, and then help them see what else they could add. Fit the factory to how the user works. Do not assume they use pull requests, Linear, or any other tool until you have checked.
Rules for the whole session:
ws-, in a question or a choice. When there is only one workspace, call it
"your Tessl workspace".--workspace <workspace> only with these Tessl commands:
project link, project create, integrations show, and github token.
Before a project is linked, the GitHub App checks need it.tessl doctor or tessl install. gh and git commands
do not take it.--org <org id> to
project link, project create, environment create, and code repo.webUrl or Web URL: value the Tessl
command prints. Never guess a link or link to an API URL. If a command prints
no link, say where to find the page in the web app instead. Write every link
as the plain URL, never as markdown link text, so a terminal shows it. See
Browser links.If the user has already said they want to add an automation to an existing factory, skip this step. Do not describe what already exists. Say in one line that new runs use Tessl credits, link to Tessl pricing, and go to step 2.
Before you run anything that changes state, tell the user in a few short sentences:
tessl.json, and maybe a label. Code Review uses a second
GitHub App, Tessl Review.tessl.json.Then show the progress timeline, with every stage to do, so the user sees the whole path before they agree. Ask: "Do you want to go ahead?" Stop if they say no.
tessl --version first. If it
is obsolete, follow Check the Tessl CLI and
stop. Otherwise run tessl cli update --dry-run. If it reports an
available update, tell the user to run tessl cli update, then check which
CLI the shell runs, as the same reference says. Do not run tessl update:
that updates plugins, not the CLI. If it fails because self-update is
disabled, the CLI came from winget: follow the same reference. If the
version check fails for another reason, tell the user to resolve the CLI
update before continuing.gh repo view --json isFork,parent). If isFork is true, say in one line
that it is a fork of the parent repository and that the factory will run
on the fork, not on the parent, then continue. Never move the user onto a
fork to get write access, for example from an upstream with read-only
access to their fork.tessl.json, tell the user to run tessl init and stop.
If the repository is a fork and tessl.json already has actions,
triggers, or schedules, they came from the parent. Before you link or
create a project, list them in plain words: what starts each one and what
it does. Say that they start running on the fork once its project exists
and the file is on the default branch, and that any action naming an
environment from the parent is refused until an environment with that name
exists in the user's workspace. Ask whether to keep, change, or remove each
one, and make that change in step 7.mode from tessl.json. If it is vendored and
git ls-files .tessl/plugins lists nothing, the plugins installed here
would be committed with the setup, often thousands of lines. Tell the user
in two sentences: managed mode keeps installed plugins out of git, like
node_modules, and every clone and cloud run installs them from
tessl.json; vendored mode commits them. Recommend managed, and ask. If
they choose managed, set "mode": "managed" in tessl.json and run
tessl install, which writes the ignore rules. If AGENTS.md or
CLAUDE.md links .tessl/RULES.md, which a fresh clone lacks until
tessl install runs, add a line before the link saying to run it first.
If .tessl/plugins is already committed, leave the mode as it is unless
the user asks.git status. If there are uncommitted changes, say so and ask the user
to commit them or put them aside before you continue. Do not move or stash
them yourself.tessl whoami. If it fails, ask the user to run tessl login.tessl project repair --json. The workspace is
linkedProject.workspaceName, and webUrl is the project's browser link.
If there is no linked project, and step 1 was
skipped, do not link or create one: tell the user this repository has no
factory yet and go to step 1. Otherwise run tessl org list --json. If it
lists several organizations, ask which one to use, by name. Then list the
workspaces with
tessl workspace list. If there is one, use it without asking. If there
are several, ask which to use. Before you link or create anything, run the
GitHub App checks from item 9 and tessl environment view <repo>-factory --json,
and check permissions for what is still to do.
Then run tessl project link --workspace <workspace>, or
tessl project create --workspace <workspace> if no project matches. Then
run tessl project repair --json again. Keep linkedProject.id and
webUrl for the rest of the session, and give the user the project link.tessl org list --json, if the organization's credits.state is not
ok, tell the user that factory runs will not start until the
organization has credits, and ask whether to continue.gh repo view --json nameWithOwner,defaultBranchRef). Use
defaultBranchRef.name wherever these steps say <default branch>. Check
that the Tessl App can write to it:
tessl integrations show github-app-agent --json and the exit status of
tessl github token --repo <owner/repo>. Run the
token check with both output streams redirected to /dev/null, and use only
its exit status. Never capture, print, log, or repeat its output because it
contains a live installation token. If either check fails, give the user a
link from the integration JSON: installUrl when the app is not installed.
When it is installed on the repository owner's account, give that entry's
manageUrl (the GitHub page where repository access is granted) first,
then webUrl. When no entry is on that account, give webUrl and ask them
to install the app on the owner's account. If there is no link, send them
to the organization settings, under Integrations, GitHub. Ask them to install the Tessl GitHub
App there, or, if it is already installed, to grant it access to this
repository. Say that it asks for read and write access so agents can
comment, push branches, and open pull requests. Show the timeline with
"Check your setup" marked ◐ and wait until they say it is done. Then run
both checks again. If they pass, carry on with step 3. If not, say which
check still fails and wait again.Read before you ask:
CLAUDE.md, AGENTS.md, and CONTRIBUTING.md, for rules about branches,
pull requests, and releases.git log --first-parent -30 <default branch>. Merge commits mean work
arrives through pull requests. Plain commits mean people push to the
default branch.gh pr list --state merged --limit 10 and
gh api repos/<owner>/<repo>/rules/branches/<default branch>.gh issue list --limit 5), or a
Linear connection (tessl integrations show linear --json)..github/workflows/.Tell the user what you found in two or three sentences, for example "You push
straight to main, file GitHub issues, and have no CI." Ask them to correct
it. If the user has already said what they want to add to an existing
factory, skip the first-ticket question and the goal question below.
Otherwise, if there are
no open GitHub issues and either no Linear connection or no open Linear issues,
recommend a small, safe first ticket, such as a README
fix, and say you can file one to show it working once it is live. Otherwise,
ask: "Is there one thing you want Tessl to take off your plate first?" Do not
create an issue until the user picks a test in step 9.
If the repository needs tools or dependencies installed to build or test, tell
the user which ones. Say that Tessl runs .tessl/cloud-launch-setup.sh before
every cloud run, and offer to write it to install them safely more than once.
Ask before writing the hook. Do not mention the hook when the repository needs
no setup.
Fetch the default branch (git fetch origin <default branch>) and read
tessl.json from the remote copy
(git show origin/<default branch>:tessl.json). The local file can be behind,
for example after a setup pull request merged on GitHub. If the local file
differs, say so. If the fetch fails, say so and stop. If the fetch works but
the default branch has no tessl.json, nothing is set up there yet. Find the
actions, triggers, and schedules, and the environments they use
(tessl environment view <env> --json). On a fork whose project was created
in this session, entries inherited from the parent are not on yet: describe
them as preflight did, not as automations already running. Check Code Review for this
repository with tessl code repo view <owner/repo> --json, and read
repository.attentionReason and, under repository.review, enabled,
triggerPolicy (open-and-command reviews when a pull request opens,
every-push on every push), publicationMode, and autoApproveWhenResolved.
Tell the user whether Code Review is on, how it publishes, and whether it will
review the setup pull request. It reviews only when enabled is true and
attentionReason is null; a non-null reason, such as
installation-suspended or missing-permissions, means the GitHub App cannot
act on the repository, so name the reason. A missing Loop or factory entry
does not mean Code Review is off. If the repository command fails or the
repository is not listed, run
tessl integrations show github-app-code-review --json:
integrations list is empty, the Tessl Review app is not connected
to this workspace. Say Code Review is not set up yet, and keep the webUrl
it prints for step 5.If nothing is set up, say so. If you skipped step 1, go back to step 1 now. Otherwise, go to step 5.
If something is set up, tell the user in plain words which automations are
on, what starts each one, and which skills are their own copies. Give the
project's Loops link: the project webUrl from preflight with /loops
added. Then
suggest one or two automations from the starters
that fit what they already have and how they work, and say what each would
save them. For example: "Tessl already ships your labeled issues. Code
Review could review every pull request, including the ones your team opens."
If an implement action is set up and no follow-ticket-changes action is, suggest adding
"Follow ticket changes" first: without it, runs keep going after a person takes an issue back, pull
requests stay open after their issue ends, and an answered or unblocked issue
waits for a person to move it.
Ask what they want to do: add an automation, remove one, change what starts
one, or edit a skill. If they
want to add an automation, go to step 5. Steps 1 to 3 have already run; do not
repeat them. In step 6, reuse the environment the existing actions use,
except for "Improve development", which has its own.
Set up the first automation, with one exception: whenever "ship tickets" is the starter being set up, offer "answer reviews and fix checks" at the same time, and Code Review too when step 4 found it not set up or unknown.
Whenever "ship tickets" is the starter being set up, first say what it does in
plain words: what starts it, what the agent does, what it changes, and how to
stop it. Say that it comes with a small loop, "Follow ticket changes" (the
follow-ticket-changes action), that keeps it in step with people: it
cancels runs when a person takes an issue back, closes the pull request when
the issue ends, and wakes the issue when a person answers Tessl's question or
its blocker ends. Then explain that "answer reviews and fix checks" acts only on pull
requests Tessl opens: it answers review comments, fixes failing checks, and says
when the pull request is ready to merge. If step 4 found Code Review not set up
or unknown, also explain "review pull requests": Tessl reviews every pull
request, including the ones Tessl opens, and the agent answering reviews acts
on those findings. Say that it needs the Tessl Review app on the repository,
and that setup turns review on once the factory is live. Recommend all of
them together.
Ask which they want: all of them, "ship tickets" with "answer reviews and fix
checks", or "ship tickets" alone. Set up only what they say yes to. Add the
tessl.json entries in one change, follow
Review pull requests for Code
Review, and test each chosen part if the user picks a test in step 9.
For every other starter, before you build it, say what it does in the same plain terms and ask: "Is this what you want?"
Use one environment named <repo>-factory. If it exists, show its access and
ask before you change it. If not, create it with the access that the chosen
starter lists. When both "ship tickets" and "answer reviews and fix checks"
are chosen, use this one environment for both. Both need
--github-access write. For Linear, also keep --linear-access write,
because the agent answering reviews reads the Linear issue:
tessl environment create <repo>-factory <flags>, then confirm it with
tessl environment view <repo>-factory --json. Give the user the environment
link from webUrl. When you tell the user, show the
timeline with "Build it" now.
"Improve development" uses its own read-only environment, <repo>-improve,
as its starter says, so its agents cannot push.
If tessl environment create --help has no flag that the starter needs, ask
the user to create the environment in the web app, under workspace settings,
Environments, with that access.
setup-tessl-factory. If that name already exists locally
or on the remote, name it after the starter being added:
add-tessl-ship-tickets, add-tessl-answer-reviews, or add-tessl-<name>
in lowercase words joined by hyphens for any other starter. If that name
exists too, add -2, -3, and so on until the name is free.
tessl launch models --json: it lists the agent and model pairs cloud runs
accept in this workspace, and the default pair, which is null when the
workspace has none. The list spells claude as claude-code and tessl as
tessl-agent; both spellings work in tessl.json. Keep a starter's agent
and model only when that pair is in the list. Otherwise ask the user to
pick a pair from the list. When default is not null, recommend it, and
offer to remove model so that pair runs. Never name a model that is not in
the list.
If the command fails, the list is unknown, not empty: say so, keep the
starter's pair, and let tessl doctor --automations below check it.dependencies.
Fill in <user-id>, <review-bot-id>, and <repo-id> as
the triggers reference says. Tell the user in one
line who can start them: on GitHub only they can, and how to let someone
else; on Linear, anyone who can delegate to Tessl..tessl/cloud-launch-setup.sh in the same change. It runs from the clone
root before every cloud run, and its install steps must be safe to run more
than once. Make every required setup failure stop the hook with a non-zero
exit, for example by using set -e or checking each command's exit status.
Write it as the setup hook reference says:
compatible version ranges from the repository's own declarations, not CI's
exact versions.sudo) and ask the user's agreement. If they decline, skip the check and
say the cloud check in step 8 will test the hook.
gh repo clone <owner/repo> <dir>)
into a temporary directory, not from the local copy, so the clone's
origin matches the project. Copy the proposed change into it, and run
tessl install from its root.CI=true bash .tessl/cloud-launch-setup.sh < /dev/null
twice, to show it is safe to run more than once, on the user's machine.
If a hook run fails, show the failing step. Fix the hook only if the
failure would also happen on the cloud machine, then test again. If it
comes from a local difference (another OS, a tool the cloud machine has
and this one lacks), say so and leave that step alone.gh label create tessl.Comment only Code Review mode cannot
satisfy that rule. Tessl can approve only when Code Review is
enabled with a null attentionReason and publicationMode is
enforcing. It then approves a pull request whose review has no blocking
findings, or, with autoApproveWhenResolved on, once every Tessl Reviewer
thread on the pull request is resolved. With auto-approve off, warn that a
pull request with blocking findings still waits for a human approval. If
Code Review is off, needing attention, or unknown, say that Tessl pull
requests will wait for a human approval. If they want Tessl's review to
satisfy the rule, offer
tessl code repo update <owner/repo> --review-publication enforcing, or
Approve or request changes under Code reviews in the web app if
that is refused. Change nothing without asking.
When Code Review and "answer reviews and fix checks" are both on or both
chosen, say what
the review's triggerPolicy means for Tessl's pull requests:
open-and-command reviews a pull request when it opens or when someone
asks, so a fix the agent pushes after an approval is not reviewed again;
every-push reviews every push, and each review uses credits. Recommend
every-push, and ask. Apply the choice with
tessl code repo update <owner/repo> --review-trigger <policy>. If setup
is turning review on, apply it in step 8, when review goes on.tessl doctor --automations. Act only on the Automation Configuration
section; ignore every other section. Fix problems in that section. Tell the
user what each warning means for them, not what it says. For example, "event
delivery not confirmed" means "Tessl has not received a GitHub event from
this repo yet. This is normal until the change is on the default branch."
If it reports that a model is not available to an agent in this workspace, run tessl launch models --json again and ask the user to pick a listed pair, or to remove model when the list has a default pair, then run tessl doctor --automations again. If it then reports The workspace organization has no default model configured for cloud-run-solver., stop and tell the user that their model provider needs a default for cloud runs or that they can set model to a model their provider enables. The local configuration passes when this section reports that tessl.json is valid and lists no configuration problems. Do not take the setup live while Agent selections or Event delivery is Undetermined; those online readiness checks must run successfully. Before the change is on the default branch, the Loops subsection reports that the project has not processed a tessl.json yet. That is expected, and the delivery lines then warn that nothing runs. When "answer reviews and fix checks" is set up, doctor always reports the shepherd-checks-failed and shepherd-checks-passed triggers as events that cannot be marked. These Information lines are not problems, and they do not block going live. Tell the user what they mean: runs that start when a check finishes leave no mark on GitHub, so watch them in the Loops tab. If it reports that cloud runs will fail installing a dependency's file: source, say in plain words that cloud runs install every dependency in tessl.json and will fail on that one, and offer to switch it to the published plugin. If it says the source is not committed, include it in the commit instead. Do not change it without asking..tessl/plugins/, say so: cloud runs fail the same way even when CI
passes. Ask before you change any lint, format, or CI configuration. Do not
edit the installed plugin files.tessl.json is on the default branch.tessl.json from
origin/<default branch>. Proceed only if it is readable and reflects the
whole submitted change: every added or changed value matches and every
removed entry is absent. Otherwise, say that the configuration is not live
and stop. When it passes, say the change is merged and that you are now
checking that Tessl has turned the automations on. Do not say or suggest
that the factory is running until step 3 confirms the Loops. Ask whether
the user wants their local default branch updated. Update it only if they
agree. If the agent's permission system refuses the update, do not retry or
work around the refusal; tell the user to run
git switch <default branch> && git pull themselves.webUrl from
Preflight with /loops added, ending in
/go/projects/<project id>/loops. Say which Loops they
will see and what starts each. Then
confirm the Loops appear. Do not say setup is
finished until they do.Do this as soon as step 8 confirms the Loops, before any test. First gather
what the message needs: the organization's credits and, when review is on,
tessl code repo view <owner/repo> --json. Then, with no tool call in
between, send one message that starts with "Your factory is live.", shows the progress timeline with "Recap"
marked ● now, and tells the user:
credits.remaining in
tessl org list --json. Do not estimate how many runs are left.If the user asks for something before this message has gone out, send it first in your next reply, then do what they asked.
End that message with one question and three choices:
verify.groups in tessl.json or its lenses are in
.tessl-code-review.yml, offer the
Improve development starter.
Otherwise offer the prepare-repo skill: it reads
the repo's review history, CI failures, and fix commits, and proposes agent
context, checks, and review rules. It changes nothing in the repository
until the user picks what to keep; a missing skill it needs is installed
for their account only if they agree. When step 3 found substantial agent
context, such as a full AGENTS.md or CLAUDE.md, call it a tune-up of
what is there.Mark "Recap" done when the user answers, or after the test's report if they
chose a test. A test, however narrowly the user
asks for it ("just label an existing issue"), ends with the short report in
Testing the factory; do not ask the
question again. If they want another starter instead, run git status as in
step 2, then go back to step 5 for it.
The Tessl project and GitHub App already exist; step 6 reuses the environment,
except for "Improve development", which has its own. Start a new timeline for
that automation, as in
Adding another automation.
Say the plain words. If a command or screen shows the Tessl term, say what it means in one line.
| Plain words | Tessl term |
|---|---|
| automation | loop, trigger, action |
the GitHub App that lets agents write to the repo, also shown as github-app-agent or GitHub (Tessl App) | Tessl App |
| cloud environment: the machine and access the agent gets | environment |
| check the setup | tessl doctor |
| review rules: what Code Review looks for | lens |
| answer reviews and fix checks: on Tessl's pull requests, an agent answers review comments and fixes failing checks | shepherd |
| wait time: Tessl waits about 90 seconds after an event, so quick events start one run | debounce |
stephaniedominy/tessl-carnival
0e37a76
Canonical home
since Oct 9, 2026
Also appears in
last in sync Oct 16, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.