AGENTS.md · trycompai/crm
AGENTS.md from trycompai/crm: 271 lines covering Always true, Report every issue.
Template by trycompai
Install
Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/trycompai/crm/release/AGENTS.md -o AGENTS.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: prompt-engineering
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.
- For
- Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
- Length
- 271 lines
- File
AGENTS.md
Sections
- Always true
- Report every issue. Use ASD-STE100
- A server page computes. A client component renders.
- Constants belong in one file per area, not beside their first use
- Parse at the boundary, never pass Record<string, unknown> around
- Design
- Commit Messages & Pull Requests
First lines (shown under the repo's MIT license)
# Strict rules — review before starting any work
**Read the doc for the area you are touching before you touch it.** The table
below is the whole index. These are plain paths, not imports: they are not in your
context until you read them, and the rules in them are not optional.
| Working on | Read first |
| --- | --- |
| Anything in `apps/api` — tRPC, auth, logging, sync, deletes, caching | `docs/api.md` |
| `apps/agent` — the eve research agent, tools, tasks, dispatch | `docs/agent.md` |
| `.env`, configuration, which variables exist and why | `docs/environment.md` |
| UI in `apps/app` or `packages/ui` | `docs/design.md` (below) |
| Deal amounts, totals, charts, exchange rates | `docs/currency.md` |
| The record sheet's Agent tab | `docs/agent-panel.md` |
| `/settings/connections`, integrations, the intake endpoint | `docs/connections.md` |
| The tracking script, the collector, form submissions | `docs/tracking.md` |
| Running it locally, Google Cloud, DB commands, secrets | `docs/setup.md` |
| Anything that sends a telemetry event, or a new property on one | `docs/telemetry.md` |
| `.github/workflows`, versions, changelog, how a change reaches `release` | `CONTRIBUTING.md` |
Also check `.agents/skills/` for a relevant skill before starting — better-auth,
prisma, nestjs-trpc, eve, shadcn, nuqs and others have one. Tell the user which
rules and skills you read.
## Always true
- **Never add code comments.** Not to new code, not to code you edit.
- **No coauthoring commits.** No `Co-Authored-By` trailer, ever.
- **Intelligence lives in `apps/agent`, never in the API.** No vendor client, no
enrichment, no scoring, no identity matching in Nest — it writes an `AgentTask`
row and lets the agent decide. See `docs/api.md`.
- **One `.env`, at the repo root.** `.env.example` is its documentation: add every
new variable there with a note on what it does, and declare it in
`apps/api/src/config/env.validation.ts` if the API reads it. Never add a
per-package `.env`.
- **Anything a self-hoster might not have is optional and must never throw.** A
missing key removes a capability. `apps/agent/agent/lib/capabilities.ts` is the
pattern.
- **`/packages/ui` is the single source of truth for UI.** Shared shadcn
components only; a new variant is implemented there, not overridden at the call
site.
- **eve's own docs ship in `apps/agent/node_modules/eve/docs`** and match the
installed version. Read the relevant guide before writing eve code rather than
working from memory — guessing typechecks, builds, and then behaves differently.
## Report every issue. Use ASD-STE100
Do not bury a known problem inside a paragraph. A problem inside prose is a
problem nobody reads. Report **every** issue, including ones you caused, in a
list at the end of your reply.
Write every message, every report and every issue in **ASD-STE100**
(Simplified Technical English):
- One idea per sentence. Maximum 20 words.
- Active voice. Present tense. No conditionals.
- One word for one meaning. Do not use synonyms for variety.
- Say the effect, not only the cause.
- No hedging: never "may", "might", "possibly", "somewhat".
Use exactly this shape:
```
## Issues
1. BROKEN — Slack is not connected. Agents that post to Slack fail.
Fix: connect Slack in Settings → Connections.
2. RISK — A run longer than 5 minutes is cancelled. Work is lost.
Fix: not done. Needs a separate execution lease.
3. NOT DONE — The manual run button shows on event-only agents.
```
Rules for the list:
- One line for the problem. One line for the fix.
- Start each with **BROKEN**, **RISK**, **NOT DONE**, or **UNKNOWN**.
- **BROKEN** is failing now. **RISK** fails later. **NOT DONE** is unbuilt.
**UNKNOWN** is not investigated.
- If you introduced it, write **I caused this** on the fix line.
- Zero issues? Write `## Issues` then `None.`
**Don't** — bury it in prose:
> The fix works well. One honest limit: abandoning a sweep unblocks the queue but
> doesn't cancel the underlying hung promise, so it leaks until restart.
**Do** — put it in the list:
> 1. RISK — An abandoned sweep leaks its promise. Memory grows until restart.
> Fix: not done. Needs cancellation in `receive()`. I caused this.
## A server page computes. A client component renders.
A client component must never import a server package. `@crm/auth` and `@crm/db`
are server packages: their barrels reach Prisma, which reaches `pg`, which
reaches `dns`. The bundler follows that chain into the browser and the build
fails with `Module not found: Can't resolve 'dns'`.
The import trace is the whole error. Read it from the bottom: the last line is
the page, the line above is the client component that leaked, and the top is the
Node module that cannot exist in a browser.
**Don't** — a client component reaching for a server package:
```tsx
"use client";
import {
describeSlackScopes,
SLACK_SCOPE_GROUPS,
} from "@crm/auth/slack-scopes";
export function SlackScopeGroups({ scopes }: { scopes: string[] }) {
const groups = SLACK_SCOPE_GROUPS.map(...)
}
```
**Do** — the page does the work and hands over plain data:
```tsx
// page.tsx — server
import {
describeSlackScopes,
SLACK_SCOPE_GROUPS,
} from "@crm/auth/slack-scopes";
const groups = groupScopes(status.scopes);
return <SlackScopeGroups groups={groups} />;
```
```tsx
// slack-scope-groups.tsx — client
"use client";
export type ScopeGroup = { id: string; label: string; scopes: ScopeLine[] };
export function SlackScopeGroups({ groups }: { groups: ScopeGroup[] }) { … }
```
Rules that follow:
- The client component owns its own prop types. It does not re-export a server
type to get them.
- Anything interactive — an accordion, a dialog, a search field — is a client
component that receives finished data. It never derives it.
- A `"use client"` file may import from `@crm/ui`, the tRPC client, and React.
Anything else needs checking.
- The server page is where `await` and secrets live. The client file has neither.
## Constants belong in one file per area, not beside their first use
A number that someone will want to tune goes in a named config module for its
area. It does not go at the top of whichever file happened to need it first.
Somebody changing a timeout must not have to know which file to open.
**Don't** — one constant per file, found only by grep:
```ts
// dispatch.ts
const DRAIN_TIMEOUT_MS = 4 * 60_000;
// crm.tsSignals
- Stars
- 11,644
- Forks
- 1,709
- Open issues
- 6
- Last commit (this folder)
- Oct 22, 2026 (7 days ago)
- Last release
- Oct 22, 2026 (7 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/trycompai/crm
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
Cite this page
AGENTS.md · trycompai/crm. Agent Mart. https://agentmart.dev/templates/trycompai-crm-agents-md (last updated 2026-10-24)