Knowledge Base
Adopt a project you already have
Put a torta workspace around the projects you have been working on, without losing a file or a commit.
The wizard makes new projects. Adoption is the other door: you point torta at a folder you already work in, Claude Code reads it and says who owns each project in there, and you land on the board with your code intact and your git history behind it. The stack does not matter. Flutter, React, React Native, Go, a pile of markdown: what torta needs to know is which agent owns it.
Start here, because it writes nothing. This prints the whole plan and stops:
torta adopt ~/Documents/projects/my-app --dry-run
You get what moves and where to, what stays where it is, what is already there and how it will be kept, which repository is reused, and the command that reverses all of it. Nothing is written, nothing moves. It is the same answer the wizard’s summary page shows, from the same function, so the two cannot disagree. When it reads right, run the same line without the flag:
torta adopt ~/Documents/projects/my-app
With no folder named, it adopts the one you are standing in. In the browser the
same door is the wizard’s first question: torta start asks what are we
setting up?, and a folder I already have is the second answer. That adds
two pages after the one asking where the project lives, what is in that
folder and who owns each project, and drops the one asking what you are
building, because that follows from what was adopted.
What actually happens to your folder
The folder you name becomes the workspace root, and your app moves into it, one directory down:
my-app/ the workspace root now
torta.json torta's config
ADOPTED.md what torta did, in full
.agents/ one home per agent
.projects/
frontend/core/ the app, moved here whole
package.json the same file, unedited
src/ public/
.git/ your repository, your history, your remote
backend/ the API beside it, moved here whole
.git/ its own repository, likewise
.git/ a new repository, for the config and the queues
Five things are worth knowing, and each one is a decision rather than an accident:
- Moved, never copied. Every file is the same file. A rename per entry, written down before it happens, so nothing is duplicated and nothing is rewritten.
- Your repository comes with the code. Each project’s
.gitmoves with it and keeps its history, its branch and its remote. Nogit initruns over it. The workspace root gets a separate new repository for the config and the queues, so each repository owns what it should. - Nothing already there is overwritten. If torta needs a name you are
already using, it merges (for
.gitignoreandCLAUDE.md, inside a marked section that leaves your lines untouched) or it keeps both, moving yours aside with a pointer to the one now in force. - A platform folder this workspace does not build comes along untouched.
android/is the usual one. It moves with the code and stays exactly as it is; torta will not build it, ship it or run anything in it. That is said on screen before you adopt, and again inADOPTED.md. - Anything is adoptable. There is no stack torta refuses. What it refuses is an empty folder, a folder too large to read, and a folder that already holds a workspace.
Who owns what
A Claude Code session reads the folder and answers, for each project it finds, which agent owns it: frontend, backend, qa, infra, archi, product or growth. It is a read on your own login and it runs nothing, and it is not something you are asked for: torta refuses to start at all without Claude Code installed and signed in, so reading the folder you chose is part of adopting it. Both doors say so on screen while it works.
Each answer arrives with a plain sentence saying why, the folder the project
would move into, and a menu to change it. Correct an owner and the folder
changes with it, so the page can never promise somewhere the code does not go.
Where an owner keeps its work comes from the layout: backend projects land in
backend, a marketing site in growth/website, documents in archi. Frontend
has four repositories, so one frontend project is kept whole in frontend/core
and several split across mobile, web and desktop by the platform folders
each already has.
torta adopt ~/work/everything --as frontend --as backend --as archi
--as repeats, once per project, in the order they were found. Saying it for
all of them skips the reading, because there is nothing left to read for.
A project nobody can be worked out for is left exactly where it is. It is
not moved, nothing is written inside it, and ADOPTED.md says so. torta does
not guess, and neither door will move a folder it cannot place.
A project you do not want adopted is answered with --as none, or with the
same option on the wizard’s assign page. Same result: left alone, named in the
report. At least one project must still be adopted, and declining all of them
is refused before anything moves.
What each project is built with
torta reads the manifest beside the code and binds the profile that fits it. An
adopted React app lands on the node profile, so its walls grant that toolchain
and its brief names package.json and npm run build, rather than the Flutter
commands the layout declares for a workspace torta built from nothing.
A stack torta has no profile for binds an honest empty one. It grants no build
tools and names no commands to run before a PR, so nothing claims a gate torta
cannot run, and ADOPTED.md says so in words. Write a profile into
.agents/.core/profiles/ and name it on that repository in torta.json to give
it real gates.
The deploy target and the test suite paths follow the same rule. The layout
wrote both for the stack it declares, so a Node service adopted into backend
does not keep a Supabase deploy target: the field is absent, and the report
names the repository that lost one. A wrong deploy target is worse than no
target, because an agent may act on it.
What the workspace builds, and what it leaves alone
Platforms follow from what was adopted, which is why the adopt door never asks. A backend project turns the backend on and a landing page turns the site on. A project whose folders and stack say nothing about what it ships turns no platform on at all, rather than being taken for a web app, and the report says which project that was.
Nothing implied is created empty either. A web build implies a backend, and an adopted React app has its backend somewhere else, so torta declares that repository and switches it off: no empty directory, and no backend agent sitting in front of nothing. Ask for one at the time:
torta adopt ~/Documents/projects/my-app --backend
Or later, put backend back in that repository’s platforms list in
torta.json and run:
torta sync
Sync makes the declared directory and stamps the home, the brief and the queues of any agent the roster has gained, so the agent it brings back can be given a ticket straight away.
Undo
The last section of ADOPTED.md is the command that reverses everything:
torta adopt <dir> --undo
It removes what torta wrote, puts back anything it moved aside, and then reverses every move through the journal that recorded it. Run it on a fresh adoption and the folder is byte for byte what it was, including work you had not committed.
It never removes anything that is not torta’s, so it is at its cleanest before you have started working in the workspace. It refuses, naming the file, rather than remove something of torta’s you have edited since: move that file aside and ask again. Anything it cannot clear (a queue holding a ticket you wrote after adopting) is left standing and named on screen, for you to delete once you have taken what you want out of it.
If a move is ever interrupted, torta adopt <dir> --resume finishes it from
the same journal, and --undo still works afterwards.
What the reading actually does
The cheap probes go first: a bounded directory walk, a manifest read line by
line, a handful of git questions. They say what is on disk and nothing about
who owns it, because a filename cannot answer that.
Then one Claude Code session, in the folder you named, with reads only: no writes, no commands, no network, and a hard timeout. It is given the list of candidates and the list of owners, and it answers with one of those owners per project and a sentence saying why. Anything it will not place comes back unplaced rather than guessed at, and everything it does place is yours to change before you press adopt.
After adopting
The board comes up exactly as it does for a new workspace: empty queues, and the terminal panel open on the agent that takes requests. Tell that agent what you want next and it writes the first ticket.
One thing an adopted app almost always turns out to want: a backend and a
landing page. Turn either on the way the section above describes, and ADOPTED.md
says the same thing at the bottom of your folder.