diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..310331f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,65 @@ +# 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/caldav`, its own git remote. It is **not** part of +the platform's repository, and `platform/plugins/caldav` 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. + +Verify the checkout is well-formed with `bun run plugins:check` from the platform repo. + +## What this plugin is, in one paragraph + +Calendars and contacts over CalDAV and CardDAV, backed by Radicale spawned on loopback by its own +sidecar. One sidecar, one permission, **two screens** — `/calendar` and `/contacts` — which makes it the +only plugin using `screens` in its manifest. + +## What must not change without knowing why + +- **`/dav`, `/.well-known/caldav`, `/.well-known/carddav`.** Claimed in `unauthenticatedRootPaths`, served + ABOVE the account gate because phones send HTTP Basic and have nowhere to put a JWT. Reserved names, + claimable only because this is a first-party plugin. +- **`dav_app_passwords`** is not prefixed `caldav_` and the installer warns about it. Deliberate: + installs hold real rows and a naming convention is not worth a data migration. +- **The two screen segments.** They were core routes; bookmarks, dock tiles and persisted layouts all + address them. +- **The panel keys** (`calendar-nav`, `calendar-view`, `contacts-nav`, `contacts-view`). A stored layout + names them. + +## Traps that have already cost time + +- **`sidecar/radicale.ts` generates `radicale.conf` inside a template literal.** A backtick in a comment + there terminates the string and the file stops parsing. No test imports it, so only `bunx tsgo` catches + this. +- **`createSidecarProxy` mounts a catch-all**, so in `api/router.ts` the plugin's own routes must be + registered BEFORE it or they are forwarded to the sidecar and 404. +- **Request bodies are not parsed** on this plugin's routes — the proxy registers the whole prefix with + `registerProxiedPrefix`. Use `jsonBody()` in `api/app-passwords.ts`, not `ctx.get('body')`. +- **`date -u -d` does not convert local time to UTC.** It parses AND prints as UTC. Every event lands an + hour out and nothing errors. See the skill. + +## Verifying + +From the platform repo, because that is where the toolchain is: + +```bash +bunx tsgo # a red typecheck is not done +bun test # 1 known failure: ModelSelector, unrelated +bun run plugins:check +bunx prettier --write +``` + +Changing the sidecar needs `pm2 restart officer-caldav`; changing `api/` or `web/` needs +`pm2 restart officer`. + +## Related + +- `README.md` — what it is and what it claims, for someone installing it +- `skills/calendar-and-contacts/SKILL.md` — how an agent USES the calendar, as opposed to changing it diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..8c36885 --- /dev/null +++ b/CLAUDE.md @@ -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.