.mobster/checks, the simulators in .mobster/matrix.yaml, the workflow files in .mobster/workflows and the branch you’re on. The folder is the source of truth. Mobster keeps only where the folder is, its name, how it came in and when you last opened it.
Projects are part of Mobster for Mac. The mobster command finds a project on its own: it walks up from where you run it to the folder that holds .mobster/ (The project folder).
In Mobster for Mac
Projects in the sidebar, or Projects in ⌘K, lists your projects, the one you opened last first. Each row shows the app’s own icon, the folder, the app and its bundle id, the branch, how many checks it has, its simulators and how the lastmobster test went.
Add a project
- Open Projects and choose Add project, or choose Add a project in ⌘K.
-
Pick one of three ways:
- Import from GitHub: your repositories, the one you pushed to last first, private ones too. Type a name to find one, then choose Import. It needs GitHub connected in Connectors; until it is, the row says so.
- Open a folder: choose Choose folder… and pick the folder with your Xcode project or Expo app.
- Clone a repository: paste its URL and choose Clone.
~/Mobster/Projects; Change folder puts a clone somewhere else. A bar shows how far git got. - The project opens.
mobster test on this Mac are under Recent folders, each with Add. When Mobster refuses a folder or a URL, the sentence under the field says why and what to choose instead.
A project’s page
- Checks: each check in
.mobster/checks, with its last 20 results as dots, newest at the right, and its pass rate. Flaky or Failing shows when its history says so, and a check that hasn’t run says Not run yet. The command that runs them all is under the list, to copy. It quotes the full folder path, so spaces and punctuation stay part of the path. - Run checks builds the app from the folder as it is, then runs every check on the simulators. While it runs, the page shows what it’s doing and how many runs are done, and Stop stops it. The results land under Last runs. A build that fails says so with its first errors.
- A project with no checks offers Set up checks, which adds a starter check for the app.
- Last runs: the project’s last five
mobster testruns. The newest shows each check that didn’t pass, why, its steps, and its log and crash. A run in another folder never shows here. - Workflows: each file in
.mobster/workflowswith its workflow, and Open. One that isn’t in step says so: Conflict, with Keep the file and Keep Mobster’s (the other stays in Versions); File deleted, with Write it again; Can’t read, with the line; Not written, with why. A project without workflow files has no section (Workflows as files). - Beside them: the app, the simulators in
.mobster/matrix.yaml, the repository (a GitHub repository opens on GitHub), and the files changed and the commits ahead on this Mac. - The title switches to another project. Show in Finder opens the folder. Remove from Mobster… asks first, then forgets the project. The folder stays.
Set up checks
Set up checks writes two files and changes nothing else:.mobster/.gitignore, unless there is one. It keeps runs, builds and test results out of git..mobster/checks/app-opens.yaml, a check for the project’s app:
has_checks), and Mobster never writes over a file. A folder with no Xcode project or Expo app is refused (no_app), and so is an app whose bundle id Mobster can’t read from its project file (no_bundle). For those, mobster test add smoke --bundle YOUR.BUNDLE.ID writes one.
Run checks
Run checks ismobster test with a build first:
- Mobster builds the app the way
mobster test prdoes: the Xcode project’s scheme for the simulator, or an Expo app’s Release build, into.mobster/build. A check of that app runs the new build. - Every check runs on the simulators in
.mobster/matrix.yaml, else on each check’s own simulator. Run checks never uses a real iPhone. - The results go in the project’s
.mobster/test-results, and its page shows them.
What Mobster reads from the folder
Reading a folder never writes to it. Mobster runs git with no terminal prompt, without taking git’s index lock and with no fsmonitor hook, so your own git keeps working and a folder’s git config can’t make Mobster run a program.
Add a folder
Send the folder’s full path.~ works.
.mobster folder means the folder that holds it. Adding a folder that is a project already opens it and answers 200 instead of 201.
Mobster refuses a folder that holds more than one project, with a sentence that says what to choose instead:
Mobster keeps up to 100 projects. When a project’s folder moves or is deleted, the project says so (
state is missing) until you remove it.
Clone a repository
Send the repository’s URL. Mobster clones it into~/Mobster/Projects/<name>, or into the folder you name, and adds the clone as a project when git is done.
GET /api/projects/clones/{id} answers how far it got: phase is git’s (Receiving objects, Resolving deltas), percent runs from 0 to 100, and state becomes done with the new projectId, or failed with a code and a sentence. On 17 Oct 2026 the clone above took 2.0 s on this Mac.
The URL is an https or SSH URL (https://github.com/acme/dailies, git@github.com:acme/dailies.git, ssh://git@host/team/app.git), github.com/owner/name, or owner/name for a GitHub repository. folder names the folder to clone into and name the folder the clone makes.
Mobster clones with your Mac’s git sign-in: the Keychain’s saved password, or your SSH key and agent. An https URL on github.com is cloned with your GitHub connector’s sign-in when you have one, so a private repository clones too. That sign-in reaches git through its environment and goes to github.com only: never into the command, the URL, a log or the clone’s .git/config. It never asks for a password, never opens a sign-in window and never waits on a question about an SSH host. A URL with a password or token in it is refused (credentials_in_url), so the token is never kept or shown. A clone that fails is never tried again by itself:
A clone that fails or is stopped (
DELETE /api/projects/clones/{id}) removes the folder it made, and only that folder. If another process creates or replaces that folder, Mobster leaves it alone. Mobster runs at most three clones at once.
Workflows as files
A project’s workflows can live in its repository, in.mobster/workflows/<name>.yaml, so a pull request shows a change to one the way it shows a change to code. Mobster keeps each file and its workflow in step both ways, and looks every 1.5 seconds.
node, or node.port when the port isn’t out or in. A moved node changes its one at line. inputs, vars and a node’s title, notes, parent and retry appear when they’re set.
Conflicts. If the file changes while the workflow has an unpublished draft, or after you published it and before Mobster wrote the file, nothing is overwritten. The workflow shows
conflict until you choose: keep the file’s version (your draft stays in Versions), or keep Mobster’s (your draft is published and written over the file). In the API that’s POST /api/projects/workflows/{workflowId}/resolve {"keep": "file"} or {"keep": "mobster"}.
What stays on your Mac. The workflow’s phone, profile and destination, whether its schedule is on, and pinned test data never go in the file. Mobster won’t write a workflow whose step runs on one named iPhone, or whose graph holds what looks like a key, a password or a card number, including input defaults, variables and notes. The file shows blocked and says why. Mobster does not follow links in .mobster/workflows or its parent folder, so a link cannot redirect a publish outside your project.
A workflow you made in the app gets a file with POST /api/projects/{id}/workflows {"workflowId"}. Workflows with the same name get separate files, such as answer-dms.yaml and answer-dms-2.yaml. File names are unique regardless of letter case. Each workflow’s file in GET /api/workflows says where it is and how it stands: synced, pending, conflict, missing, invalid or blocked, with a sentence when it isn’t synced. The workflows topic of GET /api/events has workflow_file when that changes. On 18 Oct 2026 on this Mac, a new file showed as a workflow 0.3 s after it was saved, and a publish reached the file in 1.3 s.
A task a project’s workflow starts belongs to the project (Tasks and memory in a project).
Tasks and memory in a project
A task belongs to a project when it starts with the project’s id:POST /api/runs takes "project": "<id>", and the task keeps project in its extras as {id, path, name}. A project Mobster doesn’t have is refused with a sentence. Memory learns and recalls a project’s facts under its id (Memory). Adding or opening a project tells memory where its folder is, so what it learned in the folder before it was a project moves to it.
Remove a project
DELETE /api/projects/{id} makes Mobster forget the project. The folder and everything in it stay where they are, and its workflows stay in Mobster without their files. Mobster writes in a project only its workflow files and what you ask for: Set up checks writes new files only, and Run checks builds into .mobster/build.
What a project never holds
A file in your repository never names a real iPhone. You choose a phone on the command line (--device) or in the app. Secrets never go in .mobster/.
API
The events
project_added, project_opened, project_removed, project_changed, clone_changed, clone_ended, run_changed and run_ended arrive on the projects topic of GET /api/events. run_changed comes at most four times a second, with run. Sending a request is in Scripting.