GramIO is a TypeScript Telegram bot framework for Bun, Node.js, and Deno. This repository is the VitePress documentation site at gramio.dev. All documentation is bilingual (English + Russian).
bun run dev # Start VitePress dev server
bun run build # Production build — must pass after any change
bun run preview # Preview the build locallyAfter making changes, always run bun run build to verify the site compiles successfully.
- For every markdown file in
docs/, ensure there is a corresponding file indocs/ru/with the same relative path and filename. - When a file is added, changed, renamed, or deleted in
docs/, mirror the change indocs/ru/. - If a translation is missing in
docs/ru/, automatically translate the English page to Russian and create the full Russian version. - When a file is changed in
docs/ru/, check ifdocs/has the same relative path. If so, suggest updating the English version if the Russian file is newer. - Subdirectories and their contents should be mirrored between
docs/anddocs/ru/. - Directory structure changes (create, rename, delete) in
docs/should be reflected indocs/ru/. - This rule set is bi-directional, but prioritizes English (
docs/) as the source of truth. - Exclude double translation (do not translate
docs/ru/back intodocs/ru/). - You can check updates via
Recent changes. - Correct grammatical punctuation and other errors in both: original and other language modified files.
docs/plugins/official/scenes.md↔docs/ru/plugins/official/scenes.mddocs/index.md↔docs/ru/index.mddocs/guides/usage.md↔docs/ru/guides/usage.md
The skills/gramio/ directory distills English documentation into concise, code-heavy references for AI consumption. Keep them in sync:
- When a documentation page in
docs/is added or substantially updated, check if the corresponding skill file inskills/gramio/references/orskills/gramio/plugins/needs updating. - When a new doc page covers a topic not yet in the skill, create a new reference file (YAML frontmatter with
nameanddescription, H1 heading, code-heavy sections, HTML source comment at bottom). - When a new runnable pattern emerges, add an example in
skills/gramio/examples/(complete TypeScript, full imports, no partial snippets). - After any skill content change, update
skills/gramio/SKILL.mdtables and bumpskills/gramio/metadata.jsonversion. - English documentation (
docs/) is the source of truth — skills condense it, they don't replace it.
Verification is mandatory, not optional. Any change under skills/ MUST pass both gates before handoff:
bun run check:skills— strict TypeScript typecheck for everyskills/examples/*.ts.bun run test:skills— runtime behavior check via@gramio/test; each example has a matching file intests/examples/.
When adding a new skills/examples/*.ts, also add tests/examples/<name>.test.ts and export { bot } from the example. When a test fails, fix the example — the test represents what users will actually see at runtime. CI (.github/workflows/skills.yml) enforces both gates on every push/PR that touches skills/** or tests/**.
- Code blocks may use
```ts twoslashfor inline type hints powered by Shiki Twoslash. - Never delete
// ^?— these markers generate inline type hover annotations. - Twoslash annotations must be preserved exactly during translation.
Installation examples must use VitePress code groups with all four package managers:
::: code-group
\`\`\`bash [npm]
npm install @gramio/package-name
\`\`\`
\`\`\`bash [yarn]
yarn add @gramio/package-name
\`\`\`
\`\`\`bash [pnpm]
pnpm add @gramio/package-name
\`\`\`
\`\`\`bash [bun]
bun install @gramio/package-name
\`\`\`
:::When showing GramIO code, prefer complete runnable snippets that import from gramio:
import { Bot } from "gramio";
const bot = new Bot("TOKEN");
// example code here
bot.start();Every documentation page must include YAML frontmatter with:
---
title: Page Title for GramIO
head:
- - meta
- name: "description"
content: "Concise description of the page content for SEO."
- - meta
- name: "keywords"
content: "comma, separated, keywords, gramio, telegram bot"
---title— used in browser tabs and SEO.descriptionmeta — concise summary for search engines.keywordsmeta — relevant keywords including "gramio" and "telegram bot".
Official plugin pages follow this structure:
- Frontmatter (title, description, keywords)
- H1 heading — plugin name
- Badges — npm, JSR, JSR score in a
<div class="badges">wrapper - Short description paragraph
- Installation —
::: code-groupwith npm/yarn/pnpm/bun - Usage — code example with
twoslashwhere appropriate - Configuration / Options — if applicable
- Additional examples — advanced usage patterns
- English assets go under
public/(e.g.,public/keyboards/example.png). - Russian counterparts go under
public/ru/with identical relative paths (e.g.,public/ru/keyboards/example.png). - Reference in docs as
/keyboards/example.png(EN) and/ru/keyboards/example.png(RU).
docs/ # English docs (source of truth)
.vitepress/
config.mts # Main VitePress config
config/locales/
en.locale.ts # EN sidebar & nav
ru.locale.ts # RU sidebar & nav
guides/ # User guides
plugins/official/ # Official plugin docs
ru/ # Russian translations (mirrors docs/)
public/ # EN static assets
ru/ # RU static assets
When adding a new page, it must be registered in both sidebar configs:
docs/.vitepress/config/locales/en.locale.tsdocs/.vitepress/config/locales/ru.locale.ts
Follow the existing patterns for section grouping and link formatting.
public/_redirects is a Netlify-specific redirect file (GitHub Pages does not support it). It must be kept up to date whenever doc files are moved or renamed.
- When a page is renamed or moved (e.g.,
docs/guides/foo.md→docs/guides/bar.md), add a redirect:/guides/foo /guides/bar 301! - When a page is deleted without a replacement, redirect to the closest relevant page.
- When a section index is added (e.g.,
overview.md), add a redirect from the bare section path:/section /section/overview 302! - Both EN and RU paths may need separate redirect entries (e.g.,
/ru/guides/foo→/ru/guides/bar). - Use
301!for permanent moves,302!for section index redirects.