Skip to content

Eradicate hand-rolled 'bicycles' — adopt modern, maintained packages (http framework, duration parsing, …) #40

Description

@kfastov

Philosophy

We keep reinventing utilities (HTTP routing, time parsing, config, retry, locking) that mature, well-maintained packages do better and more safely. Prefer modern, popular, actively-maintained, good-DX packages (the way got superseded request, or mtcute over traditional MTProto libs) over hand-rolled code or old "battle-tested but poor-DX" libs.

We're pre-MVP, so correctness + DX beat 0-dependency flexing — it's too early to optimize for minimal deps at the cost of reliability. Package selection per item via live npm research (see #39 for the template); pin versions; weigh supply-chain but don't fetishize 0-deps right now.

Known "bicycles" (checklist)

  • Raw http servercore/control-server.js (and the manual routing / JSON encode-decode in mcp-server.js) hand-roll method/url checks and body parsing. Adopt a minimal modern HTTP framework (candidates to evaluate: Hono, h3, Fastify). Bonus on a security-sensitive control endpoint: built-in body-size limits, robust parsing, real routing → fewer footguns (resolves the hardening notes flagged on PR feat(server): loopback control API + per-batch progress + idle-exit (#30, PR-2a) #38).
  • Hand-rolled duration parsingcore/duration.js reinvents time parsing (a classic minefield). For human strings like 30s / 5m use a maintained parser (ms, parse-duration). Note: Temporal.Duration parses ISO-8601 (PT30S) and is great for duration arithmetic, but does not parse 30s — so either pick a parser, or standardize on ISO-8601 duration strings. Research current readiness/fit.
  • Config normalization/validation — already tracked in Replace hand-rolled config normalization/validation with a modern schema lib (zod) #39 (zod / valibot).
  • Retry / backoffcore/send-utils.js hand-rolls retry, backoff strategies, and FLOOD_WAIT handling. Evaluate a maintained retry lib (e.g. p-retry, cockatiel) where it fits.
  • File lockingstore-lock.js hand-rolls PID-based lock files (read/write/stale-detection). Evaluate proper-lockfile or similar.
  • JSON state-file IO — repeated manual read/write/0600 patterns (control.json, service-state.json, feedback-last.json). At minimum a tiny shared helper; consider a small lib.
  • Full audit — sweep the rest of the codebase for remaining hand-rolled utilities (date/ISO formatting, ad-hoc parsing, etc.) and append them here.

Process

Note

This is an umbrella/epic. Split items into their own issues when picked up. #39 (config) is the first concrete child.

  • Rename mcp-server.js → a clear name (e.g. server.js / backend.js) and consider collapsing the launcher. The file is a legacy misnomer: it's no longer "just the MCP server" — it's the whole warm backend (control API + realtime/queue worker + the MCP tools as one of several surfaces). Also tgcli server (runServer in cli.js) is a thin launcher that spawns node mcp-server.js as a child — a historical artifact from when this file was the standalone npm start entry; consider merging the launcher into the server (or at least renaming) so the structure reflects "one backend process".

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions