import type { NotifyEvent, Project } from './events.ts'; export type Forum = { /** The id of the project's supergroup (forum or plain). */ chat: string; /** * The chat's own title, wherever it cannot be derived from the project key: * a product of several repositories (every row sharing that chat carries * the same `title`), and a team forum whose product name is prettier than * its repository key (a FORUM wears the product's own name; a solo chat * wears the repository's). Left out everywhere else, where `chatTitle()` * derives the name from the project. */ title?: string; /** * The "🤖 Ops" tab — robots write here. Absent for a plain chat without * topics (a solo project): the message then goes to the chat itself. */ ops?: number; /** * The "💬 Dev" tab — people. The bot does not write here; the field is * kept for completeness. Optional: an infrastructure forum has no people * and nothing to discuss, and an empty tab would read as a forgotten * setting, not as room to grow into. */ dev?: number; }; /** True when the config did not load: the table is empty and the line is said. */ export declare const routesUnavailable: () => boolean; export declare const ROUTES: Record; /** * The name of a project — THE NAME ITS REPOSITORY CARRIES, character for * character. One project, one name, everywhere: the repository, the folder on * the Mac, the Telegram chat, the `display` field of its row. A task card * once printed four different spellings of four projects at once — that is * the day this rule was set. * * That is why most keys are lowercase and hyphenated (`acme-web`, * `acme-api` are what such repositories are actually called), and a row * spells itself differently only when the repository itself does — then * `display` says so, and `display` is the only place. * * Do not restore a prettified name by hand. To change how a project is * written, rename the REPOSITORY first, then bring `display` and the chat * title to it. * * A product built from SEVERAL repositories gets one row per repository, not * one row for the product: `acme-web` and `acme-api` are two rows that * share one chat. The product's own name lives in `title` on their rows, * because that is the only place a name belongs to a chat rather than to a * repository. * * A Telegram chat title must equal `chatTitle()` below, which is built out * of this table. */ export declare const DISPLAY: Record; /** * The project the package's own service cards are addressed to (a lost event, * a card that broke the standard): the `system` key of the config. Without * it — unset, or naming a project that is not in the table — such a card is * not sent at all; the caller says one line and keeps the exit code 0. */ export declare const systemProject: () => Project | undefined; /** * A solo project's chat is « · Ops»; a team forum is just the name — the * forum already carries its own «Ops»/«Dev» tabs, so the chat's own title * does not need to repeat the word. A chat shared by several repositories of * one product, or a forum whose product name differs from the repo key, * carries the product's name in `title`, and every row sharing that chat * repeats it, so any of them answers with the same title. The real * Telegram chat title and this function must agree: the avatar scripts and the * name-drift check both read it through `notify routes --json`, not by asking * Telegram. */ export declare const chatTitle: (p: Project) => string; export type Target = { chat: string; thread?: number; silent: boolean; }; /** * Where an event goes. Everything goes to its own project's "Ops" tab; a * red one arrives there too, just with sound. * * There is no separate "incidents" topic any more: it made sense while the * forum was shared across all projects. Now every project has its own * group, and an incident is visible in that same feed — there is no reason * to funnel them into one place, and the sound already tells an incident * apart from an ordinary message. */ export declare const targets: (e: NotifyEvent) => Target[];