|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance to AI Agents when working with code in this |
| 4 | +repository. |
| 5 | + |
| 6 | +## Project Overview |
| 7 | + |
| 8 | +`@fishballpkg/acme` is a zero-dependency, minimalistic, opinionated ACME client |
| 9 | +written in TypeScript. It is designed to be platform-agnostic, running on Deno, |
| 10 | +Node.js, and other modern JavaScript environments that support `WebCrypto` and |
| 11 | +`fetch`. |
| 12 | + |
| 13 | +## Development Commands |
| 14 | + |
| 15 | +This project uses Deno for development. |
| 16 | + |
| 17 | +### Testing |
| 18 | + |
| 19 | +There are multiple tiers of tests in this repository: |
| 20 | + |
| 21 | +- **Unit Tests**: Run purely in-process, mocking external requests where |
| 22 | + necessary. |
| 23 | + - Command: `deno task test:unit` |
| 24 | + - Location: `src/**/*.test.ts` |
| 25 | + |
| 26 | +- **Integration Tests**: Run against a local Pebble instance (Let's Encrypt's |
| 27 | + ACME test server). |
| 28 | + - **Prerequisites**: Docker must be running. |
| 29 | + - **Start Pebble**: `deno task pebble:start` (starts Pebble and `challtestsrv` |
| 30 | + via Docker Compose) |
| 31 | + - **Run Integration Tests**: `deno task test:integration` |
| 32 | + - **Stop Pebble**: `deno task pebble:stop` |
| 33 | + - Location: `integration/` |
| 34 | + |
| 35 | +- **E2E Tests**: |
| 36 | + - Command: `deno task test:e2e` |
| 37 | + - Location: `e2e/` |
| 38 | + |
| 39 | +### Building |
| 40 | + |
| 41 | +The project is natively TypeScript/Deno but builds to NPM for Node.js |
| 42 | +compatibility using `dnt`. |
| 43 | + |
| 44 | +- **Build for NPM**: `deno task build:npm` |
| 45 | + - This script (`scripts/build-npm.ts`) generates the `dist-npm` directory. |
| 46 | + |
| 47 | +### Linting & Formatting |
| 48 | + |
| 49 | +- **Lint**: Use `deno lint` standard command. |
| 50 | +- **Format**: Use `deno fmt` standard command. |
| 51 | + |
| 52 | +## High-Level Architecture |
| 53 | + |
| 54 | +The codebase follows the hierarchy of the ACME standard (RFC 8555). |
| 55 | + |
| 56 | +### Core Components (`src/`) |
| 57 | + |
| 58 | +- **Entry Point**: `src/mod.ts` exports the public API. |
| 59 | +- **AcmeClient** (`src/AcmeClient.ts`): The main entry point for users. |
| 60 | + Initializes with a directory URL. |
| 61 | + - **JWS Signing**: Handles JSON Web Signature (JWS) wrapping for requests |
| 62 | + using `src/utils/jws.ts` and `src/utils/crypto.ts`. |
| 63 | + - **Nonce Management**: detailed in `AcmeClient` private methods. |
| 64 | +- **AcmeAccount** (`src/AcmeAccount.ts`): Represents a registered account on the |
| 65 | + ACME server. |
| 66 | +- **AcmeOrder** (`src/AcmeOrder.ts`): Represents a certificate order. Handles |
| 67 | + polling for status steps. |
| 68 | +- **AcmeAuthorization** (`src/AcmeAuthorization.ts`): Represents validation for |
| 69 | + a specific domain. |
| 70 | +- **AcmeChallenge** (`src/AcmeChallenge.ts`): Represents a specific challenge |
| 71 | + method (e.g., `dns-01`). |
| 72 | + |
| 73 | +### Utilities |
| 74 | + |
| 75 | +- **`src/utils/`**: Internal helpers. |
| 76 | + - `jws.ts`: JWS signing logic. |
| 77 | + - `crypto.ts`: WebCrypto wrappers. |
| 78 | + - `generateCSR.ts`: Logic to generate valid Certificate Signing Requests (CSR) |
| 79 | + without external dependencies like OpenSSL. |
| 80 | +- **`src/ACME_DIRECTORY_URLS.ts`**: Constants for common ACME directories (Let's |
| 81 | + Encrypt, etc.). |
| 82 | + |
| 83 | +### Workflows |
| 84 | + |
| 85 | +- **`src/AcmeWorkflows.ts`**: Contains high-level abstraction functions (e.g., |
| 86 | + `requestCertificate`) that bundle multiple steps (order creation, challenge |
| 87 | + solving, polling, finalization) into single calls for convenience. |
| 88 | + |
| 89 | +## Design Principles |
| 90 | + |
| 91 | +1. **Zero Dependencies**: Do not introduce NPM dependencies or external CLIs |
| 92 | + (like OpenSSL). Everything must be implemented using standard Web APIs |
| 93 | + (`WebCrypto`, `fetch`) or built from scratch (like the CSR generator). |
| 94 | +2. **Platform Agnostic**: Code must write to Deno standards but be compatible |
| 95 | + with Node.js via the build script. Avoid Deno-specific namespaces (`Deno.*`) |
| 96 | + in the `src/` directory unless strictly necessary or valid polyfills exist. |
| 97 | +3. **Opinionated**: Focus on `DNS-01` challenge and `ECDSA P-256` keys. Support |
| 98 | + for other methods is secondary. |
0 commit comments