AGENTS.md, so both harnesses find the same guidance

opencode discovers AGENTS.md and nothing else; claude code discovers CLAUDE.md.
this repo had neither, so an agent sent to change something here arrived with no
guidance at all under either.

it deliberately does NOT repeat README.md. that file says what the plugin is,
for someone deciding whether to install it. this one answers the other question:
i have to change something in here, what will i break.

the facts in it are read from the repository rather than recalled — the panel
keys from web/panels.ts, the tables from db/schema.ts, the permission keys, the
host binaries and the route claims from manifest.ts. presence is the declaration
everywhere in this system, so the file says what the platform will actually
conclude from these files existing.

CLAUDE.md beside it is a pointer, not a copy: two copies drift and the stale one
is the one somebody reads.
This commit is contained in:
2026-08-27 07:24:08 +00:00
parent af66cc47ed
commit 0892161423
2 changed files with 68 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
# AGENTS.md
Guidance for a coding agent working on **this plugin's own repository**. `CLAUDE.md` beside it only
points here — the two harnesses discover different filenames and one set of instructions has to
reach both.
**This is not what the plugin is.** `README.md` answers that, for a person deciding whether to
install it. This file answers "I have to change something in here — what will I break?"
## Where you are
A plugin repository, cloned into `~/officer-dev/plugins/email`, its own git remote. It is **not**
part of the platform's repository, and `platform/plugins/email` is a different thing — that is
where this plugin gets INSTALLED, by the installer cloning it from gitea. Never edit there; the
next install overwrites it.
Check the checkout with `bun run plugins:check` from the platform repo.
## What it ships
- `api/router.ts` — routes, mounted at `/api/email`
- `sidecar/index.ts` — a process, run by PM2 as `officer-email`
- `db/schema.ts` — tables: `email_accounts`
- `web/` — panels and a layout; the platform renders the screen, not this plugin
- `chat/AGENTS.md` — copied into a chat's working directory as its brief
- `skills/` — read by every agent session, harness-agnostic
Presence is the declaration: the platform decides what this plugin has by what files exist. Adding
`db/schema.ts` gives it tables; deleting `api/router.ts` removes its routes. There is no field to
keep in step.
## What must not change without knowing why
- **Permission key `email`** — stored as the subject of every grant. Renaming one is a data change, not a rename.
- **Panel keys** (`email-list`, `email-reader`, `email-chat`) — a user's stored layout names them.
- **Table names** — they hold real rows on installed machines.
- **`appName`** — the directory name IS the id: route segment, table prefix, sidecar suffix, install key.
## Traps that have already cost time
- **`useClient()` rebuilds its verbs on every render.** Anything putting one in a `useCallback` dependency list gets a new identity every render. This silently disabled every playback report in the Jellyfin player for days; the fix is refs.
- **The reader reads the URL param the PLATFORM passes**, which is `section`, not a name of this plugin's choosing. Asking for the wrong one returns `undefined` and the pane renders its empty state forever — that happened here and looked like a broken reading pane.
- **Snippets are extracted from raw MIME without decoding**, so some read `This is a multi-part message in MIME format.` and others show `m=C3=A1s`. Known, cosmetic, not yet fixed.
## Verifying
From the platform repo, which is where the toolchain lives:
```bash
bunx tsgo # a red typecheck is not done
bun test # 1 known failure: ModelSelector, unrelated
bun run plugins:check
bunx prettier --write <the files you touched>
```
A sidecar change needs `pm2 restart officer-email`; anything in `api/` or `web/` needs
`pm2 restart officer`.
## Related
- `README.md` — what it is and what it claims, for someone installing it
- `skills/` — how an agent USES this, as opposed to changing it
+6
View File
@@ -0,0 +1,6 @@
# CLAUDE.md
**The instructions live in [`AGENTS.md`](AGENTS.md). Read it first — this file only points there.**
Kept separate so agents that look for `AGENTS.md` by convention find the same guidance as those that
look for `CLAUDE.md`, without the two drifting apart.