Project folders and generated files
An Agentic Development Toolkit (ADT) project has two levels: the project itself, and one directory per Web Viewer app inside it. Knowing which level you're in explains where config files live and where commands need to run.
The two levels
my-project/ # the project
├── AGENTS.md
├── adt.json # registry: connected files and apps
├── package.json # workspace root
├── pnpm-workspace.yaml
├── vendor/@adt/fmdapi/ # shared ADT JavaScript library
└── webviewer-apps/
├── dashboard/ # an app
│ ├── adt.config.json # type generation config, per app
│ ├── package.json
│ └── src/
└── reports/ # another app
├── adt.config.json
├── package.json
└── src/
The project is a registry. adt.json records which FileMaker files this work is about and which apps exist. A project created by adt init has no package.json, no dependencies, and no vendor/ — those arrive with the first app.
An app is a Web Viewer app bound to exactly one connected file. Your React components, TypeScript, Tailwind styles, and build config all live under webviewer-apps/<app>/src.
Note Two config files, easily confused adt.json sits at the project root and is the registry of connected files and apps. adt.config.json sits in each app directory and configures type generation for that app. They're unrelated.
Adding an app
Add a web viewer app called dashboard to this project.
Your agent can do this from anywhere inside the project — ADT walks up to find adt.json. It needs to know which connected file to bind to (skipped if there's only one), the app name, and package-manager confirmation if you're on npm without pnpm.
Before writing anything it checks that the target file has ADT's components installed, provisioning them if they're absent. If they're installed but the file isn't connected, ADT connects it for you.
On the first app in a project it also bootstraps the workspace root: the root package.json, the workspace config, and a single shared copy of the ADT JavaScript library. Later apps reuse all three. It commits only the files it created.
A second app is a directory, not a second project. See Multiple Apps for when that's worth doing.
What the workspace shares
Apps in a project are pnpm workspace members. They share:
-
One vendored JavaScript library at
vendor/@adt/fmdapi. It's committed source, not an npm dependency, sopnpm updatewon't touch it — runadt updatefrom an app directory to move it to a newer build. -
One workspace root and one lockfile, so
pnpm installat the root installs for every app. -
The connected-file registry, so several apps can each bind to a different file in the same project.
Each app keeps its own adt.config.json, its own generated client, and its own dist/index.html build output.
Where commands run
Your agent runs the adt commands, not you — but the working directory still matters, because most of them resolve the project from where they're invoked. If a step fails with "no adt.json found", this table is usually why.
| Command | Run from |
|---|---|
adt init
|
The parent directory, or use adt init . in place |
adt connect
|
Anywhere inside the project |
adt components apply / status / reconcile / remove |
Anywhere inside the project |
adt doctor
|
Anywhere inside the project (or outside one, for install-only checks) |
adt app add
|
Anywhere inside the project |
adt layout add
|
Anywhere inside the project |
adt typegen
|
The app directory — it reads that app's adt.config.json |
adt update
|
The app directory |
pnpm dev, pnpm build, pnpm check |
The app directory — these are yours to run |
Paths in an app's adt.config.json — including the typegen path option — resolve relative to that app directory, not the project root.
What's in version control
adt init runs git init and makes an initial commit, unless you passed --no-git. Two things surprise people coming from FileMaker:
-
vendor/is committed. It's vendored source, so it shows up in diffs and in the initial app commit. That's intentional — it's how the data layer stays pinned to the build you tested against. -
node_modules/is not. It's generated bypnpm installand ignored.
adt app add makes its own commit containing only the files it generated, so app creation is easy to review or revert. See GitHub Workflow for the wider source-control picture.
What to read next
-
Preview and Edit an App for the day-to-day change loop.
-
Use a Typed Data Client for the generated data layer.
-
Multiple Apps for when to split one app into two.