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, keeping pull requests moving, 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:
--workspace <workspace> only with these Tessl commands:
project link, project create, and integrations show linear.tessl doctor or tessl install. gh and git commands
do not take it.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.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, tell the user
that Tessl does not read tessl.json from a forked repository yet, so
automations set up here will not run. Name the parent repository, and
suggest a repository that is not a fork, for example a fresh copy pushed
to a new repository. Stop without linking or creating a project, or
creating an environment, label, branch, or tessl.json change, until the
user chooses. Before you point origin at a different repository, run
this check on it. 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.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 ask which workspace to use, 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 GitHub 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 ask: "Want me to file a small first ticket, such as adding a README,
and show it working?" Otherwise, ask: "Is there one thing you want Tessl to
take off your plate first?" Do not create an issue until the user says yes.
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). 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. The organization check,
tessl integrations show github-app-code-review --json, shows only that the
app is connected. A missing Loop or factory entry does not mean Code Review is
off. If the repository command fails or the repository is not listed, say the
repository's Code Review state is unknown. Do not say Code Review is absent.
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
link to each one's Loop: the webUrl of each entry in
tessl schedule list --project-id <linked project id> --all --json, with the
project ID from linkedProject.id in tessl project repair --json. 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."
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.
Set up the first automation, with one exception: whenever "ship tickets" is the starter being set up, offer "keep pull requests moving" at the same time.
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. Then explain that "keep pull requests moving" acts only on pull
requests Tessl opens: it answers review comments, fixes failing checks, and says
when the pull request is ready to merge. Ask whether they want both. Set up both
only after they say yes; if they say no, set up "ship tickets" alone. When both
are chosen, add both automations in one tessl.json change and show both working
in the test step.
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 "keep pull requests moving" are
chosen, use this one environment for both. Both need --github-access write.
For Linear, also keep --linear-access write, because the agent keeping pull
requests moving 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.
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-keep-prs-moving, 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/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.
Then test it before the diff:
sudo). Say the test may
take a few minutes, and ask the user's agreement. If they decline, skip
the test and say the first cloud run will test the hook.CI=true bash .tessl/cloud-launch-setup.sh < /dev/null twice, to show it
is safe to run more than once. Delete the copy afterwards.ubuntu:26.04, --platform linux/amd64, a non-root user
without sudo, no build tools, Node 24, and CI=true. Otherwise make them
on the user's machine, and prefer the container for any step that
changes the machine outside the clone. Do not require Docker.gh label create tessl.Comment only Code Review mode cannot
satisfy that rule. Tessl can approve only when step 4 found Code Review
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
step 4 found Code Review off, needing attention, or unknown, say that Tessl
pull requests will wait for a human approval.
Tell the user to open Code reviews, select the
repository, and choose Approve or request changes if they want Tessl's
review to satisfy the rule. Change nothing without asking.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 Model "claude-opus-5-5" is not available to agent "claude" in this workspace., remove model from the factory actions, 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 "keep pull requests moving" 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.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. After confirming it is live, 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.Show the progress timeline with every stage done or skipped. Then tell the user:
git status as in step 2, then go back to step 5 for
the new starter. The Tessl project and GitHub App already exist; step 6
reuses the environment. Start a new timeline for that automation, as in
Adding another automation.AGENTS.md or CLAUDE.md, word it as a tune-up of what is there, not a
first setup. When prepare-repo has already run on this repo, because its
verifier groups are under verify.groups in tessl.json or its lenses are
in .tessl-code-review.yml, offer the
Keep the harness current
starter instead.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 |
| cloud environment: the machine and access the agent gets | environment |
| check the setup | tessl doctor |
| review rules: what Code Review looks for | lens |
| keep pull requests moving: answer review comments, fix failing checks | shepherd |
| wait time: Tessl waits about 90 seconds after an event, so quick events start one run | debounce |
fkukuck/fabro
ac667f5
Canonical home
since Oct 9, 2026
Also appears in
last in sync Oct 22, 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.