Skip to content

Commit 6fc4064

Browse files
committed
docs: add AGENTS.md
1 parent fd01549 commit 6fc4064

File tree

8 files changed

+257
-2068
lines changed

8 files changed

+257
-2068
lines changed

AGENTS.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# Agent Guidelines for Bark EdgeOne
2+
3+
This document provides coding guidelines and conventions for AI agents working on the Bark EdgeOne codebase.
4+
5+
## Project Overview
6+
7+
Bark EdgeOne is a push notification server implementation for EdgeOne Pages Edge Functions, providing APNs integration with global edge deployment.
8+
9+
**Tech Stack:** TypeScript, EdgeOne Pages, Vitest, ESLint, Prettier
10+
11+
## Build, Test, and Lint Commands
12+
13+
### Build
14+
```bash
15+
npm run build # Compile TypeScript to dist/
16+
npm run type-check # Type check without emitting files
17+
```
18+
19+
### Testing
20+
```bash
21+
npm test # Run all tests once
22+
npm run test:watch # Run tests in watch mode
23+
npm run test:coverage # Run tests with coverage report
24+
25+
# Run a single test file
26+
npx vitest run src/utils/__tests__/string.test.ts
27+
28+
# Run tests matching a pattern
29+
npx vitest run -t "isEmpty"
30+
```
31+
32+
### Linting and Formatting
33+
```bash
34+
npm run lint # Check for linting errors
35+
npm run lint:fix # Auto-fix linting errors
36+
npm run format # Format all files
37+
npm run format:check # Check formatting without changes
38+
```
39+
40+
### Local Development
41+
```bash
42+
npx edgeone pages dev # Start local dev server on http://localhost:8788
43+
```
44+
45+
### Deploy to EdgeOne Pages
46+
```bash
47+
npx edgeone pages deploy # Start local dev server on http://localhost:8788
48+
49+
## Project Structure
50+
51+
```
52+
bark-edgeone/
53+
├── src/ # Core source code
54+
│ ├── apns/ # APNs integration (JWT, payload, push)
55+
│ ├── handlers/ # Business logic handlers
56+
│ ├── types/ # TypeScript type definitions
57+
│ └── utils/ # Utility functions
58+
├── edge-functions/ # EdgeOne edge function endpoints
59+
│ └── api/ # API route handlers
60+
├── node-functions/ # Node.js serverless functions
61+
├── dist/ # Compiled output
62+
└── __tests__/ # Test files (co-located with source)
63+
```
64+
65+
## Code Style Guidelines
66+
67+
### Imports
68+
- Use ES6 import syntax
69+
- Import types with `type` keyword: `import type { Foo } from './types'`
70+
- Group imports: external packages first, then internal modules
71+
- Use relative paths for local imports
72+
73+
```typescript
74+
import type { EventContext } from '../../src/types/common';
75+
import { success, jsonResponse } from '../../src/utils/response';
76+
```
77+
78+
### Formatting
79+
- **Indentation:** 2 spaces (no tabs)
80+
- **Line length:** 100 characters max
81+
- **Quotes:** Single quotes for strings (except to avoid escaping)
82+
- **Semicolons:** Always required
83+
- **Trailing commas:** ES5 style (objects, arrays)
84+
- **Arrow functions:** Always use parentheses around parameters
85+
- **Line endings:** LF (Unix style)
86+
87+
### TypeScript
88+
- **Strict mode:** Enabled - all strict checks are enforced
89+
- **Target:** ES2020
90+
- **Module:** CommonJS
91+
- **Type annotations:** Prefer explicit return types for exported functions
92+
- **Any usage:** Avoid `any`; use `unknown` or proper types. If `any` is necessary, add `/* eslint-disable @typescript-eslint/no-explicit-any */` with justification
93+
- **Unused vars:** Prefix with underscore if intentionally unused: `_context`
94+
95+
```typescript
96+
// Good
97+
export async function getToken(keyId: string): Promise<string> {
98+
// ...
99+
}
100+
101+
// Acceptable with comment
102+
/* eslint-disable @typescript-eslint/no-explicit-any */
103+
export interface CommonResp {
104+
data?: any; // Dynamic response data
105+
}
106+
```
107+
108+
### Naming Conventions
109+
- **Files:** kebab-case (`push-handler.ts`, `string.test.ts`)
110+
- **Functions:** camelCase (`generateJWT`, `normalizeSound`)
111+
- **Classes:** PascalCase (if used)
112+
- **Interfaces/Types:** PascalCase (`EventContext`, `PushParams`)
113+
- **Constants:** UPPER_SNAKE_CASE (`APNS_KEY_ID`, `JWT_TOKEN_VALIDITY_MS`)
114+
- **Private/unused params:** Prefix with underscore (`_context`, `_unused`)
115+
116+
### Functions and Documentation
117+
- Add JSDoc comments for exported functions and complex logic
118+
- Include parameter descriptions and return types
119+
- Document edge cases and important behavior
120+
121+
```typescript
122+
/**
123+
* Generate JWT token for APNs authentication
124+
*
125+
* @param keyId - APNs Key ID (default from config)
126+
* @param teamId - Apple Developer Team ID (default from config)
127+
* @param privateKey - P8 private key in PEM format (default from config)
128+
* @returns JWT token string
129+
*/
130+
export async function generateJWT(
131+
keyId: string = APNS_KEY_ID,
132+
teamId: string = APNS_TEAM_ID,
133+
privateKey: string = APNS_PRIVATE_KEY
134+
): Promise<string> {
135+
// Implementation
136+
}
137+
```
138+
139+
### Error Handling
140+
- Use try-catch for async operations
141+
- Extract error messages with utility functions: `getErrorMessage(error)`
142+
- Return structured error responses using response utilities
143+
- Check error types before accessing properties
144+
145+
```typescript
146+
try {
147+
await someAsyncOperation();
148+
} catch (error) {
149+
const message = getErrorMessage(error);
150+
return jsonResponse(failure(message, 500));
151+
}
152+
```
153+
154+
### Testing
155+
- Use Vitest for all tests
156+
- Place tests in `__tests__` directories next to source files
157+
- Name test files: `*.test.ts`
158+
- Use descriptive test names with `describe` and `it`
159+
- Test edge cases, error conditions, and happy paths
160+
161+
```typescript
162+
import { describe, it, expect } from 'vitest';
163+
164+
describe('isEmpty', () => {
165+
it('should return true for undefined', () => {
166+
expect(isEmpty(undefined)).toBe(true);
167+
});
168+
169+
it('should return false for non-empty string', () => {
170+
expect(isEmpty('hello')).toBe(false);
171+
});
172+
});
173+
```
174+
175+
## EdgeOne Specifics
176+
177+
### Edge Function Structure
178+
- Export `onRequest` function for edge function handlers
179+
- Accept `EventContext` parameter containing request, env, params
180+
- Return `Response` objects using response utilities
181+
182+
```typescript
183+
export async function onRequest(context: EventContext): Promise<Response> {
184+
return jsonResponse(success());
185+
}
186+
```
187+
188+
### Environment Variables
189+
- Access via `context.env` in edge functions
190+
- Define types in `src/types/environment.ts`
191+
- Never commit `.env` files
192+
193+
## Common Patterns
194+
195+
### Response Handling
196+
Use utility functions from `src/utils/response.ts`:
197+
- `success(data?, message?)` - Success response
198+
- `failure(message, code?)` - Error response
199+
- `jsonResponse(data, status?)` - JSON response wrapper
200+
201+
### String Utilities
202+
- `isEmpty(str)` - Check for empty/whitespace strings
203+
- `safeDecodeURIComponent(str)` - Safe URI decoding
204+
- `normalizeSound(sound)` - Normalize sound file names
205+
206+
## Important Notes
207+
208+
- **No console restrictions:** `console.log` is allowed for debugging
209+
- **Explicit any:** Warn on `any` usage but don't block
210+
- **Function return types:** Not required but recommended for exports
211+
- **Coverage exclusions:** Types, config files, and dist/ are excluded from coverage

0 commit comments

Comments
 (0)