Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions 00_STATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# 00_STATE.md — agentmail-node

## Repository Info
- **Upstream**: `agentmail-to/agentmail-node`
- **Fork**: `okwn/agentmail-node` (cloned to `/root/oss-pr-campaign/repos/agentmail-node`)
- **Default branch**: `main`
- **Language**: TypeScript
- **Archived**: No
- **License**: MIT

## Upstream Stats
- Stars: 32 | Forks: 14 | Open Issues: 2 | Watchers: 32
- Created: 2025-01-12

## Fork Status
- Forked at: 2026-05-22 16:42:10 UTC
- Branches synced: `main`, `haakam/eng-300-sdks-x402mpp`, `readme-upgrade-node-sdk`
- No local development branches (main only)

## Repository Structure
```
src/
├── Client.ts # Main SDK client
├── BaseClient.ts # Client options & auth
├── environments.ts # Environment config
├── api/
│ ├── resources/ # API endpoints (18 resources)
│ │ ├── inboxes/ # Inboxes sub-client
│ │ ├── pods/ # Pods sub-client
│ │ ├── threads/ # Threads sub-client
│ │ ├── messages/ # Messages sub-client
│ │ ├── webhooks/ # Webhooks sub-client
│ │ ├── agent/ # Agent sub-client
│ │ ├── apiKeys/ # API Keys sub-client
│ │ ├── domains/ # Domains sub-client
│ │ ├── drafts/ # Drafts sub-client
│ │ ├── lists/ # Lists sub-client
│ │ ├── metrics/ # Metrics sub-client
│ │ ├── organizations/ # Organizations sub-client
│ │ ├── websockets/ # Websockets sub-client
│ │ └── attachments/ # Attachments sub-client
│ └── errors/ # Error types
├── core/
│ ├── fetcher/ # HTTP layer
│ ├── schemas/ # Type validation schemas
│ ├── websocket/ # WebSocket handling (ws package)
│ ├── auth/ # Auth providers (Bearer, Basic)
│ ├── logging/ # Logging utilities
│ ├── url/ # URL utilities
│ └── runtime/ # Runtime detection
├── serialization/ # JSON serialization
└── wrapper/ # Client wrapper for x402
```

## Package Info
- **Name**: `agentmail`
- **Version**: `0.5.3`
- **Description**: The email inbox API for AI agents
- **Entry points**: CommonJS + ESM dual distribution
- **Node requirement**: `>=18.0.0`
- **Package manager**: pnpm (v10.33.0)
- **Key dependencies**: `ws@^8.20.0`
- **Dev dependencies**: vitest, msw, typescript, biome, webpack

## CI/CD
- **CI workflow**: `.github/workflows/ci.yml`
- `compile` job: checkout → setup-node → pnpm install → pnpm build
- `test` job: checkout → setup-node → pnpm install → pnpm test
- `publish` job: runs on tags with npm publish (OIDC)
- **Concurrency**: cancel-in-progress = false

## Test Status
```
✓ 71 test files passed
✓ 686 tests passed (unit + wire)
Duration: 53.46s
```

## Code Quality
- **Linter**: Biome (v2.4.9)
- **Lint status**: 216 warnings, 16 infos (no errors)
- **Formatter**: Biome
- **Build**: TypeScript (CJS + ESM outputs)
- **Generated code**: Most `src/api/` files are auto-generated by Fern

## Open Issues (Upstream)
1. **#14**: Inbox not immediately available for send after create — 404 on fresh inbox
2. **#12**: WebSocket connection fails on Node.js 24 — built-in WebSocket doesn't support auth headers

## Key Observations
1. SDK is auto-generated by Fern from API definition
2. Custom code via `.fernignore` approach documented
3. Websocket auth issue affects Node 24+ (uses built-in WS instead of `ws` package)
4. 2-second delay workaround exists for inbox propagation issue
5. Contributors: `fern-api[bot]` (168), `Haakam21` (29)
6. Recent releases: 0.5.3 → 0.5.2 → 0.5.1 → 0.5.0 (monthly cadence)
188 changes: 188 additions & 0 deletions 01_REPO_MAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# 01_REPO_MAP.md — agentmail-node

## Repository Hierarchy

```
github.com/agentmail-to/agentmail-node (upstream, org: agentmail-to)
└── fork: github.com/okwn/agentmail-node (user fork)
```

## Branches

### Upstream (`agentmail-to/agentmail-node`)
| Branch | Description |
|--------|-------------|
| `main` | Primary development branch |
| `haakam/eng-300-sdks-x402mpp` | Feature branch (MPP fetch fix) |
| `readme-upgrade-node-sdk` | Documentation update branch |

### Local (okwn/agentmail-node)
| Branch | Description |
|--------|-------------|
| `main` | Synced with upstream main |

## Package Exports Map

```
agentmail (package)
├── . → dist/cjs/index.js / dist/esm/index.mjs
├── ./serialization → src/serialization
├── ./inboxes → src/api/resources/inboxes
├── ./pods → src/api/resources/pods
├── ./webhooks → src/api/resources/webhooks
├── ./agent → src/api/resources/agent
├── ./apiKeys → src/api/resources/apiKeys
├── ./domains → src/api/resources/domains
├── ./drafts → src/api/resources/drafts
├── ./inboxes/apiKeys → src/api/resources/inboxes/resources/apiKeys
├── ./inboxes/drafts → src/api/resources/inboxes/resources/drafts
├── ./inboxes/events → src/api/resources/inboxes/resources/events
├── ./inboxes/lists → src/api/resources/inboxes/resources/lists
├── ./inboxes/messages → src/api/resources/inboxes/resources/messages
├── ./inboxes/metrics → src/api/resources/inboxes/resources/metrics
├── ./inboxes/threads → src/api/resources/inboxes/resources/threads
├── ./pods/apiKeys → src/api/resources/pods/resources/apiKeys
├── ./pods/domains → src/api/resources/pods/resources/domains
├── ./pods/drafts → src/api/resources/pods/resources/drafts
├── ./pods/inboxes → src/api/resources/pods/resources/inboxes
├── ./pods/lists → src/api/resources/pods/resources/lists
├── ./pods/metrics → src/api/resources/pods/resources/metrics
├── ./pods/threads → src/api/resources/pods/resources/threads
├── ./lists → src/api/resources/lists
├── ./metrics → src/api/resources/metrics
├── ./organizations → src/api/resources/organizations
├── ./threads → src/api/resources/threads
├── ./websockets → src/api/resources/websockets
└── ./package.json → package.json
```

## API Resources (18 endpoints)

| Resource | Path | Description |
|----------|------|-------------|
| Inboxes | `src/api/resources/inboxes/` | Email inbox management |
| Pods | `src/api/resources/pods/` | Pod management (contains nested resources) |
| Threads | `src/api/resources/threads/` | Email thread operations |
| Messages | `src/api/resources/messages/` | Message operations |
| Webhooks | `src/api/resources/webhooks/` | Webhook configuration |
| Agent | `src/api/resources/agent/` | Agent-related endpoints |
| API Keys | `src/api/resources/apiKeys/` | API key management |
| Domains | `src/api/resources/domains/` | Domain management |
| Drafts | `src/api/resources/drafts/` | Email draft operations |
| Lists | `src/api/resources/lists/` | Mailing list operations |
| Metrics | `src/api/resources/metrics/` | Analytics/metrics |
| Organizations | `src/api/resources/organizations/` | Organization management |
| Websockets | `src/api/resources/websockets/` | WebSocket connections |
| Attachments | `src/api/resources/attachments/` | File attachments |

## Source Code Structure

```
src/
├── Client.ts # Main AgentMailClient class
├── BaseClient.ts # Base client with auth & options
├── environments.ts # Environment enumeration (Prod, Sandbox)
├── index.ts # Public exports
├── exports.ts # Internal exports
├── version.ts # Version constant
├── api/
│ ├── index.ts # Re-exports all API resources
│ ├── errors/ # API error classes
│ │ └── index.ts
│ ├── resources/ # Generated API resource modules
│ │ └── [18 resource dirs]
│ │ ├── client/ # Client classes
│ │ ├── components/ # Schema components
│ │ ├── index.ts # Resource exports
│ │ └── types/ # TypeScript types
│ └── types/ # Shared API types
├── core/ # Core SDK functionality
│ ├── auth/ # Auth providers
│ │ ├── BasicAuth.ts
│ │ ├── BearerToken.ts
│ │ └── index.ts
│ ├── fetcher/ # HTTP request handling
│ │ ├── fetcher.ts
│ │ ├── makeRequest.ts
│ │ ├── createRequestUrl.ts
│ │ └── [more files]
│ ├── schemas/ # Type validation schemas
│ │ ├── object/
│ │ ├── primitives/
│ │ ├── union/
│ │ └── [more]
│ ├── websocket/ # WebSocket implementation
│ │ ├── index.ts
│ │ └── ws.ts # getGlobalWebSocket() - uses ws package
│ ├── logging/ # Logging utilities
│ ├── url/ # URL utilities
│ ├── runtime/ # Runtime detection (node/browser/deno/bun)
│ └── index.ts
├── serialization/ # JSON serialization
│ └── index.ts
└── wrapper/ # x402 payment wrapper
├── index.ts
├── Client.ts
└── WebsocketsClient.ts
```

## Test Structure

```
tests/
├── setup.ts # Test setup
├── tsconfig.json # Test TypeScript config
├── custom.test.ts # Custom integration tests
├── mock-server/ # MSW mock server
│ ├── setup.ts
│ └── [handlers]
├── unit/ # Unit tests (39 test files)
│ ├── fetcher/ # HTTP layer tests
│ ├── logging/ # Logging tests
│ ├── schemas/ # Schema validation tests
│ ├── url/ # URL utility tests
│ ├── auth/ # Auth provider tests
│ ├── base64.test.ts
│ └── wrapper/ # Wrapper tests
└── wire/ # Wire/integration tests (32 test files)
├── inboxes/ # Inboxes API tests
├── pods/ # Pods API tests
├── threads/ # Threads API tests
├── messages/ # Messages API tests
├── webhooks/ # Webhooks API tests
├── agent.test.ts
├── apiKeys.test.ts
├── domains.test.ts
├── drafts.test.ts
├── lists.test.ts
├── metrics.test.ts
├── organizations.test.ts
└── [resource].test.ts
```

## Key Files

| File | Purpose |
|------|---------|
| `package.json` | Package manifest, scripts, dependencies |
| `biome.json` | Biome linter/formatter config |
| `vitest.config.mts` | Vitest test configuration |
| `tsconfig.json` | TypeScript base config |
| `tsconfig.cjs.json` | CommonJS build config |
| `tsconfig.esm.json` | ESM build config |
| `.fernignore` | Fern generation ignore rules |
| `.github/workflows/ci.yml` | GitHub Actions CI |
| `reference.md` | Full API reference documentation |
| `CONTRIBUTING.md` | Contributing guidelines |

## NPM Registry

- **Package**: `agentmail` on npm
- **Current version**: `0.5.3`
- **Build outputs**: CJS (`dist/cjs/`) + ESM (`dist/esm/`)
- **Publish tags**: alpha, beta, backport, latest (based on version)
95 changes: 95 additions & 0 deletions 05_PR_CANDIDATES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# 05_PR_CANDIDATES.md — agentmail-node

## Open Issues (2)

### Issue #14: Inbox not immediately available for send after create — 404 on fresh inbox

**Severity**: High
**Labels**: (none)
**Status**: Open
**Created**: 2026-04-05

**Problem**:
Calling `inboxes.messages.send()` immediately after `inboxes.create()` returns a 404 "Inbox not found" error. The inbox is created and visible in `inboxes.list()`, but the `/inboxes/{inbox_id}/messages/send` endpoint returns 404 for ~1-2 seconds after creation.

**Root Cause**:
Backend propagation delay — the inbox is created server-side but not immediately available on the send endpoint. This is a backend issue, but the SDK could provide better handling.

**Workaround**:
Users must add a ~2 second delay between `create()` and `send()`.

**Potential SDK Fixes**:
1. Add a `waitForPropagation()` helper that polls inbox status until ready
2. Add retry logic to `send()` with a brief initial delay
3. Add documentation warning about the propagation delay
4. The issue states it affects "agentmail npm v0.4.13" - checking if still present in current version (0.5.3)

**Effort**: Medium — new helper function + tests + documentation

---

### Issue #12: WebSocket connection fails on Node.js 24 — built-in WebSocket doesn't support auth headers

**Severity**: High
**Labels**: (none)
**Status**: Open
**Created**: 2026-03-08

**Problem**:
On Node.js v24+, the SDK's `ReconnectingWebSocket` uses Node's built-in `WebSocket` instead of the `ws` package. Node's built-in WebSocket does not support custom headers (like `Authorization: Bearer ***`). This causes the WebSocket connection to fail with 403 immediately.

**Root Cause** (from `src/core/websocket/ws.ts`):
```typescript
const getGlobalWebSocket = (): WebSocket | undefined => {
if (RUNTIME.type === "node" || RUNTIME.type === "bun" || RUNTIME.type === "deno") {
return NodeWebSocket as unknown as WebSocket; // Uses ws package
} else if (typeof WebSocket !== "undefined") {
return WebSocket; // Uses built-in (no headers)
}
return undefined;
};
```

The code already uses `ws` for node, but the issue suggests on Node 24 the built-in WebSocket is being used instead. Let me check the runtime detection more carefully.

Wait, looking at the code again - it checks `RUNTIME.type === "node"` first and returns `NodeWebSocket` (from `ws` package). So the current code should work. However, the issue suggests Node 24's built-in WebSocket is being used somehow.

**Potential Fixes**:
1. Ensure the `ws` package is always used on Node regardless of built-in WebSocket availability
2. Add explicit version check for Node 22+ to prefer `ws` package over built-in
3. The workaround suggested in the issue is already implemented (check node first)

**Effort**: Low — configuration change to ensure ws is always used on Node

---

## Linting Errors (5)

From `pnpm run check`:

1. **tests/unit/wrapper/Client.test.ts** - `noNonNullAssertion` on line 95
- `client["_options"].fetch!` - forbidden non-null assertion
- Easy fix: use optional chaining or type guard

2. **tests/unit/wrapper/WebsocketsClient.test.ts** - Import sorting
- Imports not sorted correctly
- Auto-fixable with `biome check --fix`

---

## Quality Observations

1. **Test Coverage**: 686 tests passing across unit (39 files) and wire (32 files)
2. **Lint Status**: 216 warnings, 16 infos, 5 errors (import sorting + non-null assertions)
3. **Generated Code**: Most `src/api/` files are auto-generated by Fern — custom code goes in `.fernignore` protected files
4. **CI/CD**: Proper compile + test + publish pipeline with pnpm

---

## PR Candidate Summary

| # | Type | Title | Effort | Priority |
|---|------|-------|--------|----------|
| 1 | Bug fix | WebSocket auth headers on Node 24 | Low | High |
| 2 | Enhancement | Add `waitForInboxReady()` helper for issue #14 | Medium | Medium |
| 3 | Quality | Fix lint errors (5 files) | Low | Medium |
Loading