AGENTS.md
This file provides guidance to agents when working with code in this repository.
Stack
- Node.js + TypeScript, Express 5, run via
tsx(no compile step needed) - Package manager: pnpm (use
pnpmnotnpm) - No test suite exists
Commands
pnpm start # run once with tsx
pnpm dev # run with --watch (hot reload)
pnpm docker # build & push Docker image via build.sh
Architecture
Request flow: src/index.ts → src/controllers/index.ts → posts.ts / users.ts / meta.ts → src/utils/fetch/findPost.ts or findUser.ts → src/utils/renderSeo.ts (returns HTML with OG/Twitter meta tags)
- Controllers redirect to
threads.comon error/not-found (never return 4xx for missing content) HttpErrorfromsrc/utils/utils.tsis the only way to propagate HTTP errors to the global error handler insrc/index.ts- All global interfaces (
ContentProps,DataProps,VideoProps, etc.) are declared insrc/types/application.d.tsas ambient globals — no import needed
Critical Patterns
Auth / Token management
config/users.json(gitignored, copy fromconfig/users.example.json) holds Instagram credentials- Token is cached in-memory and persisted to
generated/token.json(auto-created) login()/refreshToken()insrc/utils/fetch/igLogin.tshandle fallback auth when Threads API returns "Not Logged In" or rate-limit errorsrunningLoginflag prevents concurrent login attempts — do not bypass it
Video proxy
PROXIESenv var is a comma-separated list of proxy hostnames used to serve Instagram video URLsENVIRONMENT=productionswitches the oEmbed base URL fromlocal.milanm.cctofixthreads.net
Rate limiting
src/utils/ratelimit.tswrapsexpress-rate-limitand usesreq.cf_ip(Cloudflare real IP) before falling back toreq.ip- Trust proxy is set to a specific subnet (
192.168.86.0/24) insrc/index.ts— update if deploying elsewhere
Threads post ID encoding
- Post codes (e.g.
CuXX...) are base64-decoded to numeric IDs using a custom alphabet infindPost.ts— do not useatob
TypeScript Config
- Extends
gts/tsconfig-google(Google TypeScript Style) noUnusedLocals,noUnusedParameters,noImplicitAny,strictNullChecksall enabled- Module system:
NodeNext— use.jsextensions in relative imports if adding new files @ts-ignoreis used in a few places for untyped third-party API responses; acceptable pattern