Projects
A project is a folder of code on your machine. A Git repository is not required — a plain local folder can be added too.
The Projects section answers questions that Storage and Bindings cannot answer on their own:
- what this code is — what the project consists of, what it runs on, how to start it;
- what is installed specifically for it, and into which folder exactly;
- what the agent reads before any skill —
CLAUDE.mdandAGENTS.md; - how much context each AI tool gets in this folder, and at what price in tokens;
- why a particular skill is available to the agent here at all;
- whether your setup matches what the team agreed on;
- what changed since the last time you looked;
- where the work happened — in which folders and with which tool, when supported local history is available;
- how one project differs from another — when the agent copes here but not in the repository next door.
Adding a folder installs nothing, creates no files in the project, makes no Git commit and sends nothing outside. It is just a note that says «I work here».
Three shapes of a project
onplate tells them apart on its own and says which one it sees in the subtitle of the “What this project is” block.
| Shape | What it is | How it differs on screen |
|---|---|---|
| A single code folder | an ordinary repository | one part, one profile |
| A monorepo | one .git with backend, frontend, … inside | parts are listed, one branch for all, one profile |
| A workspace folder | an empty folder with several repositories cloned into it | every part has its own branch and its own profile |
There is a fourth answer: “this looks like a folder of projects, not a
project”. That is what onplate says about ~/code holding a dozen independent
repositories: add those separately, otherwise a single profile and a single card
would describe everything you own at once.
The shape is decided by facts — whether parts have their own .git, and what
markers the code leaves — not by folder names.
Where to find it
Projects live in the sidebar as their own “Projects” group, above “Management”. The group lists the folders themselves rather than a single menu item: you click a project and land on its page. Past ten projects a search box appears, matching name, path and Git remote.
The first item of the group is “All projects” — the projects overview, a screen about every folder at once. Below it: “Favorites”, then the recent ones (split by your own groups, if you made any) and a collapsed “Archive”.
A project carries up to two counters: unreviewed changes, and what needs attention — unapplied profile entries, local resources outside the profile, errors, a missing folder. So you can see where to look without opening each one.
Getting started
- Open the Projects group in the sidebar.
- Press Add on the Projects page.
- Pick a folder from the suggestions or choose another. The suggestions are the folders you have already worked in: onplate found them in your AI settings, and nothing was sent anywhere in the process.
- Select the added project in the sidebar.
- Stay on the Overview tab — that is the first thing onplate can tell you about the folder, before any setup at all.
Project overview
The “All projects” screen — “Project overview” — answers questions that do not fit inside one folder: which projects need attention, what to do with a long list, and how to run one operation across several repositories at once.
Filters at the top: Active, Needs attention, Archive, All. Projects can be sorted into groups and marked with tags — both stay on this machine and never travel to a repository.
One operation across several projects
Tick the projects and an action bar appears:
| Action | What it does |
|---|---|
| Install… | installs the chosen storage resources into the root of every ticked project |
| Remove… | deletes from disk what onplate installed into those roots |
| Apply profiles | brings every project up to its own .onplate/profile.json |
| Group and tags, Favorite, Archive | tidies the list, never touches the disk |
Three things work differently here than in a single project's dialog, on purpose.
Root only. A part inside a project (backend, frontend) is different in
every repository, and “install into frontend for all seven” is a question
without an answer. For a folder inside a project there is that project's dialog.
No “here / global / storage” groups. Across several folders they do not exist. Instead every row carries a count of how many of the selected projects already have it, and the sort puts what is missing on top: this screen is opened to fill gaps.
“Apply profiles” is not rolling one thing out to everyone. Every project is brought to its own profile from its own repository. There is no shared plan: this is how you catch up with what was already agreed in each repository separately.
Removing asks for confirmation and names the projects: files are deleted from disk, while the entries in onplate's storage stay.
Comparing two projects
Tick exactly two projects and “Compare” appears in the bar. This answers the most common question in AI-context debugging: “why does the agent cope here but not in the repository next door”.
The header holds both sides: how many resources, how many instruction files, how many tokens are always in context, and how many items need attention. Below is a row-by-row comparison of resources and instruction files. Only differences are shown by default; matches unfold with one button.
A row is a kind plus a name, not an install: a single skill has as many installs as it has AI tools, and a person asks “is it there”, not “how many times”. Of several installs the worst status wins — “broken somewhere” is the answer.
There are four kinds of difference, and each is named in words:
- installed into different AI tools;
- different versions;
- something is wrong with the install on one side;
- noticeably different weight in context — the threshold is 200 tokens: two
living
CLAUDE.mdfiles almost never match byte for byte, and flagging a ten-token gap as a difference would drown the screen in rows that explain nothing.
Instruction files are compared by their path from the project root: absolute paths differ between two projects by definition.
Global resources are left out of the comparison — they are identical for any two projects on this machine, and a “both have it” row about them would be noise. That is also why the token count covers only the project scope and the instructions; the screen says so directly.
Where the work happened
The bottom block of the screen lays the local AI logs out across every remembered project at once. The period is 7 days, 30 days or all time.
For each project: how many sessions and turns, a breakdown by tool, and the last five sessions by name and date. Projects with no work in the period are not dropped but collected into a collapsed row — “untouched” is an answer too.
Sessions that ran in folders onplate does not know are named separately: usually those folders are worth adding as projects.
The sum over projects can exceed the total: a session that walked two remembered roots honestly counts for both, and hiding it from one of them would be untrue.
The logs are read locally, and conversation content is never stored.
The project header
The header does not change between tabs and answers the question “where am I”:
- folder name, Git branch and the AI tools involved in project installs;
- the “Why” line — what this section shows in the first place;
- the full path and Git remote: long values are shortened, the full one is in the tooltip or copied with a button of its own;
- when the project snapshot was taken — and a note if the folder changed after it.
To the right of the tabs are the actions available from any tab:
- “How to open the project” — open the folder in an editor (in the current or a new window), in a terminal, in Finder, or start a session in an installed AI tool. The chosen way is remembered and becomes the main button for this project; applications that were not found are marked “not found” rather than hidden.
- re-read the whole project;
- Install into project;
- a menu with favourite and archive;
- Forget.
Resource counters do not live in the header — they belong to one tab and stand on it, so that a number and the rows it counted are next to each other.
Four tabs
The project page is split into tabs because it answers four different questions. The selected tab is remembered per project: you come back to where you were, including after restarting the app.
| Tab | Answers | What is inside |
|---|---|---|
| Overview | is everything fine, and what is this code | AI setup, the context of each tool, changes, composition and stack, Git, the profile |
| Resources | what the AI gets and where it came from | counters, search and filters, three groups by origin, the map of relations |
| Instructions | what the agent reads before skills | CLAUDE.md, AGENTS.md, their breakdown and editing |
| Sessions | where and with what you worked, and what fired | local agent sessions and resource usage |
Tabs are keyboard-operable: arrows, Home and End inside the row.
Overview
Sections with nothing to say are collapsed into a single row with a summary: “the tracked project state has not changed”, “in sync with the profile”, “Git is not available on this machine”. The answer is readable without opening anything, and the screen does not turn into a form of identical empty cards. A section that failed or is still loading never collapses — that one does have something to say.
Project AI setup
The top block gathers everything that keeps the setup from being consistent, and gives each problem a concrete next action — “Check again”, “Open folder”, “Create profile”, “Review the profile”, “Review local setup”, “Review usage”.
| State | What it means |
|---|---|
| Synced | the folder, profile and AI deployments agree |
| Needs action | there is something to review |
| Blocked | the folder is unavailable, the profile does not parse, or a conflict was found |
This is a task list, not a good/bad indicator. “Needs action” is the normal state of a living project, not an error. When there are no tasks, the block does not show an empty list: it says the folder, profile and installs agree.
A separate row appears when a resource was not used in 30 days. It also names the price of that: how many tokens of persistent context the set occupies in every agent run. The button next to it leads to the Sessions tab, where you can see where that number came from.
Below the tasks are optional suggestions, and each is backed by this project's own data rather than general advice: pin down a global resource whose invocations are recorded here, look into a resource that fired but is not among the installs, write an instruction file when there are resources but no rules for them.
How much context each AI receives
The block answers “what actually reaches the model in this folder” — separately for every AI tool, switched by tabs.
Inside the selected tool there are three groups: instructions, project
resources and global resources. Every row carries its source and its price
in tokens; instruction files also carry how many files their @-imports pull in
and how many references are broken.
An instruction file's name is clickable and opens the file right here, without
taking you off the Overview. It opens the same view as the Instructions tab:
the text, its mentions, its @-imports and editing.
The two numbers in the tool's header are kept apart on purpose: always in context is what is spent on every request, and maximum on activation is what is added only if the resource fires. Adding them into one number would frighten you with a total that never happens.
If the project has a profile, every row is compared against it: a green “in profile”, a yellow “only local” for a project resource and “not in project profile” for a global one. Above the list is a summary — “project resources in profile · outside · need action”. Global resources are not in it: a project profile does not require them by design, not by oversight.
Project changes
The block answers “what happened here since I last looked”. Instructions, resources, the profile, Git, project parts and local AI sessions all count.
You set the baseline yourself with “Start tracking” — merely opening the page does not mark future changes as reviewed. After that every change is named: what it is (an instruction, a skill, an MCP server, a subagent, the profile, a branch, a project part, an AI session), whether it was added, changed or removed, which scope it belongs to and how many tokens it cost. “Mark reviewed” covers the whole list, not only the rows on screen.
The number of unreviewed changes is visible in the sidebar next to the project — that counter is what brings you here.
What this project is
The block answers two questions at once: what the project consists of and what it is written in.
Each part is a row: path from the root, branch (if the part has its own repository), stack facts and commands to start it. Below that — what actually works in this part.
Facts come with evidence. Every chip — language, framework, image, service, port — carries the file and line it was taken from in its tooltip. This is not pedantry: someone who catches onplate inventing a fact about their own code will rightly stop trusting its security verdicts too. For the same reason there is no “probably” here: what onplate does not know is simply absent — and if nothing was found at all, it says so.
Environment variables are not listed by name — there can be dozens. A counter is shown instead, with the evidence on it.
How to start it. Commands are collected from docker-compose.yml, Makefile,
package scripts and only then README — in that order of reliability. Each one is
labelled with its purpose (run, tests, setup) and the file it came
from.
Disagreements are not resolved for you: if the Makefile says one thing and the
README another, both commands are shown. Often that is the most useful fact of
all — the README is out of date.
A command can be copied. There is no “run” button here, and there will not
be. onplate does not even run the installer of its own runner: curl … | sh is
execution of downloaded code, and running someone else's while flagging the same
thing in others with our own scanner would be doublethink. If a command looks
risky, it is marked “the scanner is wary” or “the scanner says no”.
What works in this part. Under the facts are the skills and subagents found in this folder, each answering three questions:
- where it came from — “installed by onplate” or “sits here” (arrived with the code);
- whether it worked — invocations over 30 days, or “never in 30 days”;
- whether it is mentioned in
CLAUDE.mdorAGENTS.md.
“Never in 30 days” next to a skill written specifically for this code is the most useful thing to show here: either its description does not catch the agent, or the skill is dead.
A foreign skill can be adopted into storage — onplate copies it over so you can use it like any other. The files in the project stay where they are: only what onplate knows about them changes.
Re-reading. The composition is recalculated on its own: clone another
repository next door, switch a branch, edit docker-compose.yml — the block
changes without a single click. The “Re-read project” button stays for when
you do not feel like waiting.
Git context
The local state of the repository, as far as it concerns the AI setup and the profile: how much is uncommitted (or “all committed”), whether there are conflicts, how far the branch is ahead or behind, whether the profile was changed locally, the linked worktrees, and the profile's history in commits.
onplate never fetches and never changes the repository. If Git is not found on the machine, the block says so — and collapses into one row, because it has nothing else to say.
The project profile and this machine
The block is deliberately split into two directions, because these are two different decisions.
Install settings from the profile — apply what the team agreed on. Before touching files onplate shows a plan: what it will install, what it will update, where a conflict is. Nothing changes until the plan is confirmed. If there is nothing to install, the block says exactly that: this machine already has everything from the profile.
Add local settings to the profile — offer the team what already works for you. The usual first step: a personal setup becomes a shared one. While there is no profile, the button is called Create profile.
Profiles of parts. In a workspace folder with several clones there is more
than one profile. Instead of this block you get “Profiles of parts”: every
repository has its own .onplate/profile.json, because that is where it gets
committed — next to its code.
onplate offers to write a profile only where it can be sent as a pull request; a
folder without its own repository is no place for one, and onplate explains why
it does not offer. In a monorepo there is still one profile, but its entries can
name parts: the migrations skill goes to backend, not to the root.
Details of both directions are in the project profile.
Resources
What AI receives in this folder
The list is everything that actually reaches the AI: what onplate installed, what arrived with the code, and what is global to the tool. One resource available to several AI tools is one row.
It is laid out by origin, in three groups:
| Group | What it is |
|---|---|
| Installed through onplate | entries onplate knows: they can be updated, replaced and removed |
| Arrived with the code | sits inside the project folder but was not installed by onplate; the AI reads it just the same |
| Shared by the AI tool | lives in the tool's home directory and applies to every project opened through it |
The middle group used to be shown nowhere, although in an ordinary project it is almost all of the content. A foreign find in it can be adopted — the file stays where it is, only what onplate knows about it changes.
The difference between the two install scopes is the main thing worth understanding in this section:
| Project resource | Global resource | |
|---|---|---|
| Where it is visible | in this folder only | in every project of the chosen AI |
| Who decides | you or the project profile | you, once |
| Does it travel to the repo | yes, if included in the profile | no, unless you pick it explicitly |
A Go review skill belongs in the backend service repository only. A skill about your personal commit style belongs globally: you need it everywhere and the team does not need it at all.
Counters, search and filters
At the top of the tab are numbers by kind: skills, MCP, subagents, other and attention. Every number is clickable and turns into a filter for that kind: a counter with no way to reach the rows it counted does not answer the question “which ones exactly?” — it raises it. Next to them is a search over name and folder.
Everything the AI gets here is counted — all three origins at once. The filter row only offers kinds the project actually has; “attention” appears only when there is something to attend to.
If the calculation failed, the counters stay silent: “0 skills” is the same kind of answer as an empty list, and the same kind of lie when something broke.
Install into project
The button in the header (and “install here” on every part) opens installation from storage straight into this folder. The questions come in the order a person actually thinks in — “this project needs migrations and postgres for the agent”, not “which project should this skill go into”.
Where. The parts are listed as buttons, each with how many times the agent was started in it. There is a root option and another folder… for a subfolder onplate does not treat as a part.
Who for. The AI tools found in this folder. If an .agents folder is
already there, it shows up as a separate row: Codex and Cursor both read it — one
copy instead of two. Claude Code does not, which is exactly why onplate calls it a
folder rather than a tool. onplate never creates that folder itself: offering a
place that does not exist would be an invitation to invent one.
Cursor comes with a warning of its own, and it was measured rather than read off
the docs: Cursor reads the project’s foreign directories — .claude, .codex,
.agents — before its own .cursor. If a skill of the same name already
sits in one of them, the copy in .cursor lands on disk but never reaches the
model. onplate says so before the install, not after.
What. One list of skills, MCP servers and subagents in three groups: already
here, installed globally — the agent sees it here too, everything else. Rows
say where a resource already stands (“in this project it stands in: backend”)
and where it can go at all, when a tool has no such place inside a project.
Two things are visible before anything is written: what will appear on disk (the full path of every entry) and how many tokens it adds to the context of every agent run. Nothing is written until you press Install.
What may fail to install and why is stated plainly: the AI has no such place inside a project, the scanner says no (confirmation required), the target folder holds foreign files (then install from Storage — it asks what to do with them).
At the bottom: “write into the project profile” — so the team gets the same.
The warning about the launch directory. Sometimes a warning appears next to
the folder you picked: the agent is started not from here but from another part of
the project. This matters because skills are read relative to the directory the
agent starts in: what you put into frontend will not be picked up when the
agent starts in backend.
The warning shows up only when there is something to compare against — some part of the project collected invocations over 30 days and the chosen one did not. It names that part and offers to switch to it in one click. If there is no launch history at all, onplate stays silent: there would be nothing to say.
Installing into a “quiet” folder is a legitimate choice — it may be prepared in advance. The warning only says the skill will be read when the agent starts from that folder.
How resources reach this project
The bottom block of the tab answers a question nothing else does: why is this skill available to the agent here at all. There are four reasons, and they are named explicitly:
- installed into the project folder — it sits inside this folder;
- available through AI — a global resource, visible in every project of the tool;
- named by instructions —
CLAUDE.mdmentions it by name or pulls it in with an@-import; - delivered by a package — it was installed together with others, not on its own.
The summary above the list names the numbers: how many instruction files were checked, how many resources are project-scoped and how many global, how many direct references there are and how many of them are broken. A broken reference is that same mention pointing at nothing, seen from the resource's side rather than the file's.
What this does not mean. This is a map of availability and declared links, not an invocation log. It does not claim that one resource starts another. Actual invocations are counted in exactly one place — “Resource usage” on the Sessions tab — and the block points there with a single line and a number instead of repeating the same table under a different heading.
If instruction files could not be read, onplate names how many — rather than pretending there are no relations.
Instructions
CLAUDE.md and AGENTS.md are the third place where the agent's context lives,
alongside skills and MCP. The agent reads them before any skill. onplate
finds these files both in the project root and in its parts, and shows for each:
how many resources are mentioned, how many references point at nothing, how many
files are pulled into context by @-imports, and how many blocks onplate itself
wrote there when installing packages.
The file opens right there — as rendered text or as source. Next to it, the breakdown:
| What you see | Why |
|---|---|
| mentioned skills and subagents with their state | “sits in the project”, “sits in backend”, “global”, “in the catalog but not installed”, “found nowhere” |
| invocations of each mention | mentioned in the instructions and never fired — a reason to rewrite the description |
@-imports and their size | these files spend tokens every session, and they are visible only here |
| onplate blocks | that piece of text was written by a package install, not by you |
The file can be edited right here — “Edit”, then “Save”. The edit goes into that same project file the agent reads; onplate keeps no copy of it. When there are no instruction files yet, “Create an instruction file” offers a name and says which tools read it. The file appears in the project only once you save it.
The quietest breakage, the one this was built for: the instructions point at a skill that does not exist. The agent will read it, not find it, and invent its own. Such mentions are marked both in the text and in the list.
The “personal” badge means a file like CLAUDE.local.md: it is usually in
.gitignore, so a colleague on the same repository will not have it.
An empty tab is a normal state, and onplate says so: there may be no instruction files at all, and project and global resources will keep working anyway.
onplate stores none of this: the file is read from disk on every view. A copy would become a second source of truth about text you edit in your own editor every day.
Sessions
Project sessions
The local sessions of coding agents whose working directory belongs to this project. Supported tools appear on their own once their local history is available.
A session shows its title, the tool, the date, the model, the number of turns and
which resources were verifiably invoked in it — including what the invocation
is confirmed by (a Skill or Task call recorded by Claude Code, a SKILL.md opened
by Codex from a known skill directory, a skill call recorded by OpenCode).
What you can do with a session:
- Continue — open it in the same CLI. If the CLI is not found on this machine, onplate says so instead of hiding the button;
- start a new session in any installed tool, straight from the project;
- associate a session that started from another folder, or, the other way round, say that a session does not belong to this project. Both decisions stay on this machine only.
The list is filtered by tool, by period (7 days, 30 days, all time) and by a search over titles.
A session is associated automatically only when its stored working directory is this project or one of its parts; onplate says for each one how it was associated. Titles, identifiers, paths, dates, models and counters are read — never prompts or replies.
Resource usage
The second block of the tab answers “which of the installed things actually worked”. onplate reads the local logs for the last 30 days and shows: the number of skill and subagent invocations, the active resources, the last invocation and in which tool. Next to it — the profile cost in tokens: what the set costs on every request.
Three honest limits:
- conversation text is never stored — only metadata is counted;
- MCP calls are not guessed: when the source does not allow identifying them reliably, statistics leave them out;
- zero activity does not mean “not installed”. If no supported logs were found, onplate says so in a separate message rather than showing a zero. If part of the history could not be read, it notes that too.
This is the only place where actual invocations are counted. The map of relations on the Resources tab answers a different question — what is available to the agent and why.
A team example
Alice set the project up locally: installed the go-review skill, a database MCP
server and a subagent for tests. Then she added them to the project profile and
sent the .onplate folder as an ordinary pull request.
Bob got the changes, opened the same repository in onplate and pressed “Review what to install” on the Overview tab. Before applying he saw the exact list of installs, and entered his own secrets for the MCP server separately.
The result: both have the same reproducible project setup, while their personal global skills stayed personal.
When something goes wrong
The project folder is unavailable. It was moved, renamed, or an external drive was disconnected. Put the folder back at its old path, or forget the entry and add the project again at its new one.
The profile does not parse. The file is damaged, holds unsupported values, or was created by a newer version of onplate. Check the file's changes in Git; if it is a version issue — update onplate first.
The profile has unapplied changes. Open Overview, press “Review what to install”, review the plan and apply the entries you want. Nothing changes before the plan is confirmed. In a workspace folder with several clones the same button is called “Prepare” and stands next to each part.
A local resource is missing from the profile. Press “Review local setup”, tick the resource and write the updated profile.
A global resource did not appear. It is not installed globally into any AI. Open Storage, install it for all projects of the tool you need, and refresh the project page.
Nothing is said about the project. No familiar markers were found in the folder. onplate names a stack only when it can show the file and line it took it from; there is no guessing here.
A skill was skipped: “the folder holds foreign files”. Something unrelated already sits in the destination folder. Install that skill from Storage — it asks what to do with such files.
No relations, although resources are installed. Check that this is the right project: the map of relations is built from the project folder and the instruction files in it. If those files cannot be read, onplate says how many it failed to read.
No sessions, although the work did happen. A session is associated by its stored working directory. If the agent started from another folder, associate the session by hand in the “Other local sessions” list — or look at “Where the work happened” on the projects overview: sessions in unknown folders are named there separately.
onplate suggests adding the folders separately. You added a directory that holds independent repositories. That is not a project but a shelf of projects: one profile and one card would describe all of them at once.
FAQ
Where do I install a skill in a monorepo? Into the part you start the agent from: skills are read relative to the launch directory. onplate shows invocations next to every part and warns you if the folder you picked is not that one.
What do the counters on the Resources tab count? Everything the AI gets in this folder: onplate installs, what arrived with the code, and what is global to the tool. Below the counters those three origins are split into groups, so it is clear where each number came from.
How is “Resource usage” different from the map of relations? Usage is a log of what was actually invoked. The map of relations lists what is available to the agent and why. A resource can be connected three ways and never fire once — that combination is exactly what to look for.
Can I install a skill into several projects at once? Yes: “All projects” → tick the ones you need → “Install…”. The resources land in the root of each; a folder inside a project is chosen in that project's own dialog.
Why are global resources missing from the project comparison? They are identical for any two projects on this machine. A “both have it” row explains nothing, so the comparison — and its token count — covers only the project scope and the instructions.
Is the selected tab remembered? Yes, per project, and it survives an app restart.
Does onplate run the commands from the README? No. They can only be copied.
Does onplate store my CLAUDE.md? No. The file is read from disk on every
view, no copy is kept. Editing from the Instructions tab writes into that same
project file.
Do I need a profile for a personal project? No. You can just add the folder and use project installs. A profile matters when the setup has to be reproducible, reviewable in Git, or handed to other people.
How is a project profile different from a team profile? A project profile answers “what does this code need” and lives next to the code. A team profile describes a person's role in the company and lives in a separate registry repository.
Will global resources end up in the repository? No, not unless you pick such a resource explicitly when creating or updating the profile.
Does onplate make a Git commit? No. After the profile is written you review the diff, commit and push yourself. The Git context on Overview only reads, too: onplate never fetches.
What does “Forget” do? It removes the project from onplate's list along with your local decisions about its profile. The folder, the profile and the installs stay where they are.