Imported from whatsper/texterdocs (
AGENTS.md). Install upstream withnpx skills add whatsper/texterdocs. Copyright stays with the author.
AGENTS.md
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
Project
Public documentation site for Texter — a WhatsApp bot platform configured via YAML. Built with Docusaurus 3, deployed to GitHub Pages at whatsper.github.io/texterdocs by the .github/workflows/deploy-github-pages.yml workflow on push to main (or manual dispatch).
Commands
npm start # dev server at localhost:3000
npm run build # production build -> build/
npm run serve # serve built site
npm run typecheck # tsc (no emit)
npm run clear # clear Docusaurus cache
There is no test suite and no linter configured in package.json. Build failures on broken internal links are enforced (onBrokenLinks: 'throw' in docusaurus.config.ts), so npm run build is the closest thing to a lint step — always run it before declaring docs work done.
Architecture
Content lives in three places
- docs/ — the YAML bot documentation, auto-sidebar-generated (
tutorialSidebaruses{type: 'autogenerated'}in sidebars.ts). Structure underdocs/YAML/mirrors the bot's config surface:Adapters/(CRM integrations),Types/(Func,Notify,Prompt,WhatsApp Flow),Data Injection/, plus top-levelOverview.mdandBot Configuration.md. Folder order is controlled by_category_.jsonfiles. - blog/ — served as
/changelog(routeBasePath overridden in docusaurus.config.ts). Files useYYYY-MM-DD-slug.md. Only user-visible changes belong here; internal tooling/refactors do not. - src/data/scenarios.ts — single source of truth for the Scenario Marketplace rendered at
/scenarios(src/pages/scenarios.tsx). EachScenariohasid,tags,triggerEvents,configuration[], and a fulljsonobject used as a copy-pasteable YAML/JSON example.TRIGGER_DISPLAYandACTION_DISPLAYmaps at the top of the file define the human-readable labels — any new trigger/action type must be added there.
_context/ is reference-only, not shipped
_context/code/adapters/ contains the actual TypeScript source of the bot's CRM adapters (copied from the bot repo). This is the ground truth when writing or updating adapter docs under docs/YAML/Adapters/ — the doc page should match what the code actually does. _context/ is not imported by the site and not deployed.
React customizations
- src/pages/index.tsx, src/pages/scenarios.tsx — custom landing and scenario marketplace pages.
- src/components/AIChat/ — "Ask AI" right-docked chat panel. POSTs to an n8n webhook (
AI_CHAT_WEBHOOK_URL→customFields.aiChatWebhookUrl) and consumes an SSE stream. OpenAI Responses API thread continuity viaprevious_response_idstored insessionStorage. Contract: _context/N8N-CHAT-WEBHOOK-CONTRACT.md. - src/components/GiscusComments/ — Giscus embed; configured via
GISCUS_*env vars, setup notes in _context/GISCUS-SETUP.md. - src/theme/ — Docusaurus swizzled components. Prefer editing existing swizzles over creating new ones.
- Analytics via
posthog-docusaurus, search via@easyops-cn/docusaurus-search-local(indexes both/docsand/changelog), Mermaid diagrams enabled.
RAG build-time sync
scripts/build-rag.mjs runs in prebuild. It walks docs/ + src/data/scenarios.ts, chunks on ## headings, content-hashes each chunk, and incrementally upserts (or deletes) rows in Supabase public.doc_chunks (schema: supabase/migrations/0001_doc_chunks.sql). Embeddings use text-embedding-3-small (1536 dim). The script skips cleanly unless SUPABASE_URL + SUPABASE_SECRET_KEY are set along with either OPENAI_API_KEY (direct) or EMBED_WEBHOOK_URL + EMBED_WEBHOOK_SECRET (route through the n8n "Texterdocs - Embeddings Proxy" workflow), so local npm run build without secrets still works. A .rag-cache.json file (gitignored, CI-cached via actions/cache) maps chunkId → content_hash to avoid re-embedding unchanged chunks.
Working with docs
- Adapter pages under
docs/YAML/Adapters/<Name>/must be cross-checked against the adapter's source at_context/code/adapters/<name>.ts. Use theadd-adapterskill to scaffold new ones. - Scenarios — use the
add-scenarioskill; it enforces that new trigger/action types get registered in the*_DISPLAYmaps and that the embeddedjsonis valid and references only documented types.validate-scenariosskill lints the file before build. - Blog/changelog posts cover only user-facing changes. Draft with the
changelogskill, which summarizes commits since the last post in the project's established format. - Before shipping, the
releaseskill runs the full checklist (typecheck, build, validate-scenarios, check-docs, preview screenshots) and prepares a GitHub Actions deploy dispatch. It does not actually deploy without confirmation. - Other docs skills:
check-docs(frontmatter/link lint),polish(prose suggestions),preview(screenshot key pages),cleanup(dead files/exports). - Changing chunker rules (heading split,
MAX_CHUNK_CHARS) or the embedding model in scripts/build-rag.mjs → bumpCHUNKER_VERSIONso allcontent_hashvalues invalidate and the next build re-embeds everything intentionally.
Conventions
- Docs files may contain spaces in their filenames (e.g.
Bot Configuration.md). Docusaurus handles the URLs; keep spaces when they exist to avoid breaking links. - The site uses
trailingSlash: false; hand-written internal links should match. - A client-side redirect is registered for the renamed
Split→Bot State Splitpage — follow the same pattern inplugin-client-redirectsconfig when moving any doc page that may be linked externally. - Keep changes scoped: a docs fix is a docs fix. Don't sweep
_category_.jsonsidebar orderings into unrelated commits.
