node_modules, no .env, no database. An agent that starts there and runs the project finds nothing.
.tyba/setup.sh is the answer:
When it runs
Once, when the worktree is created, right aftergit worktree add and before you start using the session.
cwdis the worktree, not the main repo.- It runs on a background thread. It never blocks session creation.
- If it fails, the worktree stays up. The failure becomes a log — TYBA keeps the script’s output (with the tail of the log, the last 400 characters, when it errors) and the session moves on.
With no
.tyba/setup.sh in the worktree, nothing happens — no warning, no error. Having no script is the normal case.A new script counts for nothing until you approve it
Same idea as.tyba/config.toml, for the same concrete reason: you clone other people’s repositories. A versioned .tyba/setup.sh with automatic effect would be arbitrary code execution triggered by opening a project.
So the worktree creation dialog shows you the whole script, with a toggle. Without the toggle on, the file may as well not exist.
Consent is tied to the SHA-256 of the content, stored locally by (repo root, hash):
1
TYBA hashes the exact content
A SHA-256 of the bytes.
2
You read the script in the dialog and decide
The content appears on screen. It is not a summary — it is the script.
3
Your 'yes' applies to that hash, and only that one
As long as the script doesn’t change, it holds, and the dialog comes with the toggle already on: “setup.sh already allowed for this repo.”
4
One different byte kills the consent
You edited it, a
git pull touched it, you switched branches — the hash changes, the consent dies, and TYBA asks again.What executes are the consented bytes, handed to
sh on stdin — not the file on disk. Swapping the file between your “yes” and the execution does not change what runs.The environment it gets
The script is the repo’s code, not yours. It does not inherit your shell. The environment is built from scratch:
And nothing else. Your
AWS_SECRET_ACCESS_KEY, your tokens, your DATABASE_URL are not there.
The
agent.env.allow from .tyba/config.toml does not apply here. That allowlist belongs to the agent; the setup gets only the baseline above. If the script needs a secret, it has to go fetch it (from a file, from a keychain) — it will not arrive in a variable.PATH coming from the login shell matters in practice: on macOS the app may be born from launchd, with a minimal PATH that has no bun, no mise and no /opt/homebrew/bin. TYBA resolves your login PATH and that is the one the script sees.
A real script
.tyba/setup.sh
Nothing cleans up what the script created. The database in the example is still there after the worktree is removed — if that matters to your project, the
dropdb is your problem.Edited the script? Commit it
The dialog reads the.tyba/setup.sh from your working copy, and it is that copy’s hash your “yes” stamps. What runs is the worktree’s .tyba/setup.sh — which was born at the base_sha, that is, at the committed version.
If you edited the script and didn’t commit, the two hashes differ, and the result is silent: the setup simply doesn’t run. Commit the change and create the worktree again.
What does not exist
- Running the setup again in an existing session. It is worktree creation, or nothing.
.tyba/setup.ps1or an equivalent. The contract isshwith the content on stdin.- A timeout. A script that hangs stays hung; the session comes up either way.
- A setup logs panel. The result comes out as a session event, not as a tab.
- Consent that travels. It is yours, local, per machine. A new machine asks again — that is the intended behavior.
See also
Worktrees
Where the script runs and when that folder is born.
.tyba/config.toml
The repo’s other file that asks for consent by hash.