Files
2026-07-13 12:30:28 +08:00

52 lines
2.8 KiB
Markdown

# AGENTS.md
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
## Project Overview
PinMe is a zero-config CLI tool for deploying static sites to IPFS. Built with TypeScript, bundled with esbuild, published to npm as `pinme`. Users run commands like `pinme upload dist` to deploy frontends.
## Build & Dev
```bash
npm run build # Production build (esbuild → dist/index.js)
npm run dev # Dev build
npm run test # Unit/integration tests (Vitest)
npm run test:cli # Real CLI black-box tests against dist/index.js
npm run verify # Full PR gate: lint, typecheck, tests, build, CLI, pack
npm run test:mutation # Slow mutation tests (manual/nightly)
```
Build uses `build.js` (esbuild), NOT `rollup.config.js` (legacy, unused). esbuild reads `.env` via dotenv at build time and injects env vars as `process.env.*` defines.
The output is a single CJS file at `dist/index.js` with a shebang, used as the `pinme` CLI binary.
## Architecture
- `bin/index.ts` — CLI entry point, uses `commander` to register all commands
- `bin/*.ts` — Individual command implementations (upload, save, create, bind, importCar, exportCar, delete, etc.)
- `bin/utils/` — Shared utilities:
- `config.ts``APP_CONFIG` singleton, all API base URLs and tuning knobs from env vars
- `apiClient.ts` — Axios client factory (`createPinmeApiClient`, `createCarApiClient`)
- `pinmeApi.ts` — High-level API wrappers (domain binding, wallet, CAR export, etc.)
- `uploadToIpfs.ts` / `uploadToIpfsSplit.ts` — IPFS upload logic (single file vs chunked)
- `webLogin.ts` — Auth token management (reads from `~/.pinme/`)
- `domainValidator.ts` — Domain name validation and DNS vs subdomain detection
- `cliError.ts` — Structured CLI error types
- `bin/services/uploadService.ts` — Upload orchestration (hash encryption, URL generation)
- `skills/` — Codex skill definitions for this project
## Key Patterns
- Auth: AppKey stored locally at `~/.pinme/`. Auth headers injected via `getAuthHeaders()` in `webLogin.ts`.
- API clients: Always use `createPinmeApiClient()` or `createCarApiClient()` from `apiClient.ts`, never raw axios.
- Token expiry: `pinmeApi.ts` has centralized token-expired detection (`isTokenExpired`) — all API calls should go through wrappers there.
- Config: All env-driven config lives in `APP_CONFIG` (`config.ts`). Don't read `process.env` directly elsewhere.
- The `save` command reads `pinme.toml` from project root for full-stack deploy (frontend + Cloudflare Worker + D1).
## Code Style
- Prettier: single quotes, trailing commas, 80 char width
- TypeScript with `strict: false`, target ESNext, module ESNext
- CLI output uses `chalk` for colors, `ora` for spinners, `inquirer` for prompts, `figlet` for banner