Files
timmy-tower/AGENTS.md
alexpaynex 56eb7bc56e task/34: Testkit self-serve plan + report endpoints
## Routes added to artifacts/api-server/src/routes/testkit.ts

### GET /api/testkit/plan
- Returns TIMMY_TEST_PLAN.md verbatim as text/markdown; charset=utf-8
- Reads file at request time (not on startup) so edits to the plan are picked
  up without server restart
- Path resolves via import.meta.url + dirname() → 4 levels up to project root
  (handles both dev/tsx and compiled dist/routes/ directories)

### GET /api/testkit/report
- Returns only the content from "## Report template" heading to end-of-file
- Content-Type: text/plain; charset=utf-8 — ready to copy and fill in
- Slice is found with indexOf("## Report template"); 500 if marker absent
- Uses the same PLAN_PATH as /api/testkit/plan (single source of truth)

## Deviation: __dirname → import.meta.url
Original plan said "resolve relative to project root regardless of cwd".
The codebase runs as ESM (tsx / ts-node with ESM), so __dirname is not
defined. Fixed by using dirname(fileURLToPath(import.meta.url)) instead —
equivalent semantics, correct in both dev and compiled output.

## AGENTS.md — Testing section added
Three-step workflow documented between "Branch and PR conventions" and
"Stub mode" sections:
  1. curl <BASE>/api/testkit/plan — fetch plan before starting
  2. curl -s <BASE>/api/testkit | bash — run suite after implementing
  3. curl <BASE>/api/testkit/report — fetch report template to fill in

## Unchanged
- GET /api/testkit bash script generation: untouched
- No new test cases or script modifications

## TypeScript: 0 errors. Smoke tests all pass:
  - /api/testkit/plan → 200 text/markdown, full TIMMY_TEST_PLAN.md content
  - /api/testkit/report → 200 text/plain, starts at "## Report template"
  - /api/testkit → 200 bash script, unchanged
2026-03-19 21:02:43 +00:00

3.2 KiB

AGENTS.md — Timmy Tower World

Development conventions and workflows for agents and contributors.

One-time setup

make install

This activates git hooks that run typecheck and lint before every commit and push.

Quality checks

pnpm run typecheck   # TypeScript type-checking (tsc --build across all packages)
pnpm run lint        # ESLint across all TypeScript source files
make check           # Run both in sequence (same as CI)

Pushing to Gitea

All pushes go through the bore tunnel helper script (see replit.md for full docs):

bash scripts/push-to-gitea.sh [PORT]
  • First call after bore starts: pass the port once — it's saved for the session
  • Subsequent calls: no argument needed, reads from .bore-port
  • Bore port changes every restart — pass the new port to update

Set GITEA_TOKEN or write the token to .gitea-credentials (gitignored). Never commit credentials.

Branch and PR conventions

  • Never push directly to main — Gitea enforces branch protection
  • Every change lives on a feature branch: feat/<slug>, fix/<slug>, chore/<slug>
  • Open a PR on Gitea and squash-merge after review
  • CI runs pnpm typecheck && pnpm lint on every PR automatically

Testing

Executor agents should follow this three-step workflow when implementing or verifying any change:

1. Fetch the test plan before starting

curl <BASE>/api/testkit/plan

Returns TIMMY_TEST_PLAN.md — full architecture notes, route descriptions, and expected behaviour for all 24 tests. Read this first so you understand what each endpoint is supposed to do before touching the code.

2. Run the full test suite after implementing

curl -s <BASE>/api/testkit | bash

The server returns a self-contained bash script with the base URL already baked in. Requirements: curl, bash, jq — nothing else. All 24 tests must pass (FAIL=0) before submitting.

3. Fill in and submit the report

curl <BASE>/api/testkit/report

Returns just the report template section ready to copy and fill in. Attach the completed report to your PR or task output.

Where <BASE> is the running server URL, e.g. http://localhost:8080 locally or the Replit dev URL in CI.

Stub mode

The API server starts without Lightning or AI credentials:

  • LNbits stub: invoices are simulated in-memory. Mark paid via POST /api/dev/stub/pay/:hash
  • AI stub: Anthropic credentials absent → canned AI responses. Set AI_INTEGRATIONS_ANTHROPIC_API_KEY for real AI

Workspace structure

artifacts/api-server/    — Express 5 API server (@workspace/api-server)
lib/db/                  — Drizzle ORM schema + PostgreSQL client (@workspace/db)
lib/api-spec/            — OpenAPI spec + Orval codegen
lib/api-zod/             — Generated Zod schemas (do not edit by hand)
lib/api-client-react/    — Generated React Query hooks (do not edit by hand)
scripts/                 — Utility scripts (@workspace/scripts)

Running the API server

pnpm --filter @workspace/api-server run dev

Gitea repos

Repo Purpose
replit/token-gated-economy This repo — TypeScript API
perplexity/the-matrix Three.js 3D world frontend